[PHP source code reading] explode and implode functions, explodeimplode. [PHP source code reading] explode and implode functions, explodeimplodeexplode and implode functions are mainly used for string-Array Operations. for example, after obtaining a parameter, a string is split based on a specific character, [PHP source code reading] explode and implode functions, explodeimplode
The explode and implode functions are mainly used as string-Array Operations. for example, after a parameter is obtained, a string is split based on a character, or the result of an array is combined into a string for output. These two functions are often used in PHP, so it is necessary to understand their principles.
Explode
array explode ( string $delimiter, string $string, [ , $limit ] )
Returns an array composed of strings. each element is a substring of a string, which is separated by the string $ delimiter as the boundary point.
$ Limit
If $ limit is set and the value is positive, the returned array can contain up to $ limit elements, and the last element will contain the rest of $ string.
If $ limit is a negative number, all elements except the last-$ limit element are returned.
If $ limit is 0, it is treated as 1.
$ Delimiter
If $ delimiter is empty, the function returns FALSE. If delimiter is not in string and $ limit is a negative number, an empty array is returned.
Core source code
// If delimiter is a NULL string, FALSE is returned if (delim_len = 0) {php_error_docref (NULL TSRMLS_CC, E_WARNING, "Empty delimiter"); RETURN_FALSE ;} // initialize the returned array array_init (return_value); if (str_len = 0) {if (limit> = 0) {// if the string is empty and the limit value is greater than or equal to 0, returns an array containing an empty string. Note that sizeof ("") = 1 add_next_index_stringl (return_value, "", sizeof ("")-1, 1 );} return;} // initialize the string variables ZVAL_STRINGL (& zstr, str, str_len, 0) of zstr and zdelim; ZVAL_STRINGL (& zdelim, delim, delim_len, 0 ); if (limit> 1) {// limit is greater than 1, the default limit is LONG_MAX php_explode (& zdelim, & zstr, return_value, limit);} else if (limit <0) {// limit is negative php_explode_negative_limit (& zdelim, & zstr, return_value, limit);} else {// limit is 0, which is treated as 1 and returns the entire string, add_index_stringl function adds str to the array return_value add_index_stringl (return_value, 0, str, str_len, 1 );}
CallPhp_explode/Php_explode_negative_limitFunction. The following is the source code of the php_explode function.
Php_explode
Endp = Z_STRVAL_P (str) + Z_STRLEN_P (str); // p1 points to the start position of the string p1 = Z_STRVAL_P (str); // p2 points to the position of the first separator, the php_memnstr function p2 = php_memnstr (Z_STRVAL_P (str), Z_STRVAL_P (delim), Z_STRLEN_P (delim), and endp) are used to locate the separator. if (p2 = NULL) {// If p2 is NULL, the separator cannot be found. The entire string add_next_index_stringl (return_value, p1, Z_STRLEN_P (str), 1) is directly returned );} else {do {// add p1 to the return_value array and move it to the next separator location add_next_index_stringl (return_value, p 1, 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); // Append the last value to return_value if (p1 <= endp) add_next_index_stringl (return_value, p1, endp-p1, 1 );}
Called during implementationAdd_next_index_stringlAdd each string to the array.Return_value. Add_next_index_string is the core function of this function.
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 function callZend_hash_next_index_insertThe function inserts str into the array. Let's take a look at the source code of the php_explode_negative_limit function.
Php_explode_negative_limit
// If delimiter is not in string and limit is negative, nothing is done. an empty array is returned. if p2 is NULL, delimiter is not in string. if (p2 = NULL ){/*
If limit <=-1, nothing is done. Therefore, if there is only one string,-1 + (limit) <= 0
Returns an empty array */} else {int allocated = EXPLODE_ALLOC_STEP, found = 0; long I, to_return; char ** positions = emalloc (allocated * sizeof (char *)); // positions [found + +] = p1; do {if (found> = allocated) {allocated = found + EXPLODE_ALLOC_STEP; /* Ensure sufficient memory space */positions = erealloc (positions, allocated * sizeof (char *));} // positions save the start position of each word positions [found ++] = p1 = p2 + Z_STRLEN_P (delim);} w Hile (p2 = php_memnstr (p1, Z_STRVAL_P (delim), Z_STRLEN_P (delim), endp ))! = NULL); // to_return is the number of return_value, which is actually equal to found-| limit | to_return = limit + found;/* limit must be at least-1, so no border check is required: I will always be less than found */for (I = 0; I <to_return; I ++) {/* This check checks that to_return is greater than 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 is similar to php_implode. after finding the separator string, call the add_next_index_string function to add the limit + found strings to the return_value array.
Implode
string implode ( string $glue, array $pieces )
string implode ( array $pieces )
Converts the value of a one-dimensional array to a string.
The implode function can receive two parameter sequences.
Core code
If (arg2 = NULL) {// The second parameter is NULL. The first parameter must be an array 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 "" // by default, ZVAL_STRINGL (delim, _ IMPL_EMPTY, sizeof (_ IMPL_EMPTY)-1, 0); SEPARATE_ZVAL (arg1 ); arr = * arg1;} else {// set the parameter value if (Z_TYPE_PP (arg1) = IS_ARRAY) {arr = * arg1; convert_to_string_ex (arg2) based on the parameter type ); delim = * arg2;} else if (Z_TYPE_PP (arg2) = IS_ARRAY) {arr = * arg2; convert_to_string_ex (arg1); delim = * arg1 ;} else {Encode (NULL TSRMLS_CC, E_WARNING, "Invalid arguments passed"); return ;}// call the php_implode function to convert php_implode (delim, arr, return_value TSRMLS_CC );
At the underlying implementation level, the implode function is called after processing parameters.Php_implodeFunction.
Php_implode
// Traverse every element of the array, determine its type, and call the smart_str_appendl function to append the value to the string 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 [limit + 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; values (& tmp_val); convert_to_string (& tmp_val); values (& implstr, Z_STRVAL (tmp_val), Z_STRLEN (tmp_val); zval_dtor (& tmp_val ); break;} // add the glue character if (++ I! = Numelems) {smart_str_appendl (& implstr, Z_STRVAL_P (delim), Z_STRLEN_P (delim);} substring (Z_ARRVAL_P (arr), & pos );} // add the character 0 smart_str_0 (& implstr) at the end );
We can see that the php_implode function traverses every element of the array, judges its type, converts the necessary types, and then callsSmart_str_appendlThe function appends the value to a string. Smart_str_appendl is the core function in implode implementation code.
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_exMemcpyFunction to copy strings.
The original article is limited in writing, so it is easy to learn. if there is anything wrong with the article, please let us know.
If this article is helpful to you, please make a suggestion. thank you! ^_^.
For more PHP source code reading articles:
[PHP source code reading] strlen function
[PHP source code reading] strpos, strstr, stripos, stristr functions
Explode and implode functions are mainly used as string-Array Operations. for example, after obtaining a parameter, a string is split based on a specific character ,...