PHP内核探索:变量的类型转换
PHP内核    2019-04-25 15:45:33    17    0    0
admin   PHP内核

现在我们已经可以从符号表中获取用户在PHP语言里定义的变量了,是该做点其它事的时候了,举个比例,比如给它来个类型转换:-)。想想C语言中的类型转换细则,你的头是不是已经大了?但是变量的类型转换就是如此重要,如果没有,那我们的代码就会是下面这样了:

01void display_zval(zval *value)
02{
03    switch (Z_TYPE_P(value)) {
04        case IS_NULL:
05            /* 如果是NULL,则不输出任何东西 */
06            break;
07         
08        case IS_BOOL:
09            /* 如果是bool类型,并且true,则输出1,否则什么也不干 */
10            if (Z_BVAL_P(value)) {
11                php_printf("1");
12            }
13            break;
14        case IS_LONG:
15            /* 如果是long整型,则输出数字形式 */
16            php_printf("%ld", Z_LVAL_P(value));
17            break;
18        case IS_DOUBLE:
19            /* 如果是double型,则输出浮点数 */
20            php_printf("%f", Z_DVAL_P(value));
21            break;
22        case IS_STRING:
23            /* 如果是string型,则二进制安全的输出这个字符串 */
24            PHPWRITE(Z_STRVAL_P(value), Z_STRLEN_P(value));
25            break;
26        case IS_RESOURCE:
27            /* 如果是资源,则输出Resource #10 格式的东东 */
28            php_printf("Resource #%ld", Z_RESVAL_P(value));
29            break;
30        case IS_ARRAY:
31            /* 如果是Array,则输出Array5个字母! */
32            php_printf("Array");
33            break;
34        case IS_OBJECT:
35            php_printf("Object");
36            break;
37        default:
38            /* Should never happen in practice,
39             * but it's dangerous to make assumptions
40             */
41             php_printf("Unknown");
42             break;
43    }
44}

看完上面的代码,你是不是有点似曾相识的感觉?o(∩∩)o...哈哈,和直接<?php echo $foo;?>这个简单到极点的php语句来比,上面的实现算是天书了。当然,真正的环境并没有这么囧,内核中提供了好多函数专门来帮我们实现类型转换的功能,你需要的只是调用一个函数而已。这一类函数有一个统一的形式:convert_to_*()

01//将任意类型的zval转换成字符串
02void change_zval_to_string(zval *value)
03{
04    convert_to_string(value);
05}
06 
07//其它基本的类型转换函数
08ZEND_API void convert_to_long(zval *op);
09ZEND_API void convert_to_double(zval *op);
10ZEND_API void convert_to_null(zval *op);
11ZEND_API void convert_to_boolean(zval *op);
12ZEND_API void convert_to_array(zval *op);
13ZEND_API void convert_to_object(zval *op);
14 
15ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
16#define convert_to_string(op) if ((op)->type != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }

这里面有两个比较特殊,一个就是convert_to_string其实是一个宏函数,调用的另外一个函数;第二个便是没有convert_to_resource()的转换函数,因为资源的值在用户层面上,根本就没有意义,内核不会对它的值(不是指那个数字)进行转换。

好了,我们用php的echo的时候会先把变量转换成字符串,但是我们看见convert_to_string的参数是zval*的,你是不是开始担心在进行数据转换时破坏了原来数据的值?而我们<?php $a=intval($b);?>并不会破坏$b的值。把原来的值破坏掉的做法绝对不是一个好主意,内核中在echo一个变量的时候也不是这样做的。在下一章,我们将知道怎样便可以在不损坏原变量值的情况下,进行convert_to_类操作。

上一篇: PHP内核探索:弱类型变量的实现

下一篇: PHP内核探索:变量的检索

17
登录 后评论.
没有帐号? 现在注册.
0 评论
Table of content