试图了解php的zvals

时间:2015-08-03 15:35:47

标签: php php-internals

我正在尝试理解PHP的zvals。请考虑以下代码:

<?php
$randomByteString = 'abcd';

$val = 0;
for ($i = 0; $i < 4; ++$i) {
    $val |= ord($randomByteString[$i]) << ($i * 8);
}

echo $val;

在我看来,将为每个语句创建一个zval:

  • $ i = 0
  • ++ $ I
  • $ i * 8
  • $ randomByteString [$ i]于
  • ORD($ randomByteString [$ i]于)
  • 以及对$ val
  • 的任何更改

这是对的吗?

1 个答案:

答案 0 :(得分:3)

不完全。让我们逐行浏览,介绍PHP 5如何处理这些zval。

<?php
$randomByteString = 'abcd';

创建了一个包含'abcd'的新zval,现在$randomByteString指向它。

到目前为止的Zval数:1

$val = 0;

创建了一个包含0的新zval,现在$val指向它。

到目前为止的Zval数:2

for ($i = 0; $i < 4; ++$i) {

我们第一次执行此操作时,会为0创建一个zval并将$i指向它。

比较$i4可能会暂时创建一个布尔zval。我对PHP 5在这里所做的事情的记忆是模糊的,它可能不会在幕后做这件事。但这对我们的总体数量并不重要,因为它会立即被丢弃。

增量$i不会创建zval,只会更改已经指向的zval $i内的数字。

到目前为止的Zval计数:3(不包括丢弃的临时zval)

    $val |= ord($randomByteString[$i]) << ($i * 8);

访问$randomByteString[$i]将创建包含单字节字符串的zval。将其传递给ord()将丢弃该zval并创建一个包含整数的新zval。

8乘以$i将创建一个新的zval。

我们的ord()结果左移我们的$i结果会创建一个新的zval,并且会丢弃我们的两个输入zval。

最后,将|=$val一起使用会更改$val中的值并删除我们的左移结果。 $val已经存在,所以我们只是更改内容而不是为它创建一个新的zval。

到目前为止的Zval计数:4

}

echo $val;

Echo不会创造任何zvals。

在脚本结束时,你有4个zval。

顺便说一句,为$i < 4$randomByteString[$i]($i * 8)<<创建的zvals都是临时 zvals:他们不会&#39 ; t导致新的内存分配,而是将它们存储在用于临时值的特殊内存区域中。这意味着创建这些临时值没有性能损失。其他zval(包括ord()由于某种原因,函数调用效率低下),另一方面,需要内存分配。

此外,这只适用于PHP 5. PHP 7更灵活地处理zval,因此通常不需要单独的内存分配。