php递归引用,循环引用
PHP支持递归引用,但会导致序列化时产生错误.
如
$arr=array(1,2);
// 递归引用自己
$arr['c']=&$arr;
class A{
public $self;
public function __construct(){
// 引用自身
$this->self=$this;
}
}
$obj=new A;
var_dump($arr,$obj);
各版本出输
PHP8.1:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
["c"]=>
*RECURSION*
}
object(A)#1 (1) {
["self"]=>
*RECURSION*
}
Result for 7.4.30, 7.1.33, 5.3.29:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
["c"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
["c"]=>
*RECURSION*
}
}
object(A)#1 (1) {
["self"]=>
*RECURSION*
}
Result for 5.1.6:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
["c"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
["c"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
["c"]=>
*RECURSION*
}
}
}
object(A)#1 (1) {
["self"]=>
object(A)#1 (1) {
["self"]=>
*RECURSION*
}
}
var_export
会产生warning错误.
把循环引用改成null;不能正常反序列化.
Result for 8.1.9, 7.4.30, 7.1.33:
Warning: var_export does not handle circular references in /home/user/scripts/code.php on line 14
array (
0 => 1,
1 => 2,
'c' => NULL,
)
Warning: var_export does not handle circular references in /home/user/scripts/code.php on line 15
A::__set_state(array(
'self' => NULL,
))
Result for 5.3.29:
Fatal error: Nesting level too deep - recursive dependency? in /home/user/scripts/code.php on line 14
Result for 5.1.6:
array (
0 => 1,
1 => 2,
'c' =>
array (
0 => 1,
1 => 2,
'c' =>
array (
0 => 1,
1 => 2,
'c' =>
array (
0 => 1,
1 => 2,
'c' =>
array (
json_encode
会产生错误,输出false;
报Recursion detected 错误.
echo json_encode($arr);
echo json_last_error_msg();
echo json_encode($obj);
echo json_last_error_msg();
serialize
都能正常序列化和反序列化.
处理循环引用
常用框架的忽略json错误.
$data=[1,2,3];
$data['self']=&$data;
// 原生
json_encode($data);// 无错误
json_last_error_msg()// Recursion detected
return json_encode($data,JSON_PARTIAL_OUTPUT_ON_ERROR); // self=>null
// laravel
return $data; // 严重错误
return response($data,200);// 严重错误
return new JsonResponse($obj, 200, [], JSON_PARTIAL_OUTPUT_ON_ERROR);// self=>null
// phalcon
$serialize=new Phalcon\Storage\Serializer\Php($data);
echo $serialize->serialize();//允许
$serialize=new Phalcon\Storage\Serializer\Json($data);
echo $serialize->serialize();//严重错误
$Response=new \Phalcon\Http\Response();
$Response->setJsonContent($data,JSON_PARTIAL_OUTPUT_ON_ERROR);// BUG,参数不生效
$Response->send();
// hyperf
return $data; // 严重错误
return $response->json($data);// 严重错误,不支持json参数
return Json::encode($data,JSON_PARTIAL_OUTPUT_ON_ERROR);// self=>null
原作者:阿金
本文地址:https://hi-arkin.com/archives/php-recusion.html