zoukankan      html  css  js  c++  java
  • PHP源码阅读笔记一(explode和implode函数分析)

    PHP源码阅读笔记一
    一、explode和implode函数
    array explode ( string separator, string string [, int limit] )
    此函数返回由字符串组成的数组,每个元素都是 string 的一个子串,它们被字符串 separator 作为边界点分割出来。如果设置了 limit 参数,则返回的数组包含最多 limit 个元素,而最后那个元素将包含 string 的剩余部分。

    此函数的时间复杂度应该是O(strlen(separator) * strlen(string))
    其实现过程基本上是遍历字符串string,将它与separator比较,如果相同,则写入hash表,并将string的指针移到新的位置(即每一个separator的右边);

    另外,对于limit小于0的情况有特殊处理
    本函数实现主要是依赖于php_memnstr函数,在php.h文件中我们可以看到它的定义,
    #define php_memnstr zend_memnstr
    其真正的函数是zend_memnstr,在Zend/zend_operators.h文件的217行,可以看到它的定义,其实现主要是一个while循环和两个C语言的函数memchr和memcmp

    php源代码如下:

    PHP_FUNCTION(explode)
    {
    char *str, *delim;
    int str_len = 0, delim_len = 0;
    long limit = LONG_MAX; /* No limit */
    zval zdelim, zstr;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &delim, &delim_len, &str, &str_len, &limit) == FAILURE) {
    return;
    }

    if (delim_len == 0) {
    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
    RETURN_FALSE;
    }

    array_init(return_value);

    if (str_len == 0) {
    if (limit >= 0) {
    add_next_index_stringl(return_value, "", sizeof("") - 1, 1);
    }
    return;
    }

    ZVAL_STRINGL(&zstr, str, str_len, 0);
    ZVAL_STRINGL(&zdelim, delim, delim_len, 0);
    if (limit > 1) {
    php_explode(&zdelim, &zstr, return_value, limit);
    } else if (limit < 0) {
    php_explode_negative_limit(&zdelim, &zstr, return_value, limit);
    } else {
    add_index_stringl(return_value, 0, str, str_len, 1);
    }
    }



    string implode ( string glue, array pieces )
    此函数返回一个以glue字符串连接的pieces数组的各元素的字符串。
    此函数可以是以一个数组为参数,可以是以一个数组和一个字符串为参数,并且字符串和数组的顺序可以改变,这些在程序中都有针对每种情况的特殊处理,如下代码:

    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
    
                  if (argc == 1) {
                                if (Z_TYPE_PP(arg1) != IS_ARRAY) {                            //              只有一个参数并且还不是数组
                                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument must be an array");
                                              return;
                                }
     
                                MAKE_STD_ZVAL(delim);
    #define _IMPL_EMPTY ""
                                ZVAL_STRINGL(delim, _IMPL_EMPTY, sizeof(_IMPL_EMPTY) - 1, 0);
     
                                SEPARATE_ZVAL(arg1);
                                arr = *arg1;
                  } else {              //              两个参数
                                if (Z_TYPE_PP(arg1) == IS_ARRAY) {              //              如果每一个参数是数组
                                              arr = *arg1;
                                              convert_to_string_ex(arg2);
                                              delim = *arg2;
                                } else if (Z_TYPE_PP(arg2) == IS_ARRAY) {              //              如果第二个参数是数组
                                              arr = *arg2;
                                              convert_to_string_ex(arg1);
                                              delim = *arg1;
                                } else {
                                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments passed");
                                              return;
                                }
                  }

    最后数组都会赋值给arr,分隔字符串赋值给delim,没有的置为””

    就是一个遍历数组,并连接字符串的过程,只是这个过程中使用了smart_str相关函数(更多相关请移步 ),针对不同的类型作了不同的连接操作(如果是数字还需要将数字转化成字符串,这些在smart_str中都有相关函数处理)

    本文地址:PHP源码阅读笔记一:explode和implode函数    文章出处:PHP源码阅读,PHP设计模式,PHP学习笔记,项目管理-胖胖的空间

    转载请以链接形式注明原始出处和作者,谢绝不尊重版权者抄袭!

  • 相关阅读:
    1082 射击比赛 (20 分)
    1091 N-自守数 (15 分)
    1064 朋友数 (20 分)
    1031 查验身份证 (15 分)
    1028 人口普查 (20 分)
    1059 C语言竞赛 (20 分)
    1083 是否存在相等的差 (20 分)
    1077 互评成绩计算 (20 分)
    792. 高精度减法
    791. 高精度加法
  • 原文地址:https://www.cnblogs.com/yubinbin/p/3551246.html
Copyright © 2011-2022 走看看