我正在尝试理解PHP的zvals。请考虑以下代码:
<?php
$randomByteString = 'abcd';
$val = 0;
for ($i = 0; $i < 4; ++$i) {
$val |= ord($randomByteString[$i]) << ($i * 8);
}
echo $val;
在我看来,将为每个语句创建一个zval:
这是对的吗?
答案 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
指向它。
比较$i
和4
可能会暂时创建一个布尔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,因此通常不需要单独的内存分配。