php对字符串进行数组操作

看到一道php笔试题目,如下:

$str = "hello";
//输出以下结果
echo $str[1];
echo count($str);

这道题是想了解开发人员对php内核的zvalue数据结构和count函数熟悉程度。初学者一般是背答案的,下面我们一起来分析下。


看看php源码目录php/Zend/Zend.h

typedef union _zvalue_value {
    long lval;                  /* long value */
    double dval;                /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;              /* hash table value */
    zend_object_value obj;
} zvalue_value;

_zvalue_value是表示php变量的联合体,当对一个变量赋值字符串时,结构体str的val指针指向字符串,len表示长度。

那么,$str[1]就表示为c语言的str[1],即是字符e。


看看php源码目录php/ext/Standard/Array.c

PHP_FUNCTION(count)
{
    zval *array;
    long mode = COUNT_NORMAL;
 
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &array, &mode) == FAILURE) {
        return;
    }
 
    switch (Z_TYPE_P(array)) {
        case IS_NULL:
            RETURN_LONG(0);
            break;
        case IS_ARRAY:
            RETURN_LONG (php_count_recursive (array, mode TSRMLS_CC));
            break;
        case IS_OBJECT: {
#ifdef HAVE_SPL
            zval *retval;
#endif
            /* first, we check if the handler is defined */
            if (Z_OBJ_HT_P(array)->count_elements) {
                RETVAL_LONG(1);
                if (SUCCESS == Z_OBJ_HT(*array)->count_elements(array, &Z_LVAL_P(return_value) TSRMLS_CC)) {
                    return;
                }
            }
#ifdef HAVE_SPL
            /* if not and the object implements Countable we call its count() method */
            if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) {
                zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval);
                if (retval) {
                    convert_to_long_ex(&retval);
                    RETVAL_LONG(Z_LVAL_P(retval));
                    zval_ptr_dtor(&retval);
                }
                return;
            }
#endif
        }
        default:
            RETURN_LONG(1);
            break;
    }
}

由此可看到,count函数对string处理直接进入default分支,返回1。


说说对数组使用count函数,count($array)直接读取HashTable结构体的nNumberOfElements,时间复杂度为0(1),就算在for阈值判断时使用没多大影响,就是看起来不舒服了。。。


static int php_count_recursive(zval *array, long mode TSRMLS_DC) 
{
	/*省略非关键代码*/
	cnt = zend_hash_num_elements(Z_ARRVAL_P(array));
	return cnt;
}


zend/zend_hash.c

ZEND_API int zend_hash_num_elements(const HashTable *ht)
{
	IS_CONSISTENT(ht);
	return ht->nNumOfElements;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值