Вы не упомянули, какую версию PHP вы используете, но второй аргумент unserialize
доступен только в PHP 7.
От php.net:
7.0.0 Параметр опции было добавлено.
РНР 5.5.9-1ubuntu4.20 (CLI):
php > $a = serialize(array('a'=>'b', 'c'=>20));
php > var_dump(unserialize($a, array('allowed_classes'=>false)));
PHP Warning: unserialize() expects exactly 1 parameter, 2 given in php shell code on line 1
PHP Stack trace:
PHP 1. {main}() php shell code:0
PHP 2. unserialize() php shell code:1
bool(false)
PHP 7.0.12 (CLI):
php > $a = serialize(array('a'=>'b', 'c'=>20));
php > var_dump(unserialize($a, array('allowed_classes'=>false)));
array(2) {
["a"]=>
string(1) "b"
["c"]=>
int(20)
}
PHP 7.0.12 (CLI) с сериализованным объект:
php > $a = serialize(array('a'=>'b', 'c'=>20, 'd'=> new Exception));
php > var_dump(unserialize($a, array('allowed_classes'=>false)));
array(3) {
["a"]=>
string(1) "b"
["c"]=>
int(20)
["d"]=>
object(__PHP_Incomplete_Class)#1 (8) {
["__PHP_Incomplete_Class_Name"]=>
string(9) "Exception"
["message":protected]=>
string(0) ""
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(14) "php shell code"
["line":protected]=>
int(1)
["trace":"Exception":private]=>
array(0) {
}
["previous":"Exception":private]=>
NULL
}
}
Я не могу говорить за это безопасность или полнота, но comment 119851 в в unserialize
PHP Документах это implmentation из unserialize
с аргументом опции для> PHP 5.3:
function php7_unserialize($str, $options = array())
{
if(version_compare(PHP_VERSION, '7.0.0', '>='))
{ return unserialize($str, $options); }
$allowed_classes = isset($options['allowed_classes']) ?
$options['allowed_classes'] : true;
if(is_array($allowed_classes) || !$allowed_classes)
{
$str = preg_replace_callback(
'/(?=^|:)(O|C):\d+:"([^"]*)":(\d+):{/',
function($matches) use ($allowed_classes)
{
if(is_array($allowed_classes) &&
in_array($matches[2], $allowed_classes))
{ return $matches[0]; }
else
{
return $matches[1].':22:"__PHP_Incomplete_Class":'.
($matches[3] + 1).
':{s:27:"__PHP_Incomplete_Class_Name";'.
serialize($matches[2]);
}
},
$str
);
}
unset($allowed_classes);
return unserialize($str);
}
да, это была моя ошибка использовать @unserialize, так что я не был в состоянии видеть это предупреждение с PHP 5.3. – AlexandrX
и спасибо за реализацию php7_unserialize, он выглядит безопасным, насколько я могу судить. – AlexandrX