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

首頁 > 編程 > PHP > 正文

[PHP源碼閱讀]explode和implode函數(shù)

2020-03-22 20:27:56
字體:
供稿:網(wǎng)友
  • explode和implode函數(shù)主要用作字符串-數(shù)組的操作,比如獲取一段參數(shù)后根據(jù)某個(gè)字符分割字符串,或者將一個(gè)數(shù)組的結(jié)果使用一個(gè)字符合并成一個(gè)字符串輸出。在PHP中經(jīng)常會(huì)用到這兩個(gè)函數(shù),因此有必要了解一下其原理。

    explode

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

    返回由字符串組成的數(shù)組,每個(gè)元素都是string的一個(gè)子串,被字符串$delimiter作為邊界點(diǎn)分割出來。

    $limit

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

    如果$limit是負(fù)數(shù),則返回除了最后的-$limit個(gè)元素外的所有元素。

    如果$limit是0,則會(huì)被當(dāng)做1。

    $delimiter

    如果$delimiter為空,則函數(shù)返回FALSE。如果delimiter不在string中,且$limit為負(fù)數(shù),則返回空數(shù)組。

    核心源碼
        // 如果delimiter為空字符串,返回FALSE    if (delim_len == 0) {        php_error_docref(NULL TSRMLS_CC, E_WARNING, 'Empty delimiter');        RETURN_FALSE;    }    // 初始化返回的數(shù)組    array_init(return_html' target='_blank'>value);    if (str_len == 0) {          if (limit >= 0) {              // 如果字符串為空且limit大于等于0,則返回一個(gè)包含空字符串的數(shù)組,注意此處sizeof('') == 1            add_next_index_stringl(return_value, '', sizeof('') - 1, 1);        }        return;    }    // 初始化zstr和zdelim的字符串變量    ZVAL_STRINGL(&zstr, str, str_len, 0);    ZVAL_STRINGL(&zdelim, delim, delim_len, 0);    if (limit > 1) {        // limit大于1,limit默認(rèn)是LONG_MAX        php_explode(&zdelim, &zstr, return_value, limit);    } else if (limit < 0) {        // limit 為負(fù)數(shù)        php_explode_negative_limit(&zdelim, &zstr, return_value, limit);    } else {        // limit為0,被當(dāng)作1處理,返回整個(gè)字符串,add_index_stringl函數(shù)將str追加到數(shù)組return_value中        add_index_stringl(return_value, 0, str, str_len, 1);    }

    處理完特殊情況和初始化變量后,就調(diào)用php_explode/php_explode_negative_limit函數(shù)進(jìn)行下一步處理。下面是php_explode函數(shù)的源碼

    php_explode
      endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);    // p1指向字符串的開始    p1 = Z_STRVAL_P(str);    // p2指向第一個(gè)分隔符的位置 ,找出分隔符位置主要用的是php_memnstr函數(shù)    p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);    if (p2 == NULL) {        // p2為NULL表示找不到分隔符,直接返回整個(gè)字符串        add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1);    } else {        do {            // 將p1添加到return_value數(shù)組中 ,移動(dòng)到下一個(gè)分隔符的位置            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);        // 將最后一個(gè)值追加到return_value        if (p1 <= endp)            add_next_index_stringl(return_value, p1, endp-p1, 1);    }

    實(shí)現(xiàn)時(shí)調(diào)用了add_next_index_stringl將得到的每個(gè)字符串添加到數(shù)組return_value中。add_next_index_string是此功能的核心函數(shù)。

    ZEND_API int add_next_index_stringl(zval *arg, const char *str, uint length, int duplicate) {    zval *tmp;    MAKE_STD_ZVAL(tmp);    ZVAL_STRINGL(tmp, str, length, duplicate);    return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);}

    add_next_index_stringl函數(shù)調(diào)用zend_hash_next_index_insert函數(shù)將str插入到數(shù)組中。再看看php_explode_negative_limit函數(shù)的源碼

    php_explode_negative_limit
      // 如果delimiter不在string中,且limit為負(fù)數(shù),什么都不做,返回空的array,p2為NULL表示delimiter不在string中    if (p2 == NULL) {        /*     如果limit <= -1,那么什么都不做,因此如果只有一個(gè)字符串,那么- 1 + (limit) <= 0     返回空數(shù)組*/    } else {        int allocated = EXPLODE_ALLOC_STEP, found = 0;        long i, to_return;        char **positions = emalloc(allocated * sizeof(char *));        // 第一個(gè)單詞的位置        positions[found++] = p1;        do {            if (found >= allocated) {                allocated = found + EXPLODE_ALLOC_STEP;/* 保證有足夠的內(nèi)存空間 */                positions = erealloc(positions, allocated*sizeof(char *));            }            // positions保存每個(gè)單詞的起始位置            positions[found++] = p1 = p2 + Z_STRLEN_P(delim);        } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL);        // to_return 是return_value的數(shù)量,其實(shí)等于found - |limit|        to_return = limit + found;        /* limit至少是-1,因此不需要邊界檢查:i永遠(yuǎn)小于found */        for (i = 0;i < to_return;i++) { /* 這個(gè)檢查是檢查to_return大于0 */            add_next_index_stringl(return_value, positions[i],                    (positions[i+1] - Z_STRLEN_P(delim)) - positions[i],                    1                );        }        efree(positions);    }

    php_explode_negative_limit也是跟php_implode類似的操作,找到分隔的字符串之后,調(diào)用add_next_index_string函數(shù)將limit + found個(gè)字符串添加到return_value數(shù)組中。

    implode

    string implode ( string $glue, array $pieces )

    string implode ( array $pieces )

    將一個(gè)一維數(shù)組的值轉(zhuǎn)換為字符串

    implode函數(shù)可以接收兩種參數(shù)順序。

    核心代碼
    if (arg2 == NULL) {        // 第二個(gè)參數(shù)為空,第一個(gè)參數(shù)必須為數(shù)組        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 ''        // 默認(rèn)使用''連接        ZVAL_STRINGL(delim, _IMPL_EMPTY, sizeof(_IMPL_EMPTY) - 1, 0);        SEPARATE_ZVAL(arg1);        arr = *arg1;    } else {        // 根據(jù)參數(shù)類型設(shè)置參數(shù)的值        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;        }    }    // 調(diào)用php_implode函數(shù)進(jìn)行轉(zhuǎn)換    php_implode(delim, arr, return_value TSRMLS_CC);

    在底層實(shí)現(xiàn)中,implode函數(shù)處理好參數(shù)之后就調(diào)用php_implode函數(shù)進(jìn)行轉(zhuǎn)換。

    php_implode
      // 遍歷數(shù)組的每一個(gè)元素,判斷其類型,然后調(diào)用smart_str_appendl函數(shù)將值追加到字符串中    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函數(shù)遍歷數(shù)組的每一個(gè)元素,判斷其類型,并進(jìn)行必要的類型轉(zhuǎn)換,然后調(diào)用smart_str_appendl函數(shù)將值追加到字符串中。smart_str_appendl是implode實(shí)現(xiàn)代碼中的核心函數(shù)。

    smart_str_appendl
    #define smart_str_appendl(dest, src, len)     smart_str_appendl_ex((dest), (src), (len), 0)#define smart_str_appendl_ex(dest, src, nlen, what) do {                register size_t __nl;                                                smart_str *__dest = (smart_str *) (dest);                                                                                                smart_str_alloc4(__dest, (nlen), (what), __nl);                        memcpy(__dest->c + __dest->len, (src), (nlen));                        __dest->len = __nl;                                                } while (0)

    smart_str_appendl_ex主要調(diào)用memcpy函數(shù)進(jìn)行字符串復(fù)制。

    原創(chuàng)文章 http://www.cnblogs.com/h-hq/p/5509090.html

    PHP編程

    鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

  • 發(fā)表評(píng)論 共有條評(píng)論
    用戶名: 密碼:
    驗(yàn)證碼: 匿名發(fā)表
    91影视免费在线观看| 在线国产伦理一区| 亚洲色婷婷一区二区三区| 国产精品亚洲自拍| wwww在线观看| 免费观看四虎精品成人| 国产jjizz一区二区三区视频| 在线碰免费视频在线观看| 国产精品久久一区| 欧美怡春院一区二区三区| 午夜精品久久久久久99热软件| 免费成年人视频在线观看| 亚洲aa在线观看| 免费国产一区二区| 夜夜操天天操亚洲| 欧美三级一区二区| 亚洲美女视频在线免费观看| 日本在线不卡一区二区| 天堂网在线资源| 久久这里精品国产99丫e6| 欧美日韩国产专区| 亚洲色图第三页| 精品亚洲a∨一区二区三区18| 在线观看免费黄色小视频| 久久精品无码一区二区三区毛片| 国产高潮国产高潮久久久91| 国产又粗又黄又猛| 日韩成人免费视频| 免费大片黄在线| 欧美成人性生活| 国产激情久久| 亚洲综合国产| www.日韩大片| 午夜影院免费版| 国产aaaaa毛片| 天天操 夜夜操| 国产福利片在线观看| 在线观看精品自拍视频| 日本天码aⅴ片在线电影网站| 先锋影音中文字幕| 国产九色精品成人porny| a屁视频一区二区三区四区| 国外成人在线视频网站| 狠狠色噜噜狠狠狠狠色吗综合| 国产又粗又猛又爽视频| 老司机午夜网站| 黑人巨大精品欧美一区二区桃花岛| 91免费国产在线| 色大师av一区二区三区| 色猫猫成人app| 五月天久久狠狠| 欧美magnet| 国产精品变态另类虐交| 超碰超碰超碰超碰| av电影免费在线| 成人激情av在线| 久久国产欧美| 欧美少妇一区| 国产欧美日韩一区二区三区| 精品欧美色视频网站在线观看| 在线不卡视频一区二区| www99xav| 天天做天天爱夜夜爽| 久久99精品久久久久久久青青日本| 爽爽爽在线观看| 亚洲香蕉伊在人在线观| 日韩精品黄色网| 97se国产在线视频| yy111111少妇影院日韩夜片| 欧美日韩在线免费播放| 黄色动漫网站入口| 久久精品久久久| 久久伊伊香蕉| 无码人妻精品一区二区三区9厂| 国产超碰人人爽人人做人人爱| 亚洲欧美综合国产精品一区| 国产稀缺精品盗摄盗拍| 免费精品一区二区三区在线观看| 久久99国产精品99久久| 色噜噜国产精品视频一区二区| 在线观看欧美日韩| 欧美福利视频一区二区| 国产做受高潮漫动| 日韩精品在线观看网站| 蜜桃91丨九色丨蝌蚪91桃色| 欧美激情按摩在线| 天海翼亚洲一区二区三区| 无码精品国产一区二区三区免费| 91首页免费视频| 国偷自拍第113页| 国产情侣第一页| 日韩视频精品在线观看| 3344国产永久在线观看视频| 中文字幕乱在线伦视频中文字幕乱码在线| 成人在线观看a| 性欧美一区二区三区| 99久免费精品视频在线观看| 青青草国产成人久久91网| 欧美一区二区视频免费观看| 亚洲欧洲av色图| 91亚洲人成网污www| 成人免费视频网址| 8x拔播拔播x8国产精品| 欧美中文字幕一二三四区| 小草av在线播放| 免费a级毛片永久免费| 精品剧情v国产在线观看在线| 黄色免费在线看| 猛男欧美办公室激情在线| 国产精品一区二区久久| 亚洲精品av在线| chinesegaysextube| 欧美一级做一级爱a做片性| 草民午夜欧美限制a级福利片| 免费亚洲一区| 福利所第一导航| 亚洲私拍视频| 欧美xxxx做受欧美88bbw| 精品视频在线导航| 蜜桃av一区二区三区电影| 国产精品yjizz视频网一二区| 欧美成年人视频网站欧美| 91麻豆国产在线观看| 国产亚洲精品久久久久久青梅| 国内一区二区在线视频观看| 亚洲久久久久久久久久| 精品一区二区三区在线播放视频| 国产精品成人a在线观看| 97精品视频在线观看| 亚洲色成人www永久在线观看| 亚洲精品tv久久久久久久久久| 成人激情黄色网| 精产国产伦理一二三区| 免费一看一级毛片| 黄色片在线播放| 国产精品一区二区三区成人| 欧美日韩人人澡狠狠躁视频| 日韩色级片先锋影音| 欧美夜福利tv在线| 久久免费视频网站| 尤物九九久久国产精品的分类| 欧美日韩亚洲国产一区| 国产极品在线观看| 欧美激情图片区| 国产视频一区免费看| 中文字幕中文字幕在线中一区高清| 稀缺呦国内精品呦| 久久视频社区| 欧美亚洲成人xxx| 久久色成人在线| 亚洲欧美专区| 国产精品黄页免费高清在线观看| 国产日韩在线免费观看| 视频精品导航| 中国一级特黄录像播放| 日韩美女精品| 夜夜狠狠擅视频| 97色成人综合网站| 超碰在线观看99| 亚洲乱亚洲乱妇无码| 亚洲缚视频在线观看| 亚洲动漫第一页| 国产喷水吹潮视频www| 91麻豆精品国产91久久| 国产精品一区二区亚洲| 欧美jizzhd精品欧美满| 美女黄视频在线观看| 日本系列欧美系列| 亚洲精品日韩激情在线电影| 综合天天久久| 国内精品卡一卡二卡三新区| 精品全国在线一区二区| 一区二区三区福利| 一区二区三视频| 成人mm视频在线观看| www在线观看免费视频| 久久久久久12| 色婷婷综合久久久久| 九九热精品在线观看| 久久久成人精品| 一区二区三区四区视频在线| 亚洲男人天堂久久| 国产成人精品男人的天堂538| 最新中文乱码字字幕在线| 成年人免费大片| 国产十八熟妇av成人一区| 免费下载黄色软件| 蜜桃视频免费网站| av一本在线| 久久精品国产亚洲7777| 日韩免费观看视频| 自拍亚洲欧美老师丝袜| 日本va欧美va国产激情| 天堂va久久久噜噜噜久久va| 国产精品久久久久久久久久久久午夜片| 精品久久av| 国产a久久麻豆| 国产剧情av在线播放| 成年人免费观看的视频| 青春草在线观看视频| 精品欧美一区二区在线观看| 日韩一区二区三区三四区视频在线观看| 91成人噜噜噜在线播放| 欧美三级美国一级| 天海翼在线观看视频| 亚洲精品免费在线播放| 国产白丝袜美女久久久久| www.国产成人| 国产精品亚洲综合色区韩国| 欧美黑人巨大videos精品| 国产亚洲精品久久久久久移动网络| 在线观看欧美日韩电影| 免费黄网站观看| www.视频在线.com| 亚洲波多野结衣| 男人透女人免费视频| 色视频成人在线观看免| 台湾成人免费视频| 亚洲色图欧美自拍| 国产一区二区日韩| 国产乱人伦精品一区二区三区| 国产精品欧美一区二区三区| 忘忧草在线www成人影院| youjizz.com日本| 老牛影视av老牛影视av| 日韩精品成人在线| 天天综合天天做天天综合| 大片免费在线看视频| 午夜精品久久久久久久久久久久| 欧美在线你懂的| 少妇大叫太粗太大爽一区二区| 日韩禁在线播放| 欧美日韩国产成人精品| 欧美mv日韩mv国产网站| 欧美a级大片在线| 国产又粗又黄视频| 亚洲在线视频一区二区| 99热手机在线观看| 成人毛片在线免费观看| 快射av在线播放一区| 丰满人妻一区二区三区四区| 男女男精品视频站| 一区二区高清在线| 国产不卡精品一区二区三区| 国产在线你懂得| 国产一区二区视频在线播放| 中文字幕精品一区二区精品| 人妖粗暴刺激videos呻吟| 亚洲深深色噜噜狠狠爱网站| 91国偷自产中文字幕久久| 97精品欧美一区二区三区| 99在线精品免费视频九九视| 欧美精品福利| 视频一区中文字幕| 国产精品视频分类| 中文字幕亚洲一区二区av在线| 伊人五月天婷婷| 无码人妻精品一区二区三区夜夜嗨| 日韩欧美中文视频| 美女视频网站久久| 不卡的一区二区| 夜夜骑日日射| 91精品啪在线观看国产爱臀| 母乳一区在线观看| 国内老司机av在线| 日韩视频www| 国产精品久久久久久99| 亚洲国产精久久久久久久| 成人vr资源| 青青草社区在线| 亚洲高清视频一区二区| 久久综合导航| 国内外成人激情视频| 亚洲综合图片| 俄罗斯精品一区二区三区| 美女视频网站久久| 无码人妻精品一区二区三区99v| 午夜电影久久久| 亚洲成av人片在线观看| sesexxxx| 女人天堂av手机在线| 日韩欧美国产小视频| 亚洲免费人成在线视频观看| 97婷婷大伊香蕉精品视频| 国产成人av一区二区三区不卡| 中文字幕区一区二区三| 久久九九有精品国产23| 日韩视频一区二区三区四区| 欧美大胆a人体大胆做受| 亚洲韩国在线| 欧美高清在线播放| 日本三级网站在线观看| 亚洲精美视频| 波多野结衣精品| 亚洲香蕉成人av网站在线观看| 日韩日韩日韩日韩| 成人一对一视频| 亚洲一品av免费观看| 亚洲国产成人一区二区| 丰满少妇高潮久久三区| 日本高清视频在线| 天天干,天天操,天天射| 国产日产精品久久久久久婷婷| 国产精品一区牛牛影视| 日韩精品福利片午夜免费观看| 国产日韩欧美精品一区二区三区| 亚洲综合激情另类专区老铁性| 国产亚洲欧美视频| 精品成人av一区二区三区| www.欧美com| 中文字幕一区二区三三| 亚洲天堂网一区| 亚洲色图 在线视频| 成人台湾亚洲精品一区二区| xfplay每日更新av资源在线| 精品成人av一区二区三区| 激情小视频在线| 国产精品美女久久久久久久久| 亚洲精品久久久久久久久久| eeuss国产一区二区三区四区| 成人在线免费播放视频| 国产精品国产三级国产普通话蜜臀| 黑人巨大精品欧美一区二区小视频| 国产二区视频在线播放| 成年人影院在线观看| 一个人看的日本免费视频| 国产在线一二区| hitomi一区二区三区精品|