Sprawdź, czy ciąg jest serializowany?

Jaki jest najlepszy sposób na określenie, czy łańcuch jest wynikiem funkcji serialize()?

Https://www.php.net/manual/en/function.serialize

Author: Valerio Bozz, 2009-09-02

12 answers

Powiedziałbym, że spróbuj unserialize it; -)

Cytowanie instrukcji:

W przypadku, gdy przekazywany ciąg nie jest unserializable, False jest zwracane i Wydano E_NOTICE.

Więc musisz sprawdzić, czy wartość zwracana jest false czy nie (z === lub !==, aby upewnić się, że nie masz żadnego problemu z 0 lub null lub czymkolwiek, co jest równe false, powiedziałbym).

Po prostu uważaj na powiadomienie : możesz chcieć / musisz użyć @ operator .

Na przykład:

$str = 'hjkl';
$data = @unserialize($str);
if ($data !== false) {
    echo "ok";
} else {
    echo "not ok";
}

Dostaniesz:

not ok


EDIT: Aha, i tak jak powiedział @ Piotr (dzięki niemu!jeśli nie chcesz wyświetlać wartości logicznej false, możesz mieć problem z wyświetlaniem wartości logicznej false.]}

Więc sprawdzanie, czy twój seryjny ciąg znaków nie jest równy "b:0; " może być również pomocne ; coś takiego powinno załatwić sprawę, jak sądzę:

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

Testowanie tego specjalnego przypadku przed próbą unserializacji byłoby optymalizacja -- ale prawdopodobnie nie jest to przydatne, jeśli często nie masz fałszywej wartości seryjnej.

 197
Author: Pascal MARTIN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-02 20:39:06

Nie napisałem tego kodu, jest z WordPressa. Pomyślałem, że dołączę go dla każdego zainteresowanego, może to przesada, ale działa:)

<?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;
}
 58
Author: Brandon Wamboldt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-14 16:32:18

Optymalizacja odpowiedzi Pascala Martina

/**
 * Check if a string is serialized
 * @param string $string
 */
public static function is_serial($string) {
    return (@unserialize($string) !== false);
}
 20
Author: SoN9ne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-14 20:21:26

Jeśli $ string jest serializowaną wartością false, czyli $string = 'b:0;' SoN9ne 's funkcja zwraca false, jest źle

Więc funkcja będzie

/**
 * Check if a string is serialized
 *
 * @param string $string
 *
 * @return bool
 */
function is_serialized_string($string)
{
    return ($string == 'b:0;' || @unserialize($string) !== false);
}
 18
Author: Hazem Noor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-03 08:35:08

Pomimo doskonałej odpowiedzi Pascala Martina, byłem ciekaw, czy możesz podejść do tego w inny sposób, więc zrobiłem to tylko jako ćwiczenie umysłowe

<?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 );
}
I to naprawdę działa. Jedynym zastrzeżeniem jest to, że prawdopodobnie pęknie, jeśli masz zarejestrowaną obsługę błędów, ponieważ $php_errormsg działa.
 13
Author: Peter Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-02 21:26:56
$data = @unserialize($str);
if($data !== false || $str === 'b:0;')
    echo 'ok';
else
    echo "not ok";

Poprawnie obsługuje przypadek serialize(false). :)

 11
Author: chaos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-02 20:38:33

Istnieje rozwiązanie WordPress: (szczegóły tutaj)

    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;
    }
 3
Author: ingenious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-17 09:09:34
/**
 * 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;
}

}
 2
Author: Björn3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-27 23:11:24

Wbuduj do funkcji

function isSerialized($value)
{
   return preg_match('^([adObis]:|N;)^', $value);
}
 2
Author: RossW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-22 10:43:14

To działa dobrze dla mnie

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

?>
 1
Author: Daniel Lichtenberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-05 20:39:38

Zobacz funkcję wordpress is_serialized

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;

}

 0
Author: onlinewebsite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-20 10:16:45

Po prostu spróbowałbym to odserializować. Tak bym to rozwiązał

public static function is_serialized($string)
{
    try {
        unserialize($string);
    } catch (\Exception $e) {
        return false;
    }

    return true;
}

Lub bardziej jak funkcja pomocnicza

function is_serialized($string) {
  try {
        unserialize($string);
    } catch (\Exception $e) {
        return false;
    }

    return true;
}
 0
Author: Mikael Dalholm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-01 15:54:54