PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit)
{
char *p1, *p2, *endp;
//Get it first It is the pointer to the end position of the source string
endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);
//Record starting position
p1 = Z_STRVAL_P(str);
//The following is Get the position of the separator in str. You can see that this method is also used in strrpos and strpos to locate
p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);
if (p2 == NULL) {
//Because of this, when we call explode('|', 'abc'); it is legal, and what comes out is array(0 => 'abc' )
add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1);
} else {
//Loop to obtain the position of the next delimiter in sequence until the end
do {
/ /The obtained substring (the section between the previous position and this position, the previous position is the beginning for the first time
add_next_index_stringl(return_value, p1, p2 - p1, 1);
//Positioning To the delimiter position p2 + the length of the delimiter
//For example, delimiter ='|', original string = 'ab|c', p2 = 2, then p1=2+1=3
p1 = p2 + Z_STRLEN_P(delim);
} while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL &&
--limit > 1);
//Put the string after the last delimiter into the result array
//explode('|', 'avc|sdf'); => array(0 => 'avc' , 1= > 'sdf')
if (p1 <= endp)
add_next_index_stringl(return_value, p1, endp-p1, 1);
}
}
<0 php_explode_negative_limit(zval *delim, zval *str, zval *return_value, long limit)
{
#define EXPLODE_ALLOC_STEP 64
char *p1, *p2, *endp; endp = Z_STRVAL_P(str) + Z_STRLEN_P(str); p1 = Z_STRVAL_P(str); p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp); if (p2 == NULL ) { //It is not processed here, then explode('|', 'abc', -1) becomes illegal and cannot get any value
/* do nothing since limit < ;= -1, thus if only one chunk - 1 + (limit) <= 0
by doing nothing we return empty array
*/
} else {
int allocated = EXPLODE_ALLOC_STEP, found = 0;
long i, to_return;
char **positions = emalloc(allocated * sizeof(char *));
//Note the declaration of positions here, this array is used to save all sub- The reading position of the string
positions[found++] = p1; //Of course the starting position still needs to be saved
//The following two loops, the first one is to loop through all delimiter positions that appear in the string , and save the next substring reading position
do {
if (found >= allocated) {
allocated = found + EXPLODE_ALLOC_STEP;/* make sure we have enough memory */
positions = erealloc(positions, allocated*sizeof(char *));
}
positions[found++] = p1 = p2 + Z_STRLEN_P(delim);
} while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL);
//This is the substring from which the returned result will be read from the array
to_return = limit + found;
/* limit is at least -1 therefore no need of bounds checking : i will be always less than found */
for (i = 0;i < to_return;i++) { /* this checks also for to_return > 0 */
add_next_index_stringl(return_value, positions[i],
(positions[i+1] - Z_STRLEN_P(delim)) - positions[i],
1
);
}
efree(positions); // Very important, release memory
}
#undef EXPLODE_ALLOC_STEP
}
3. limit = 1 or limit = 0 :
When all the first and second conditions are not met, this branch will be entered. This branch is simply to put the source string into the output array, explode('|', 'avc|sd' , 1) or explode('|', 'avc|sd', 0) will return array(0 => 'avc|sd');
Copy code
The code is as follows:
//add_index_stringl source code
//File 4: zend/zend_API.c
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); }
//zend_hash_next_index_insert //zend/zend_hash.h
#define zend_hash_next_index_insert(ht, pData, nDataSize .
Visible (excluding allocated space),
When limit>1, the efficiency is O(N) [N is the limit value],
When limitWhen limit=1 or limit=0, the efficiency is O(1)
http://www.bkjia.com/PHPjc/324052.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/324052.htmlTechArticleWhen we need to split an array into arrays based on a certain character or string, explode is very useful happy, but do you know~how explode works~~ First of all, you can be sure...