摘要:現(xiàn)在我們已經(jīng)可以從符號表中獲取用戶在PHP語言里定義的變量了,是該做點其它事的時候了,舉個比例,比如給它來個類型轉(zhuǎn)換 。想想C語言中的類型轉(zhuǎn)換細(xì)則,你的頭是不是已經(jīng)大了?但是變量的類型轉(zhuǎn)換就是如此重要,如果沒有,那我們的代碼就會是下面這樣了:void display_zval(zval *value) { s
現(xiàn)在我們已經(jīng)可以從符號表中獲取用戶在PHP語言里定義的變量了,是該做點其它事的時候了,舉個比例,比如給它來個類型轉(zhuǎn)換 。想想C語言中的類型轉(zhuǎn)換細(xì)則,你的頭是不是已經(jīng)大了?但是變量的類型轉(zhuǎn)換就是如此重要,如果沒有,那我們的代碼就會是下面這樣了:
void display_zval(zval *value) { switch (Z_TYPE_P(value)) { case IS_NULL: /* 如果是NULL,則不輸出任何東西 */ break; case IS_BOOL: /* 如果是bool類型,并且true,則輸出1,否則什么也不干 */ if (Z_BVAL_P(value)) { php_printf("1"); } break; case IS_LONG: /* 如果是long整型,則輸出數(shù)字形式 */ php_printf("%ld", Z_LVAL_P(value)); break; case IS_DOUBLE: /* 如果是double型,則輸出浮點數(shù) */ php_printf("%f", Z_DVAL_P(value)); break; case IS_STRING: /* 如果是string型,則二進制安全的輸出這個字符串 */ PHPWRITE(Z_STRVAL_P(value), Z_STRLEN_P(value)); break; case IS_RESOURCE: /* 如果是資源,則輸出Resource #10 格式的東東 */ php_printf("Resource #%ld", Z_RESVAL_P(value)); break; case IS_ARRAY: /* 如果是Array,則輸出Array5個字母! */ php_printf("Array"); break; case IS_OBJECT: php_printf("Object"); break; default: /* Should never happen in practice, * but it's dangerous to make assumptions */ php_printf("Unknown"); break; } }
看完上面的代碼,你是不是有點似曾相識的感覺?o(∩∩)o...哈哈,和直接<?php echo $foo;?>這個簡單到極點的php語句來比,上面的實現(xiàn)算是天書了。當(dāng)然,真正的環(huán)境并沒有這么囧,內(nèi)核中提供了好多函數(shù)專門來幫我們實現(xiàn)類型轉(zhuǎn)換的功能,你需要的只是調(diào)用一個函數(shù)而已。這一類函數(shù)有一個統(tǒng)一的形式:convert_to_*()
//將任意類型的zval轉(zhuǎn)換成字符串 void change_zval_to_string(zval *value) { convert_to_string(value); } //其它基本的類型轉(zhuǎn)換函數(shù) ZEND_API void convert_to_long(zval *op); ZEND_API void convert_to_double(zval *op); ZEND_API void convert_to_null(zval *op); ZEND_API void convert_to_boolean(zval *op); ZEND_API void convert_to_array(zval *op); ZEND_API void convert_to_object(zval *op); ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC); #define convert_to_string(op) if ((op)->type != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
這里面有兩個比較特殊,一個就是convert_to_string其實是一個宏函數(shù),調(diào)用的另外一個函數(shù);第二個便是沒有convert_to_resource()的轉(zhuǎn)換函數(shù),因為資源的值在用戶層面上,根本就沒有意義,內(nèi)核不會對它的值(不是指那個數(shù)字)進行轉(zhuǎn)換。
好了,我們用php的echo的時候會先把變量轉(zhuǎn)換成字符串,但是我們看見convert_to_string的參數(shù)是zval*的,你是不是開始擔(dān)心在進行數(shù)據(jù)轉(zhuǎn)換時破壞了原來數(shù)據(jù)的值?而我們<?php $a=intval($b);?>并不會破壞$b的值。把原來的值破壞掉的做法絕對不是一個好主意,內(nèi)核中在echo一個變量的時候也不是這樣做的。在下一章,我們將知道怎樣便可以在不損壞原變量值的情況下,進行convert_to_類操作。