首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >PHP如何处理作为元素引用自身的数组?

PHP如何处理作为元素引用自身的数组?
EN

Stack Overflow用户
提问于 2018-03-21 04:40:13
回答 1查看 0关注 0票数 0

比方说我声明一个数组:

$data = array( 'foo' => 'bar' );

现在我将添加一个对自身的引用作为一个新元素:

$data['baz'] = &$data;

倾倒内容$data将导致:

Array
(
[foo] => bar
[baz] => Array
    (
        [foo] => bar
        [baz] => Array
         *RECURSION*
    )

)

现在,我可以转储内容$data['baz']['baz']['baz']['baz']['baz']['baz']['baz']['baz']['baz']并且结果与上述内容完全相同,因为数组有一个指向自身的指针作为元素。

我想知道的是,如果php将数组作为一个单一的数据集处理,并且指针与我在使用时指向的指针完全相同,$data或者它完成了一些完全不同的操作。

此外,PHP可能会在尝试返回内容时耗尽内存$data{['baz']*n}

EN

Stack Overflow用户

发布于 2018-03-21 13:41:15

在PHP内部,所有内容都存储在称为ZVAL的变体容器中。由ZVAL表示,每个键和每个值都是ZVAL等。$data$data

所以在初始分配后,PHP创建了三个ZVAL:

   /-------------------\      /-------------------\   
   | ZVAL #1           |  /==>| ZVAL #2           |   
   |   type: array     |  |   |   type: string    |   
   |   data: [         |  |   |   data: "foo"     |
   |      {            |  |   \-------------------/
   |          key: =======/                         /-------------------\
   |          val: ================================>| ZVAL #3           |
   |      }            |                            |   type: string    |
   |   ]               |                            |   data:  "bar"    |
   \-------------------/                            \-------------------/

你可以看到这样的事实"foo""bar"被用作数组键/值对是不可能通过看他们的变量容器,以确定:你要知道,他们正在由数组引用。

分配之后$data['baz'] = &$data,会发生什么情况?你现在有一个循环引用:位于ZVAL#1内的某个位置有一个指向ZVAL#1的指针:

   /-------------------\      /-------------------\   
   | ZVAL #1           |  /==>| ZVAL #2           |   
/=>|   type: array     |  |   |   type: string    |   
|  |   data: [         |  |   |   data: "foo"     |
|  |      {            |  |   \-------------------/
|  |          key: =======/                         /-------------------\
|  |          val: ================================>| ZVAL #3           |
|  |      },           |                            |   type: string    |
|  |      {            |                            |   data: "bar"     |
|  |          key: =========================\       \-------------------/
|  |          val: =========\               |       
|  |      }            |    |               |       /-------------------\
|  |   ]               |    |               \======>| ZVAL #4           |
|  \-------------------/    |                       |   type: string    |
|                           |                       |   data: "baz"     |
\===========================/                       \-------------------/

那么PHP如何解决$data['baz']['baz']?它知道这$data是由ZVAL#1表示的,它看到你正试图用数组语法对它进行索引。它看着ZVAL,看到它是一个数组,找到具有该键的项目"baz"并获取表示该项目的ZVAL。你知道什么?这再次是ZVAL#1。这就结束了决议$data['baz']

在下一步中,它看到你正在尝试将$data['baz']数组索引。它知道这$data['baz']是由ZVAL#1表示的,所以同样的事情最终会再次发生,等等。

你将注意到上述过程不涉及存储任何中间结果(第一步和第二步完全独立),这意味着在尝试解析数组访问时,PHP虚拟机不会遇到任何资源限制。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档