内核判断php数组索引是字符串还是数字

为了能在遍历时同时接收索引的值,就像PHP语言中这样的功能:

?
1
2
3
4
5
6
<?php
foreach ( $arr as $key => $val )
{
     echo "The value of $key is: $val\n" ;
}
?>

为了配合zend_hash_apply_with_arguments()函数,我们需要使其接受索引作为一个参数:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int php_sample_print_zval_and_key(zval **val, int num_args, va_list args,zend_hash_key *hash_key)
{
     //重新copy一个zval,防止破坏原数据
     zval tmpcopy = **val;
     /* tsrm_ls is needed by output functions */
     TSRMLS_FETCH();
     zval_copy_ctor(&tmpcopy);
     INIT_PZVAL(&tmpcopy);
     
     //转换为字符串
     convert_to_string(&tmpcopy);
     
     //执行输出
     php_printf( "The value of " );
     if (hash_key->nKeyLength)
    {
        //如果是字符串类型的key
        PHPWRITE(hash_key->arKey, hash_key->nKeyLength);
    }
    else
    {
        //如果是数字类型的key
        php_printf("%ld", hash_key->h);
    }
     
     php_printf( " is: " );
     PHPWRITE(Z_STRVAL(tmpcopy), Z_STRLEN(tmpcopy));
     php_printf( "\n" );
     
     //毁尸灭迹
     zval_dtor(&tmpcopy);
     /* continue; */
     return ZEND_HASH_APPLY_KEEP;
}

执行遍历:

?
1
zend_hash_apply_with_arguments(arrht,php_sample_print_zval_and_key, 0);
这个函数通过C语言中的可变参数特性来接收参数。This particular example required no arguments to be passed; for information on extracting variable argument lists from va_list args, see the POSIX documentation pages for va_start(), va_arg(), and va_end().
当我们检查这个hash_key是字符串类型还是数字类型时,是通过nKeyLength属性来检测的,而不是arKey属性。这是因为内核有时候会留在arKey属性里些脏数据,但nKeyLength属性是安全的,可以安全的使用。甚至对于空字符串索引,它也照样能处理。比如:$foo[''] ="Bar";索引的值是NULL字符,但它的长度却是包括最后这个NULL字符的,所以为1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值