亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP源碼閱讀 explode和implode函數

2020-03-22 18:13:47
字體:
來源:轉載
供稿:網友
  • explode和implode函數主要用作字符串和數組間轉換的操作,比如獲取一段參數后根據某個字符分割字符串,或者將一個數組的結果使用一個字符合并成一個字符串輸出。在PHP中經常會用到這兩個函數,因此有必要了解一下其原理。

    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);

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

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

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

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

    limit為0,當作1處理。

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

    explode執行步驟

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

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

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

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

    php_explode函數核心代碼:

        if (p2 == NULL) {            // 找不到分隔符,直接返回整個字符串        add_next_index_stringl(return_html' target='_blank'>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計算編譯時編譯器分配給''的空間,此時要算上的長度,因此是1,而strlen函數不會計算。

    如果不設置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函數的執行流程圖如下:

    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做字符串的復制。

    小結

    原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

    暫且寫這么多吧,還有更多的優化和PHP源碼中常用的函數,將會在以后的源碼閱讀中慢慢講述。

    如果本文對你有幫助,請點下推薦吧,謝謝^_^

    最后,我在github有對PHP源碼更詳細的注解。感興趣的可以圍觀一下,給個star。PHP5.4源碼注解。

    PHP編程

    鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

  • 發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
    国产欧美一区二区三区久久人妖| 欧美亚洲伦理www| 国产一区视频在线播放| 色老头一区二区三区| 日日狠狠久久偷偷四色综合免费| 色偷偷偷亚洲综合网另类| 欧美一区二区三区……| 国产日韩在线看片| 亚洲精品国精品久久99热| 亚洲人成五月天| 影音先锋欧美精品| 日本久久亚洲电影| 成人精品aaaa网站| 国产伦精品一区二区三区精品视频| 亚洲自拍偷拍视频| 久久久噜噜噜久久久| 成人精品福利视频| 国产玖玖精品视频| 国产精品成人av性教育| 欧洲美女免费图片一区| 91在线看www| 亚洲第一福利在线观看| 狠狠色噜噜狠狠狠狠97| 欧美黄色片在线观看| 亚洲色图18p| 国产一区二区三区四区福利| 一区二区三区久久精品| 国产99久久精品一区二区| 91国产在线精品| 日韩电影在线观看免费| 91美女福利视频高清| 久久青草精品视频免费观看| 亚洲一区二区三区在线视频| 亚洲成年网站在线观看| 国产精品高潮呻吟久久av黑人| 亚洲一区二区久久久| 国产mv免费观看入口亚洲| 97激碰免费视频| 成人久久精品视频| 精品偷拍各种wc美女嘘嘘| 精品国产成人在线| 中文字幕日本精品| 国产成人亚洲综合91精品| 91爱爱小视频k| 97久久伊人激情网| 国产a∨精品一区二区三区不卡| 一区二区三区视频观看| 国产日韩一区在线| 激情成人中文字幕| 国产91色在线|免| 成人免费淫片视频软件| 日本精品视频在线| 成人免费观看49www在线观看| 欧美亚洲视频在线看网址| 影音先锋日韩有码| 最近2019年好看中文字幕视频| 欧美网站在线观看| 精品亚洲国产视频| 久久久av亚洲男天堂| 亚洲欧美成人精品| 欧美激情xxxxx| 精品久久久久久久久久久久久| 国产婷婷色综合av蜜臀av| 97视频com| 成人av番号网| 一级做a爰片久久毛片美女图片| 在线播放国产一区中文字幕剧情欧美| 亚洲人成亚洲人成在线观看| 亚洲一区二区免费在线| 狠狠久久亚洲欧美专区| 国产一区二区在线免费视频| 国产精品久久久久久av福利| 亚洲高清不卡av| 精品亚洲夜色av98在线观看| 在线亚洲男人天堂| 在线观看日韩www视频免费| 亚洲少妇激情视频| 久久影视三级福利片| 国产美女精品视频免费观看| 国产精品黄色影片导航在线观看| 亚洲人a成www在线影院| 亚洲欧美色图片| 粉嫩av一区二区三区免费野| 精品无人区太爽高潮在线播放| 亚洲男人第一av网站| 2018中文字幕一区二区三区| 精品久久国产精品| 国产亚洲精品久久久久久| 97久久伊人激情网| 九九热在线精品视频| 色狠狠av一区二区三区香蕉蜜桃| 欧美视频一区二区三区…| 91麻豆国产语对白在线观看| 成人妇女淫片aaaa视频| 欧美性xxxxx极品| 欧美二区乱c黑人| 国产成人精品a视频一区www| 51色欧美片视频在线观看| 国产精品永久免费在线| 日本精品免费一区二区三区| 97在线观看视频国产| 久久久久免费视频| 欧洲亚洲在线视频| 欧美性猛交xxxx免费看久久久| 国产成人综合精品在线| 国产成人精品在线| 久久精品91久久久久久再现| …久久精品99久久香蕉国产| 在线观看欧美日韩| 在线亚洲欧美视频| 日本久久精品视频| 久久国产视频网站| 色噜噜狠狠狠综合曰曰曰88av| 久久精品视频va| 欧美美女操人视频| 久久噜噜噜精品国产亚洲综合| 精品免费在线视频| 亚洲成人黄色网| 国产精品自拍小视频| 亚洲精品www久久久久久广东| 中文字幕日韩有码| 日韩欧美成人网| 2020久久国产精品| 国产精品久久久久久久久粉嫩av| 亚洲人成网站色ww在线| 久久免费在线观看| 久青草国产97香蕉在线视频| 日韩av手机在线| 国产精品美女视频网站| 国产精品女主播视频| 成人免费福利在线| 欧美激情一级精品国产| 日韩国产精品亚洲а∨天堂免| 精品动漫一区二区三区| 97精品久久久中文字幕免费| 另类专区欧美制服同性| 亚洲精品网站在线播放gif| 亚洲理论在线a中文字幕| 亚洲一区二区三区在线视频| 在线视频日韩精品| 欧美巨猛xxxx猛交黑人97人| 国产成人精品免高潮费视频| 国产999在线| 97香蕉久久夜色精品国产| 中文字幕国产日韩| 亚洲人成免费电影| 26uuu日韩精品一区二区| 国产不卡一区二区在线播放| 国内精品久久久久久久久| 国产精品黄页免费高清在线观看| 热久久视久久精品18亚洲精品| 2018中文字幕一区二区三区| 91精品国产色综合久久不卡98| 91禁外国网站| 日韩美女av在线免费观看| 亚洲国产小视频在线观看| 欧美日韩国内自拍| 欧美小视频在线观看| 国产欧美一区二区三区久久| 国产日产亚洲精品| 成人精品视频在线| 一本色道久久88综合日韩精品| 日本在线观看天堂男亚洲| 欧美激情xxxxx|