【PHP源码阅读】explode和implode函数,explodeimplode_PHP教程
【PHP源码阅读】explode和implode函数,explodeimplode
explode和implode函数主要用作字符串和数组间转换的操作,比如获取一段参数后根据某个字符分割字符串,或者将一个数组的结果使用一个字符合并成一个字符串输出。在PHP中经常会用到这两个函数,因此有必要了解一下其原理。
explode
<p>array explode ( string $delimiter, string $string, [ , $limit ] )</p>
函数返回由字符串组成的数组,每个元素都是string的一个子串,被字符串$delimiter作为边界点分割出来。
参数说明
limit
如果设置了$limit,且为正数,则返回的数组最多包含$limit个元素,最后的那个元素将包含$string的剩余部分。
如果$limit是负数,则返回除了最后的-$limit个元素外的所有元素。
如果$limit是0,则会被当做1。
delimiter
如果$delimiter为空,则函数返回FALSE。如果delimiter不在string中,且$limit为负数,则返回空数组。
运行示例
<span>$str</span> = 'hello,world,heiheihei,php';
先来看看不设置limit的情况
<span>$arr</span> = <span>explode</span>(',', <span>$str</span><span>); </span><span>print_r</span>(<span>$arr</span>);
limit为正数时,limit设为1,最多返回1个元素。
<span>$arr</span> = <span>explode</span>(',', <span>$str</span>, 1<span>); </span><span>print_r</span>(<span>$arr</span>);
limit为负数,limit为-1,返回最后的1个元素外的所有元素。
<span>$arr</span> = <span>explode</span>(',', <span>$str</span>, -1<span>); </span><span>print_r</span>(<span>$arr</span>);
limit为0,当作1处理。
<span>$arr</span> = <span>explode</span>(',', <span>$str</span>, 0<span>); </span><span>print_r</span>(<span>$arr</span>);
explode执行步骤
<p>1、接收参数,处理参数为空的情况</p> <p>2、创建函数中使用的局部变量</p> <p>3、根据limit的值调用不同的函数分隔字符串</p>
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
<p>string implode ( string $glue, array $pieces )<br />string implode ( array $pieces )</p>
将一个一维数组的值转换为字符串
参数说明
implode函数可以接收两种参数顺序。另外,如果第一个参数为数组而第二个参数为空,则第二个参数为默认值''。此函数可以看作是explode的逆向过程。
当然,使用文档规定的顺序可避免混淆。
运行示例
<span>$arr</span> = <span>array</span>('hello', 'world');
按照文档顺序参数
<span>$str</span> = <span>implode</span>('-‘, $arr);// 输出"hello-world"
第一个参数为数组
<span>$str</span> = <span>implode</span>(<span>$arr</span><span>); // 输出"helloworld" </span><span>$str</span> = <span>implode</span>(<span>$arr</span>, '-'); // 输出"hello-world"
implode执行步骤
<p>1、接收参数并赋值<br />2、如果第二个参数为空,则判断第一个参数的类型是否为数组,如果不是,则报错。否则,则使用""对glue赋值,使用其作为连接符。<br />3、如果第二个参数不为空,那么,如果第一个参数是数组类型,则将第二个参数转换成字符串类型;否则,如果第二个参数是数组类型,则将第一个参数转换成字符串类型。<br />4、调用php_implode函数做字符串的连接。</p>
在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, ©);
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源码注解。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP中的explode函數是用來將字串分割成陣列的函數,它非常常用且靈活。在使用explode函數的過程中,常常會遇到一些報錯和問題,本文將介紹explode函數的基本用法並提供一些解決報錯的方法。一、explode函數基本用法在PHP中,explode函數的基本語法如下:explode(string$separator,string$stri

標題:PHP中使用explode函數時常見的錯誤及解在PHP中,explode函數是用來將字串分割成陣列的常用函數。然而,由於使用不當或資料格式不正確,可能會導致一些常見的錯誤。本文將針對使用explode函數時可能遇到的問題進行分析,並提供解決方案和具體的程式碼範例。錯誤一:未傳入分隔符號參數在使用explode函數時,最常見的錯誤之一是未傳入分隔

在PHP程式設計中,處理字串是經常需要進行的操作。其中,分割和合併字串則是兩種常見的需求。為了更方便地進行這些操作,PHP提供了兩個非常實用的函數,即explode和implode函數。本文將介紹這兩個函數的用法,以及一些實用的技巧。一、explode函數explode函數用於將一個字串依照指定的分隔符號分割,並傳回一個陣列。其函數原型如下:arra

使用PHP函數"explode"將字串拆分為數組在PHP開發中,經常會遇到需要將一個字串依照指定的分隔符號進行拆分的情況。這時,我們可以使用PHP內建函數"explode"來實現字串到陣列的轉換。本文將介紹如何使用"explode"函數來拆分字串,並給出相關的程式碼範例。 "explode"函數的基本語法如下:arrayexplode(

在PHP語言中,有許多基礎函數可以幫助我們快速有效地處理字串。其中,explode函數是一個很實用的字串分割函數。它可以將一個字串依照指定的分割符分割成數組,進而進行更靈活的字串操作。在本文中,我們將會介紹PHP中如何使用explode函數來分割字串。一、explode函數格式explode函數在PHP語言的格式如下:explode(separa

php explode報錯的解決方法:1、找到並打開出錯的PHP代碼;2、找到explode函數部分;3、修改代碼為“dump(explode(',',$str));die;”,也就是用逗號分割為數組即可。

使用PHP函數"explode"將字串拆分為多個子字串在PHP編程中,我們經常會遇到需要將一個字串拆分為多個子字串的情況。這時,PHP提供了一個非常方便的函數"explode",可以幫助我們輕鬆實現這個功能。 "explode"函數的語法如下:arrayexplode(string$delimiter,string$string[,in

在本文中,了解如何使用PHPExplode()函數,該函數是預先定義的內建PHP函數。 explode函數用於「將字串拆分為PHP中的explode函數使我們能夠透過break將一個字串分解成更小的內容。這種分隔符號稱為分隔符號。語法explode(分隔符號,字串,元素數)參數爆炸函數接受三個參數,其中兩個是強制的,一個是可選的。讓我們討論這三個參數。分隔符號這個字元指定臨界點或點字串將在此分割,即每當在字串中找到該字元時,它就像徵著數組中一個元素的結束和另一個元素的開始。String輸入字串
