Профессиональное программирование на PHP

Страница 466 из 591


484 Глава 20 Устройство РНР и Zend Engine

Когда переменная выпадает из области действия (например, она определена в функции и эта функция возвращает ее значение) или когда переменная уничтожается, счетчик ссылок zval уменьшается на единицу. Когда zval re f count становится равным 0, система уборки мусора удаляет содержимое структуры.

Атрибут тип особенно интересен. Тот факт, что РНР является слабо типизированным языком, не означает, что переменные не имеют типов. Атрибут type структуры zval определяет текущий тип zval; это указывает на то, какая часть объединения zvalue_value содержит значение переменной.

Наконец, атрибут is_ref указывает на то, действительно ли zval содержит данные или просто является ссылкой на другой объект zval, содержащий данные.

Значение zval_value определяет, где в действительности хранятся данные для zval. Это объединение всех возможных базовых типов для переменных в РНР: длинных целых чисел, чисел с двойной точностью, строк, хеш-таблиц (массивов) и дескрипторов объектов. Объединение (union) в С представляет собой составной тип данных, который использует минимальное пространство для хранения различных возможных типов в разное время. На практике это означает, что данные, хранящиеся для zval, являются либо числом, строкой, массивом, или объектом, но они никогда не используют одновременно несколько типов. Это значительно отличает РНР от таких языков, как Perl, где все потенциальные представления могут сосуществовать (так, в Perl можно использовать переменную, которая имеет разные виды представления в зависимости от того, как к ней обращаются — как к строке или как к числу).

Когда программист переключает типы в РНР (что почти всегда происходит неявно, когда необходимо изменить текущую форму представления zval), zvalue_value конвертируется в необходимый формат. Именно поэтому можно использовать следующий код:

$а = "00"; $а += 0; echo $а;

который распечатывает 0, а не 0 0, потому что лишние символы были незаметно отброшены во время преобразования $а в целое число (вторая строка).

Типы переменных также важны при сравнении. Когда две переменные сравниваются с помощью оператора идентичности (===), сравниваются активные типы zval, и если они различны, то сравнение немедленно прекращается:

$а = 0; $Ь = ■0 • ;

echo ($а === $Ь)?"Идентичны":"Не идентичны"; По этой причине в данном примере условие ложно.

Сравнение, выполняемое с помощью оператора равенства (==), основывается на активных типах операндов. Если операнды являются строками или NULL-значениями, то они сравниваются как строки; если один из них имеет тип Boolean, то они преобразовываются в Boolean-значения и сравниваются; в противном случае они преобразовываются в числа и сравниваются. Хотя это приводит к симметричным результатам в сравнении с помощью оператора == (например, $а == $Ь то же самое, что $Ь == $а), сравнение нетранзитивно. Следующий пример был любезно предоставлен Дэном Коугиллом (Dan Cowgill):




  Hostland.Ru

 «Бесплатный хостинг Hostland.Su» © 2006