php对字符串进行数组操作

来源:互联网 发布:网络投诉中心电话 编辑:程序博客网 时间:2024/06/04 01:28

看到一道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
原创粉丝点击