문자열이 결과인지 여부를 결정하는 가장 좋은 방법은 무엇입니까? serialize()
함수 ?
문자열이 결과인지 여부를 결정하는 가장 좋은 방법은 무엇입니까? serialize()
함수 ?
답변:
나는 그것을 시도해보십시오 unserialize
;-)
매뉴얼 인용 :
전달 된 문자열을 직렬화 할 수없는 경우 FALSE가 리턴되고 E_NOTICE가 발행됩니다.
그래서, 당신은 반환 값이 있는지 확인해야합니다 false
여부 (와 ===
나 !==
, 확실하게 어떤 문제가되지 0
또는 null
하거나 동일 무엇이든 false
, 내가 말할 것이다) .
@ 연산자 를 사용하고 싶을 수도 있습니다 .
예를 들면 :
$str = 'hjkl';
$data = @unserialize($str);
if ($data !== false) {
echo "ok";
} else {
echo "not ok";
}
당신을 얻을 것입니다 :
not ok
편집 : 아, 그리고 @Peter가 말했듯이 (그에게 감사합니다!) 부울 거짓의 표현을 직렬화하려고 시도하면 문제가 발생할 수 있습니다.
따라서 직렬화 된 문자열이 " b:0;
" 이 아닌지 확인하는 것도 도움이 될 수 있습니다. 이런 식으로 트릭을 수행해야한다고 생각합니다.
$data = @unserialize($str);
if ($str === 'b:0;' || $data !== false) {
echo "ok";
} else {
echo "not ok";
}
직렬화 해제를 시도하기 전에 해당 특수 사례를 테스트하는 것은 최적화 일 것입니다.
나는이 코드를 쓰지 않았다. 실제로 WordPress에서 온 것입니다. 내가 관심있는 사람을 위해 그것을 포함 할 것이라고 생각했지만 과잉 일 수도 있지만 작동합니다 :)
<?php
function is_serialized( $data ) {
// if it isn't a string, it isn't serialized
if ( !is_string( $data ) )
return false;
$data = trim( $data );
if ( 'N;' == $data )
return true;
if ( !preg_match( '/^([adObis]):/', $data, $badions ) )
return false;
switch ( $badions[1] ) {
case 'a' :
case 'O' :
case 's' :
if ( preg_match( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ) )
return true;
break;
case 'b' :
case 'i' :
case 'd' :
if ( preg_match( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ) )
return true;
break;
}
return false;
}
^([adObis]:|N;)
는 IF $ 문자열 직렬화 된입니다 false
값, 즉 $string = 'b:0;'
SoN9ne 의 기능 반환false
, 그것의 잘못은
그래서 기능은
/**
* Check if a string is serialized
*
* @param string $string
*
* @return bool
*/
function is_serialized_string($string)
{
return ($string == 'b:0;' || @unserialize($string) !== false);
}
In case the passed string is not unserializeable, FALSE is returned and E_NOTICE is issued.
예외가 아니므로 E_NOTICE 오류를 잡을 수 없습니다.
Pascal MARTIN의 탁월한 답변에도 불구하고, 다른 방법으로 접근 할 수 있는지 궁금합니다.
<?php
ini_set( 'display_errors', 1 );
ini_set( 'track_errors', 1 );
error_reporting( E_ALL );
$valueToUnserialize = serialize( false );
//$valueToUnserialize = "a"; # uncomment this for another test
$unserialized = @unserialize( $valueToUnserialize );
if ( FALSE === $unserialized && isset( $php_errormsg ) && strpos( $php_errormsg, 'unserialize' ) !== FALSE )
{
echo 'Value could not be unserialized<br>';
echo $valueToUnserialize;
} else {
echo 'Value was unserialized!<br>';
var_dump( $unserialized );
}
그리고 실제로 작동합니다. 유일한주의 사항은 $ php_errormsg 작동 방식으로 인해 등록 된 오류 처리기가 있으면 중단 될 수 있다는 것입니다 .
$a
과 Deserializing 사이의 오류를 확인하지 않은 경우에만 $b
실제 응용 프로그램 디자인이 아닙니다.
함수를 구축하다
function isSerialized($value)
{
return preg_match('^([adObis]:|N;)^', $value);
}
a:
(또는 b:
하지 처음에 $ 값 내부에 존재 곳입니다 등). 그리고 ^
여기에서 문자열의 시작을 의미하지는 않습니다. 완전히 오해의 소지가 있습니다.
WordPress 솔루션이 있습니다. (자세한 내용은 여기에 있습니다)
function is_serialized($data, $strict = true)
{
// if it isn't a string, it isn't serialized.
if (!is_string($data)) {
return false;
}
$data = trim($data);
if ('N;' == $data) {
return true;
}
if (strlen($data) < 4) {
return false;
}
if (':' !== $data[1]) {
return false;
}
if ($strict) {
$lastc = substr($data, -1);
if (';' !== $lastc && '}' !== $lastc) {
return false;
}
} else {
$semicolon = strpos($data, ';');
$brace = strpos($data, '}');
// Either ; or } must exist.
if (false === $semicolon && false === $brace)
return false;
// But neither must be in the first X characters.
if (false !== $semicolon && $semicolon < 3)
return false;
if (false !== $brace && $brace < 4)
return false;
}
$token = $data[0];
switch ($token) {
case 's' :
if ($strict) {
if ('"' !== substr($data, -2, 1)) {
return false;
}
} elseif (false === strpos($data, '"')) {
return false;
}
// or else fall through
case 'a' :
case 'O' :
return (bool)preg_match("/^{$token}:[0-9]+:/s", $data);
case 'b' :
case 'i' :
case 'd' :
$end = $strict ? '$' : '';
return (bool)preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
}
return false;
}
/**
* some people will look down on this little puppy
*/
function isSerialized($s){
if(
stristr($s, '{' ) != false &&
stristr($s, '}' ) != false &&
stristr($s, ';' ) != false &&
stristr($s, ':' ) != false
){
return true;
}else{
return false;
}
}
이것은 나를 위해 잘 작동
<?php
function is_serialized($data){
return (is_string($data) && preg_match("#^((N;)|((a|O|s):[0-9]+:.*[;}])|((b|i|d):[0-9.E-]+;))$#um", $data));
}
?>
나는 그렇게하는 것을 선호합니다 :
if (is_array(unserialize($serialized_string))):