Programing

문자열이 직렬화되어 있는지 확인 하시겠습니까?

lottogame 2020. 7. 3. 18:43
반응형

문자열이 직렬화되어 있는지 확인 하시겠습니까?


문자열이 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;
}

Pascal MARTIN의 응답 최적화

/**
 * Check if a string is serialized
 * @param string $string
 */
public static function is_serial($string) {
    return (@unserialize($string) !== false);
}

는 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);
}

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 );
}

And it actually works. The only caveat is that it will likely break if you have a registered error handler because of how $php_errormsg works.


$data = @unserialize($str);
if($data !== false || $str === 'b:0;')
    echo 'ok';
else
    echo "not ok";

Correctly handles the case of serialize(false). :)


build in to a function

function isSerialized($value)
{
   return preg_match('^([adObis]:|N;)^', $value);
}

There is WordPress solution: (detail is here)

    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;
}

}

This works fine for me

<?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));
    }

?>

I prefer doing it that way:

 if (is_array(unserialize($serialized_string))):

참고URL : https://stackoverflow.com/questions/1369936/check-to-see-if-a-string-is-serialized

반응형