What's the best way to determine whether or not a string is the result / output of the serialize() function?
I'd say, try to unserialize
it ;-)
Quoting the manual :
In case the passed string is not unserializeable, FALSE is returned and E_NOTICE is issued.
So, you have to check if the return value is false
or not (with ===
or !==
, to be sure not to have any problem with 0
or null
or anything that equals to false
, I'd say).
Just beware the notice : you might want/need to use the @ operator.
For instance :
$str = 'hjkl';
$data = @unserialize($str);
if ($data !== false) {
echo "ok";
} else {
echo "not ok";
}
Will get you :
not ok
EDIT : Oh, and like @Peter said (thanks to him!), you might run into trouble if you are trying to unserialize the representation of a boolean false :-(
So, checking that your serialized string is not equal to "b:0;
" might be helpful too ; something like this should do the trick, I suppose :
$data = @unserialize($str);
if ($str === 'b:0;' || $data !== false) {
echo "ok";
} else {
echo "not ok";
}
testing that special case before trying to unserialize would be an optimization -- but probably not that usefull, if you don't often have a false serialized value.
My guess is that you are coding incorrectly causing this dilemma. Since there is no build-in PHP way to handle this (that is efficient @karim79) I really recommend you look at solving this problem before your code gets to this point. Would you mind explaining a little more about why you are ending up with random strings or serialized objects?
$data = @unserialize($str);
if($data !== false || $str === 'b:0;')
echo 'ok';
else
echo "not ok";
Correctly handles the case of serialize(false)
. :)
Despite Pascal MARTIN's excellent answer, I was curious if you could approach this another way, so I did this just as a mental exercise
<?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.
@Xeoncross
For example: when you put serialized data into a cookie. Then the value of this cookie becomes untrusted and is has to be checked before you do anything with it.