php中explode和implode函數


explode

array explode ( string $delimiter, string $string, [ , $limit ] )

函數返回由字符串組成的數組,每個元素都是string的一個子串,被字符串$delimiter作為邊界點分割出來。

參數說明

limit

如果設置了limit,且為正數,則返回的數組最多包含limit個元素,最后的那個元素將包含string的剩余部分。

如果limit是負數,則返回除了最后的-$limit個元素外的所有元素。

如果limit是0,則會被當做1。

delimiter

如果delimiter為空,則函數返回FALSE。如果delimiter不在string中,且limit為負數,則返回空數組。

運行示例

$str = 'hello,world,heiheihei,php';

先來看看不設置limit的情況

$arr = explode(',', $str);
print_r($arr);

運行結果1

limit為正數時,limit設為1,最多返回1個元素。

$arr = explode(',', $str, 1);
print_r($arr);

運行結果2

limit為負數,limit為-1,返回最后的1個元素外的所有元素。

$arr = explode(',', $str, -1);
print_r($arr);

運行結果3

limit為0,當作1處理。

$arr = explode(',', $str, 0);
print_r($arr);

運行結果4

explode執行步驟

1、接收參數,處理參數為空的情況

2、創建函數中使用的局部變量

3、根據limit的值調用不同的函數分隔字符串

explode函數的核心實現是php_explode函數,下面是該函數的執行流程圖:

explode流程

php_explode函數核心代碼:

if (p2 == NULL) {
        // 找不到分隔符,直接返回整個字符串
    add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1);
} else {
    do {
        // 將p1添加到return_value數組中
        add_next_index_stringl(return_value, p1, p2 - p1, 1);
        p1 = p2 + Z_STRLEN_P(delim);
    } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL &&
             --limit > 1);

    // 將最后一個值添加到return_value
    if (p1 <= endp)
        add_next_index_stringl(return_value, p1, endp-p1, 1);
}

源碼解讀

sizeof(“”) == 0。sizeof有兩種用法,sizeof(typename)sizeof(expression),當參數為typename是,即類型名稱,sizeof返回類型對應對象的大小;當參數為表達式時,sizeof計算表達式的返回類型對應對象的大小。此處,”“是表達式,sizeof計算編譯時編譯器分配給”“的空間,此時要算上\0的長度,因此是1,而strlen函數不會計算\0

如果不設置limit,limit的默認值是LONG_MAX。在php.h文件中,LONG_MAX定義為2147483647L。

在實現里面,如果limit大於1,則調用php_explode函數;如果limit小於0,則調用php_explode_negative_limit函數;如果limit等於0,則被當做1處理,此時調用add_index_stringl函數將str添加到數組return_value中。

在查找分隔符delimiter時,調用了php_memnstr函數 php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp); 而php_memnstr是zend_memnstr的宏定義,zend_memnstr實現里面,因此實際上是調用了C里面的memchr來查找字符delimiter。

找到分隔符的位置之后,就調用add_next_index_stringl函數將分隔得到的字符串插入到返回數組里。

implode

string implode ( string $glue, array $pieces )
string implode ( array $pieces )

將一個一維數組的值轉換為字符串

參數說明

implode函數可以接收兩種參數順序。另外,如果第一個參數為數組而第二個參數為空,則第二個參數為默認值’‘。此函數可以看作是explode的逆向過程。

當然,使用文檔規定的順序可避免混淆。

運行示例

$arr = array('hello', 'world');

按照文檔順序參數

$str = implode('-‘, $arr);// 輸出"hello-world"

第一個參數為數組

$str = implode($arr); // 輸出"helloworld"
$str = implode($arr, '-'); // 輸出"hello-world"

implode執行步驟

1、接收參數並賦值

2、如果第二個參數為空,則判斷第一個參數的類型是否為數組,如果不是,則報錯。否則,則使用”“對glue賦值,使用其作為連接符。

3、如果第二個參數不為空,那么,如果第一個參數是數組類型,則將第二個參數轉換成字符串類型;否則,如果第二個參數是數組類型,則將第一個參數轉換成字符串類型。

4、調用php_implode函數做字符串的連接。

implode函數設置完參數之后,底層就調用php_implode函數進行字符串連接,php_implode函數的執行流程圖如下:

implode流程

php_implode函數核心代碼:

// 遍歷數組的每一個元素,判斷其類型,然后調用smart_str_appendl函數將值追加到字符串中
    while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **) &tmp, &pos) == SUCCESS) {
        switch ((*tmp)->type) {
            case IS_STRING:
                smart_str_appendl(&implstr, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
                break;

            case IS_LONG: {
                char stmp[MAX_LENGTH_OF_LONG + 1];
                str_len = slprintf(stmp, sizeof(stmp), "%ld", Z_LVAL_PP(tmp));
                smart_str_appendl(&implstr, stmp, str_len);
            }
                break;

            case IS_BOOL:
                if (Z_LVAL_PP(tmp) == 1) {
                    smart_str_appendl(&implstr, "1", sizeof("1")-1);
                }
                break;

            case IS_NULL:
                break;

            case IS_DOUBLE: {
                char *stmp;
                str_len = spprintf(&stmp, 0, "%.*G", (int) EG(precision), Z_DVAL_PP(tmp));
                smart_str_appendl(&implstr, stmp, str_len);
                efree(stmp);
            }
                break;

            case IS_OBJECT: {
                int copy;
                zval expr;
                zend_make_printable_zval(*tmp, &expr, &copy);
                smart_str_appendl(&implstr, Z_STRVAL(expr), Z_STRLEN(expr));
                if (copy) {
                    zval_dtor(&expr);
                }
            }
                break;

            default:
                tmp_val = **tmp;
                zval_copy_ctor(&tmp_val);
                convert_to_string(&tmp_val);
                smart_str_appendl(&implstr, Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
                zval_dtor(&tmp_val);
                break;

        }

        // 添加glue字符
        if (++i != numelems) {
            smart_str_appendl(&implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim));
        }
        zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos);
    }
    // 在尾部添加結束字符0
    smart_str_0(&implstr);

源碼解讀

php_implode會逐個獲取數組里面的內容,然后判斷每個元素的類型,再做必要的數據類型轉換之后,調用smart_str_appendl函數將值追加到返回的字符串后面。最后,還要在字符串后面加上結束符,這是個必須的操作,以后編程時也應注意。

smart_str_appendl是函數smart_str_appendl_ex的宏定義,該函數調用了memcpy做字符串的復制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM