taoCMS是基于php+sqlite/mysql的国内最小(100Kb左右)的功能完善的CMS管理系统

解读zend_api字符串替换之php_str_replace_common

2012-04-05

INTERNAL_FUNCTION_PARAMETERS 是一个宏

static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensitivity)
{
zval **subject, **search, **replace, **subject_entry, **zcount;
zval *result;
char *string_key;
uint string_key_len;
ulong num_key;
int count = 0;
int argc = ZEND_NUM_ARGS();
    如果传递过来的参数个数少于三个或者多余四个则报参数错误
if (argc < 3 || argc > 4 ||
    zend_get_parameters_ex(argc, &search, &replace, &subject, &zcount) == FAILURE) {
   WRONG_PARAM_COUNT;
}
   分离变量
SEPARATE_ZVAL(search);
SEPARATE_ZVAL(replace);
SEPARATE_ZVAL(subject);
把要操作的数据转换成字符串,查找的跟替换的都不是数组的情况
/* Make sure we're dealing with strings and do the replacement. */
if (Z_TYPE_PP(search) != IS_ARRAY) {
   convert_to_string_ex(search);
   convert_to_string_ex(replace);
} else if (Z_TYPE_PP(replace) != IS_ARRAY) {
   convert_to_string_ex(replace);
}
如果原始字符串是一个数组
/* if subject is an array */
if (Z_TYPE_PP(subject) == IS_ARRAY) {
   初始化一个需要返回的数组
     array_init(return_value);
   zend_hash_internal_pointer_reset(Z_ARRVAL_PP(subject));
开始循环subject数组
   /* For each subject entry, convert it to string, then perform replacement
     and add the result to the return_value array. */
   取得当前值
   while (zend_hash_get_current_data(Z_ARRVAL_PP(subject), (void **)&subject_entry) == SUCCESS) {
    如果当前值不是数组并且不是对象
      if (Z_TYPE_PP(subject_entry) != IS_ARRAY && Z_TYPE_PP(subject_entry) != IS_OBJECT) {
     申请并初始化一个新的的 zval 容器
          MAKE_STD_ZVAL(result);
          分离变量,制作一份拷贝
     SEPARATE_ZVAL(subject_entry);
     调用替换函数
     php_str_replace_in_subject(*search, *replace, subject_entry, result, case_sensitivity, (argc > 3) ? &count : NULL);
    } else {
       创建一个变量
     ALLOC_ZVAL(result);
     ZVAL_ADDREF增加引用,让系统不要在调用函数完毕后删除
     ZVAL_ADDREF(*subject_entry);
     COPY_PZVAL_TO_ZVAL(*result, *subject_entry);
    }
    /* Add to return array */
    得到当前key的属性
    switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key,
             &string_key_len, &num_key, 0, NULL)) {
             如果hash数组的key是字符串类型的                
     case HASH_KEY_IS_STRING:
      add_assoc_zval_ex(return_value, string_key, string_key_len, result);
      break;
              如果是数字类型的
     case HASH_KEY_IS_LONG:
      add_index_zval(return_value, num_key, result);
      break;
    }
       指向下一个数组元素
    zend_hash_move_forward(Z_ARRVAL_PP(subject));
   }
} else { /* if subject is not an array */
   如果原数据不是数组
     php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity, (argc > 3) ? &count : NULL);

if (argc > 3) {
   析构函数自动销毁变脸用这里为啥要用没理解呢
     zval_dtor(*zcount);
     给变量赋值
   ZVAL_LONG(*zcount, count);
}
}

类别:技术文章 | 阅读:195481 | 评论:0 | 标签:zend php

想收藏或者和大家分享这篇好文章→

“解读zend_api字符串替换之php_str_replace_common”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

taoCMS发布taoCMS 3.0.2(最后更新21年03月15日),请大家速速升级,欢迎大家试用和提出您宝贵的意见建议。

捐助与联系

☟请使用新浪微博联系我☟

☟在github上follow我☟

标签云