[PHP源码阅读]explode和implode函数,explodeimplode
[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>//</span><span> 如果delimiter为空字符串,返回FALSE</span> <span>if</span> (delim_len == <span>0</span><span>) { php_error_docref(NULL TSRMLS_CC, E_WARNING, </span><span>"</span><span>Empty delimiter</span><span>"</span><span>); RETURN_FALSE; } </span><span>//</span><span> 初始化返回的数组</span> <span> array_init(return_value); </span><span>if</span> (str_len == <span>0</span><span>) { </span><span>if</span> (limit >= <span>0</span><span>) { </span><span>//</span><span> 如果字符串为空且limit大于等于0,则返回一个包含空字符串的数组,注意此处sizeof("") == 1</span> add_next_index_stringl(return_value, <span>""</span>, <span>sizeof</span>(<span>""</span>) - <span>1</span>, <span>1</span><span>); } </span><span>return</span><span>; } </span><span>//</span><span> 初始化zstr和zdelim的字符串变量</span> ZVAL_STRINGL(&zstr, str, str_len, <span>0</span><span>); ZVAL_STRINGL(</span>&zdelim, delim, delim_len, <span>0</span><span>); </span><span>if</span> (limit > <span>1</span><span>) { </span><span>//</span><span> limit大于1,limit默认是LONG_MAX</span> php_explode(&zdelim, &<span>zstr, return_value, limit); } </span><span>else</span> <span>if</span> (limit < <span>0</span><span>) { </span><span>//</span><span> limit 为负数</span> php_explode_negative_limit(&zdelim, &<span>zstr, return_value, limit); } </span><span>else</span><span> { </span><span>//</span><span> limit为0,被当作1处理,返回整个字符串,add_index_stringl函数将str追加到数组return_value中</span> add_index_stringl(return_value, <span>0</span>, str, str_len, <span>1</span><span>); }</span>
处理完特殊情况和初始化变量后,就调用php_explode/php_explode_negative_limit函数进行下一步处理。下面是php_explode函数的源码
php_explode
<span> endp </span>= Z_STRVAL_P(str) +<span> Z_STRLEN_P(str); </span><span>//</span><span> p1指向字符串的开始</span> p1 =<span> Z_STRVAL_P(str); </span><span>//</span><span> p2指向第一个分隔符的位置 ,找出分隔符位置主要用的是php_memnstr函数</span> p2 =<span> php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp); </span><span>if</span> (p2 ==<span> NULL) { </span><span>//</span><span> p2为NULL表示找不到分隔符,直接返回整个字符串</span> add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), <span>1</span><span>); } </span><span>else</span><span> { </span><span>do</span><span> { </span><span>//</span><span> 将p1添加到return_value数组中 ,移动到下一个分隔符的位置</span> add_next_index_stringl(return_value, p1, p2 - p1, <span>1</span><span>); p1 </span>= p2 +<span> Z_STRLEN_P(delim); } </span><span>while</span> ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL && --limit > <span>1</span><span>); </span><span>//</span><span> 将最后一个值追加到return_value</span> <span>if</span> (p1 <=<span> endp) add_next_index_stringl(return_value, p1, endp</span>-p1, <span>1</span><span>); }</span>
实现时调用了add_next_index_stringl将得到的每个字符串添加到数组return_value中。add_next_index_string是此功能的核心函数。
ZEND_API <span>int</span> add_next_index_stringl(zval *arg, <span>const</span> <span>char</span> *str, <span>uint</span> length, <span>int</span><span> duplicate) { zval </span>*<span>tmp; MAKE_STD_ZVAL(tmp); ZVAL_STRINGL(tmp, str, length, duplicate); </span><span>return</span> zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, <span>sizeof</span>(zval *<span>), NULL); }</span>
add_next_index_stringl函数调用zend_hash_next_index_insert函数将str插入到数组中。再看看php_explode_negative_limit函数的源码
php_explode_negative_limit
<span> //</span><span> 如果delimiter不在string中,且limit为负数,什么都不做,返回空的array,p2为NULL表示delimiter不在string中</span> <span>if</span> (p2 ==<span> NULL) { </span><span>/*<br /> 如果limit <= -1,那么什么都不做,因此如果只有一个字符串,那么- 1 + (limit) <= 0<br /> 返回空数组</span><span>*/</span><span> } </span><span>else</span><span> { </span><span>int</span> allocated = EXPLODE_ALLOC_STEP, found = <span>0</span><span>; </span><span>long</span><span> i, to_return; </span><span>char</span> **positions = emalloc(allocated * <span>sizeof</span>(<span>char</span> *<span>)); </span><span>//</span><span> 第一个单词的位置</span> positions[found++] =<span> p1; </span><span>do</span><span> { </span><span>if</span> (found >=<span> allocated) { allocated </span>= found + EXPLODE_ALLOC_STEP;<span>/*</span><span> 保证有足够的内存空间 </span><span>*/</span><span> positions </span>= erealloc(positions, allocated*<span>sizeof</span>(<span>char</span> *<span>)); } </span><span>//</span><span> positions保存每个单词的起始位置</span> positions[found++] = p1 = p2 +<span> Z_STRLEN_P(delim); } </span><span>while</span> ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) !=<span> NULL); </span><span>//</span><span> to_return 是return_value的数量,其实等于found - |limit|</span> to_return = limit +<span> found; </span><span>/*</span><span> limit至少是-1,因此不需要边界检查:i永远小于found </span><span>*/</span> <span>for</span> (i = <span>0</span>;i < to_return;i++) { <span>/*</span><span> 这个检查是检查to_return大于0 </span><span>*/</span><span> add_next_index_stringl(return_value, positions[i], (positions[i</span>+<span>1</span>] - Z_STRLEN_P(delim)) -<span> positions[i], </span><span>1</span><span> ); } efree(positions); }</span>
php_explode_negative_limit也是跟php_implode类似的操作,找到分隔的字符串之后,调用add_next_index_string函数将limit + found个字符串添加到return_value数组中。
implode
<p>string implode ( string $glue, array $pieces )</p> <p>string implode ( array $pieces )</p>
将一个一维数组的值转换为字符串
implode函数可以接收两种参数顺序。
核心代码
<span>if</span> (arg2 ==<span> NULL) { </span><span>//</span><span> 第二个参数为空,第一个参数必须为数组</span> <span>if</span> (Z_TYPE_PP(arg1) !=<span> IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, </span><span>"</span><span>Argument must be an array</span><span>"</span><span>); </span><span>return</span><span>; } MAKE_STD_ZVAL(delim); </span><span>#define</span> _IMPL_EMPTY "" <span>//</span><span> 默认使用""连接</span> ZVAL_STRINGL(delim, _IMPL_EMPTY, <span>sizeof</span>(_IMPL_EMPTY) - <span>1</span>, <span>0</span><span>); SEPARATE_ZVAL(arg1); arr </span>= *<span>arg1; } </span><span>else</span><span> { </span><span>//</span><span> 根据参数类型设置参数的值</span> <span>if</span> (Z_TYPE_PP(arg1) ==<span> IS_ARRAY) { arr </span>= *<span>arg1; convert_to_string_ex(arg2); delim </span>= *<span>arg2; } </span><span>else</span> <span>if</span> (Z_TYPE_PP(arg2) ==<span> IS_ARRAY) { arr </span>= *<span>arg2; convert_to_string_ex(arg1); delim </span>= *<span>arg1; } </span><span>else</span><span> { php_error_docref(NULL TSRMLS_CC, E_WARNING, </span><span>"</span><span>Invalid arguments passed</span><span>"</span><span>); </span><span>return</span><span>; } } </span><span>//</span><span> 调用php_implode函数进行转换</span> php_implode(delim, arr, return_value TSRMLS_CC);
在底层实现中,implode函数处理好参数之后就调用php_implode函数进行转换。
php_implode
<span> //</span><span> 遍历数组的每一个元素,判断其类型,然后调用smart_str_appendl函数将值追加到字符串中</span> <span>while</span> (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (<span>void</span> **) &tmp, &pos) ==<span> SUCCESS) { </span><span>switch</span> ((*tmp)-><span>type) { </span><span>case</span><span> IS_STRING: smart_str_appendl(</span>&<span>implstr, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); </span><span>break</span><span>; </span><span>case</span><span> IS_LONG: { </span><span>char</span> stmp[MAX_LENGTH_OF_LONG + <span>1</span><span>]; str_len </span>= slprintf(stmp, <span>sizeof</span>(stmp), <span>"</span><span>%ld</span><span>"</span><span>, Z_LVAL_PP(tmp)); smart_str_appendl(</span>&<span>implstr, stmp, str_len); } </span><span>break</span><span>; </span><span>case</span><span> IS_BOOL: </span><span>if</span> (Z_LVAL_PP(tmp) == <span>1</span><span>) { smart_str_appendl(</span>&implstr, <span>"</span><span>1</span><span>"</span>, <span>sizeof</span>(<span>"</span><span>1</span><span>"</span>)-<span>1</span><span>); } </span><span>break</span><span>; </span><span>case</span><span> IS_NULL: </span><span>break</span><span>; </span><span>case</span><span> IS_DOUBLE: { </span><span>char</span> *<span>stmp; str_len </span>= spprintf(&stmp, <span>0</span>, <span>"</span><span>%.*G</span><span>"</span>, (<span>int</span><span>) EG(precision), Z_DVAL_PP(tmp)); smart_str_appendl(</span>&<span>implstr, stmp, str_len); efree(stmp); } </span><span>break</span><span>; </span><span>case</span><span> IS_OBJECT: { </span><span>int</span><span> copy; zval expr; zend_make_printable_zval(</span>*tmp, &expr, &<span>copy); smart_str_appendl(</span>&<span>implstr, Z_STRVAL(expr), Z_STRLEN(expr)); </span><span>if</span><span> (copy) { zval_dtor(</span>&<span>expr); } } </span><span>break</span><span>; </span><span>default</span><span>: tmp_val </span>= **<span>tmp; zval_copy_ctor(</span>&<span>tmp_val); convert_to_string(</span>&<span>tmp_val); smart_str_appendl(</span>&<span>implstr, Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); zval_dtor(</span>&<span>tmp_val); </span><span>break</span><span>; } </span><span>//</span><span> 添加glue字符</span> <span>if</span> (++i !=<span> numelems) { smart_str_appendl(</span>&<span>implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim)); } zend_hash_move_forward_ex(Z_ARRVAL_P(arr), </span>&<span>pos); } </span><span>//</span><span> 在尾部添加字符0</span> smart_str_0(&implstr);
可以看到,php_implode函数遍历数组的每一个元素,判断其类型,并进行必要的类型转换,然后调用smart_str_appendl函数将值追加到字符串中。smart_str_appendl是implode实现代码中的核心函数。
smart_str_appendl
<span>#define</span> smart_str_appendl(dest, src, len) \<span> smart_str_appendl_ex((dest), (src), (len), </span><span>0</span><span>) </span><span>#define</span> smart_str_appendl_ex(dest, src, nlen, what) do { \<span> register size_t __nl; \ smart_str </span>*__dest = (smart_str *<span>) (dest); \ \ smart_str_alloc4(__dest, (nlen), (what), __nl); \ memcpy(__dest</span>->c + __dest-><span>len, (src), (nlen)); \ __dest</span>->len =<span> __nl; \ } </span><span>while</span> (<span>0</span>)
smart_str_appendl_ex主要调用memcpy函数进行字符串复制。
原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
如果本文对你有帮助,点个推荐吧,谢谢^_^。
更多PHP源码阅读文章:
[PHP源码阅读]strlen函数
[PHP源码阅读]strpos、strstr和stripos、stristr函数

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Die Explosionsfunktion in PHP ist eine Funktion zum Aufteilen einer Zeichenfolge in ein Array. Sie ist sehr verbreitet und flexibel. Bei der Verwendung der Explosionsfunktion treten häufig Fehler und Probleme auf. In diesem Artikel wird die grundlegende Verwendung der Explosionsfunktion vorgestellt und einige Methoden zur Lösung der Fehlerberichte bereitgestellt. 1. Grundlegende Verwendung der Explosionsfunktion In PHP lautet die grundlegende Syntax der Explosionsfunktion wie folgt: explosion(string$separator,string$stri

Titel: Häufige Fehler und Lösungen bei der Verwendung der Explosionsfunktion in PHP In PHP ist die Explosionsfunktion eine häufige Funktion, die zum Aufteilen eines Strings in ein Array verwendet wird. Allerdings können einige häufige Fehler aufgrund unsachgemäßer Verwendung oder eines falschen Datenformats auftreten. In diesem Artikel werden die Probleme analysiert, die bei der Verwendung der Explosionsfunktion auftreten können, und Lösungen sowie spezifische Codebeispiele bereitgestellt. Fehler 1: Der Trennzeichenparameter wird nicht übergeben. Bei der Verwendung der Explosionsfunktion besteht einer der häufigsten Fehler darin, dass der Trennzeichenparameter nicht übergeben wird.

Bei der PHP-Programmierung ist die Verarbeitung von Strings ein häufig erforderlicher Vorgang. Unter diesen sind das Teilen und Zusammenführen von Zeichenfolgen zwei häufige Anforderungen. Um diese Vorgänge bequemer durchführen zu können, stellt PHP zwei sehr praktische Funktionen zur Verfügung, nämlich die Explode- und Implode-Funktion. In diesem Artikel werden die Verwendung dieser beiden Funktionen sowie einige praktische Fertigkeiten vorgestellt. 1. Die Explosionsfunktion Die Explosionsfunktion wird verwendet, um eine Zeichenfolge gemäß dem angegebenen Trennzeichen aufzuteilen und ein Array zurückzugeben. Sein Funktionsprototyp ist wie folgt: arra

Verwenden Sie die PHP-Funktion „explode“, um einen String in ein Array aufzuteilen. Bei der PHP-Entwicklung kommt es häufig vor, dass Sie einen String entsprechend dem angegebenen Trennzeichen aufteilen müssen. Zu diesem Zeitpunkt können wir die in PHP integrierte Funktion „explode“ verwenden, um einen String in ein Array zu konvertieren. In diesem Artikel wird erläutert, wie Sie mit der Funktion „explode“ eine Zeichenfolge aufteilen, und es werden relevante Codebeispiele gegeben. Die grundlegende Syntax der Funktion „explode“ lautet wie folgt: arrayexplode(

Lösung für den PHP-Explosionsfehler: 1. Suchen und öffnen Sie den fehlerhaften PHP-Code. 2. Suchen Sie den Explosionsfunktionsteil , verwenden Sie das Array einfach durch Kommas.

In der PHP-Sprache gibt es viele Grundfunktionen, die uns helfen können, Strings schnell und effizient zu verarbeiten. Unter diesen ist die Explosionsfunktion eine sehr praktische Funktion zum Aufteilen von Zeichenfolgen. Es kann eine Zeichenfolge gemäß dem angegebenen Trennzeichen in Arrays aufteilen und dann flexiblere Zeichenfolgenoperationen ausführen. In diesem Artikel stellen wir vor, wie Sie die Explosionsfunktion zum Teilen von Zeichenfolgen in PHP verwenden. 1. Das Format der Explosionsfunktion in der PHP-Sprache ist wie folgt: explosion(separa

Verwenden Sie die PHP-Funktion „explode“, um einen String in mehrere Teilstrings aufzuteilen. Bei der PHP-Programmierung kommt es häufig vor, dass wir einen String in mehrere Teilstrings aufteilen müssen. Derzeit bietet PHP eine sehr praktische Funktion „Explodieren“, mit deren Hilfe wir diese Funktion einfach implementieren können. Die Syntax der Funktion „explode“ lautet wie folgt: arrayexplode(string$delimiter,string$string[,in

In diesem Artikel erfahren Sie, wie Sie die Funktion PHPExplode() verwenden, eine vordefinierte integrierte PHP-Funktion. Die Explosionsfunktion wird verwendet, um eine Zeichenfolge in kleinere Inhalte aufzuteilen. Mit der Explosionsfunktion in PHP können wir eine Zeichenfolge durch Umbrechen in kleinere Inhalte aufteilen. Diese Art von Trennzeichen wird als Trennzeichen bezeichnet. Syntax explosion(Trennzeichen, Zeichenfolge, Anzahl der Elemente ) Die Parameterexplosionsfunktion akzeptiert drei Parameter, von denen zwei obligatorisch und einer optional ist. Lassen Sie uns diese drei Parameter besprechen. Dieses Zeichen gibt den kritischen Punkt oder Punkt an, an dem die Zeichenfolge geteilt wird, d. h. wann immer dieses Zeichen in einer Zeichenfolge gefunden wird , symbolisiert es das Ende eines Elements im Array und den Anfang eines anderen Elements in der String-Eingabezeichenfolge.
