внутренности php — пытаясь понять zvals php

Я пытаюсь понять PHP zvals. Итак, рассмотрим следующий код:

<?php
$randomByteString = 'abcd';

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

echo $val;

Мне кажется, что zval будет создан для каждого из этих утверждений:

  • $ i = 0
  • ++$ я
  • $ я * 8
  • $ RandomByteString [$ я]
  • ога ($ randomByteString [$ я])
  • и при любом изменении в $ val

Это верно?

1

Решение

Не совсем. Давайте посмотрим на это построчно, рассказав, как PHP 5 будет обрабатывать эти звали.

<?php
$randomByteString = 'abcd';

Новый звал, содержащий 'abcd' создан и сейчас $randomByteString указывает на это.

Звал всего пока: 1

$val = 0;

Новый звал, содержащий 0 создан и сейчас $val указывает на это.

Звала пока что: 2

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

При первом запуске мы создаем zval для 0 и указать $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 для него.

Звала пока что: 4

}

echo $val;

Эхо не создаст звалс.

В конце сценария у вас есть 4 звали вокруг.

Кстати, zvals создан для $i < 4, $randomByteString[$i], ($i * 8) а также << являются все временный zvals: они не вызывают нового выделения памяти, вместо этого они хранятся в специальной области памяти, используемой для временных значений. Это означает, что при создании этих временных значений нет снижения производительности. Другие звалы (в том числе ord() по какой-то причине вызовы функций неэффективны), с другой стороны, требуют выделения памяти.

Кроме того, это все только для PHP 5. PHP 7 обрабатывает zvals более разумно, поэтому обычно для них не требуется отдельное выделение памяти.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]