str_replace — Sub-string substitution[
Str_replace]
Mixed Str_replace ( Mixed $search , Mixed $replace , Mixed $subject [ , int & $count ] )
PHP functions
Str_replace: Returns a string or array. The string or array is the
subject In all of the
Search have been
Replace The result after the replacement.
Now we can know some of the uses of this function, such as: Str_replace ("#", "-", "dizaz#7#final"), Str_replace (Array (' # ', ' $ '), "-", "dizaz#7$final"), etc., In the case of these calls, how PHP is implemented internally, given the [deep understanding of the PHP kernel], here is a small analysis.
Test code:
Copy CodeThe code is as follows:
$object = "Dizaz#7#final";
$res = Str_replace ("#", "-", $object);
Echo $res;
As above, first replace the character "#" with the character "-" to begin.
Preparatory work:
Download PHP source code, http://www.php.net download can
Tools to build your own reading code [I use Vim+cscope] Another: Linux users also recommend graphical view of source code Tools Kscope [Google]
compilation tools [GCC], debugging tools [GDB], other: GDB graphical port ddd is also very good, recommended
Compile PHP source code, remember to use--enable-debug [of course also hope to pass./configure--help See some of the compilation options provided by PHP, there will be a lot of gains]
Start Analysis:
Reading in [Deep understanding of the PHP kernel], it is not difficult to find that its PHP provides standard functions in the directory Php-source-dir/ext/standard directory, because it is a string function, it is easy for us to find the Str_replace function implementation of the file in this directory STRING.C, the next step revolves around this file for analysis. [Of course with Cscope is easy to lock, with: CS find S Str_replace]
The query learns its definition implementation:
Copy CodeThe code is as follows:
/* {{{proto mixed str_replace (mixed search, mixed replace, mixed subject [, int &replace_count])
Replaces all occurrences of search in haystack with replace */
Php_function (Str_replace)
{
Php_str_replace_common (Internal_function_param_passthru, 1);
}
/* }}} */
Now you need to see the function Php_str_replace_common function
Copy CodeThe code is as follows:
/* {{{Php_str_replace_common
*/
static void Php_str_replace_common (internal_function_parameters, int case_sensitivity)
{
/**
* TODO
* typedef struct _ZVAL_STRUCT zval;
* typedef struct _ZEND_CLASS_ENTRY Zend_class_entry
*
* struct _zval_struct {
* Zvalue_value value;
* Zend_uint refcount__gc;
* Zend_uchar type;
* Zend_uchar is_ref__gc;
* };
*
* typedef Union _ZVALUE_VALUE {
* Long lval;
* Double dval;
* struct {
* Char *val;
* int Len;
*} str;
* HashTable *ht;
* Zend_object_value obj;
*} Zvalue_value;
*
* typedef struct _ZEND_OBJECT {
* Zend_class_entry *ce;
* HashTable *properties;
* HashTable *guards;
*} Zend_object;
*
*/
Zval **subject, **search, **replace, **subject_entry, **zcount = NULL;
Zval *result;
Char *string_key;
UINT String_key_len;
ULONG Num_key;
int count = 0;
int argc = Zend_num_args ();
if (Zend_parse_parameters (Zend_num_args () tsrmls_cc, "zzz| Z ", &search, &replace, &subject, &zcount) = = FAILURE) {
Return
}
Separate_zval (search);
Separate_zval (replace);
Separate_zval (subject);
/* Make sure we ' re dealing with strings and do the replacement. */
if (z_type_pp (search) = Is_array) {
....//Code Save filter
} else {/* If subject is isn't an array */
Php_str_replace_in_subject (*search, *replace, subject, Return_value, case_sensitivity, (argc > 3)? &count:null) ;
}
if (argc > 3) {
Zval_dtor (*zcount);
Zval_long (*zcount, Count);
}
}
/* }}} */
Continue tracking Php_str_replace_in_subject
Copy CodeThe code is as follows:
/* {{{Php_str_replace_in_subject
*/
static void Php_str_replace_in_subject (Zval *search, Zval *replace, Zval **subject, zval *result, int case_sensitivity, in T *replace_count)
{
Zval **search_entry,
**replace_entry = NULL,
Temp_result;
char *replace_value = NULL;
int replace_len = 0;
/* Make sure we ' re dealing with strings. */
CONVERT_TO_STRING_EX (subject);
Z_type_p (Result) = is_string;
if (z_strlen_pp (subject) = = 0) {
Zval_stringl (Result, "", 0, 1);
Return
}
/* If Search is an array */
if (z_type_p (search) = = Is_array) {
...//Do not take this step
} else {
if (z_strlen_p (search) = = 1) {///example only "#" So, perform this step.
PHP_CHAR_TO_STR_EX (z_strval_pp (subject),//subject value, which is dizaz#7#final
Z_STRLEN_PP (subject),//Get the length of subject
Z_strval_p (search) [0],//due to only 1 "#", only the first character is required
Z_strval_p (replace),//the character to be replaced, now is "-"
Z_strlen_p (replace),//The length of the target character, now 1
result,//Replace results
Case_sensitivity,//Case sensitive, default is 1
Replace_count); Number of replacements
} else if (z_strlen_p (search) > 1) {
Z_strval_p (Result) = PHP_STR_TO_STR_EX (z_strval_pp (subject), z_strlen_pp (subject),
Z_strval_p (search), z_strlen_p (search),
Z_strval_p (replace), z_strlen_p (replace), &z_strlen_p (Result), case_sensitivity, Replace_count);
} else {
Make_copy_zval (subject, result);
}
}
}
So far, our goal has finally been locked into the PHP_CHAR_TO_STR_EX function, and now it's OK to just parse the function. In fact, it is now:
Copy CodeThe code is as follows:
/* {{{PHP_CHAR_TO_STR_EX
*/
Phpapi int php_char_to_str_ex (char *str, uint Len, char from, char *to, int to_len, Zval *result, Int. case_sensitivity, in T *replace_count)
{
int char_count = 0;
int replaced = 0;
Char *source, *target, *tmp, *source_end=str+len, *tmp_end = NULL;
if (case_sensitivity) {//Now case_sensitivity = 1
char *p = str, *e = p + len;
Calculation needs to be replaced several times
while (P = MEMCHR (P, from, (E-p)))) {
char_count++;
p++;
}
} else {
for (source = str; source < source_end; source++) {
if (ToLower (*source) = = ToLower (from)) {
char_count++;
}
}
}
if (Char_count = = 0 && case_sensitivity) {
Zval_stringl (result, str, Len, 1);
return 0;
}
Calculates the length of the replacement and stores it in result.
Z_strlen_p (Result) = Len + (Char_count * (to_len-1));
Request memory, store the replaced data
Z_strval_p (Result) = target = Safe_emalloc (Char_count, To_len, Len + 1);
Set result is a string
Z_type_p (Result) = is_string;
Both target and result values point to the unified block memory, so you only need to handle the target
if (case_sensitivity) {
char *p = str, *e = p + len, *s = str;
while (P = MEMCHR (P, from, (e-p))) {//judgment appears in the first few characters #
memcpy (Target, S, (p-s)); Copy the previous # data to target
Target + = P-s;
memcpy (target, to, To_len); Copy the target character to target[of course at this point the target is to start target+p-s]
Target + = To_len;
p++;
s = p;
if (Replace_count) {
*replace_count + = 1; Set the number of replacements
}
}
If there is, continue adding to target, so that the block of memory pointed to by Target is already a replacement data.
if (S < e) {
memcpy (Target, S, (e-s));
Target + = E-s;
}
} else {
for (source = str; source < source_end; source++) {
if (ToLower (*source) = = ToLower (from)) {
replaced = 1;
if (Replace_count) {
*replace_count + = 1;
}
for (TMP = to, tmp_end = Tmp+to_len; tmp < tmp_end; tmp++) {
*target = *tmp;
target++;
}
} else {
*target = *source;
target++;
}
}
}
*target = 0;
return replaced;
}
/* }}} */
As noted above, this completes the substitution of characters to strings. As for how to return, how a detailed process, need to have a relative understanding of the PHP implementation process.
Of course, you can use the GDB down breakpoint to the PHP_CHAR_TO_STR_EX function, to understand its detailed execution process.
The next article is to do an analysis of string substitution for strings.
Summary:
The result is the presence of Zval
The implementation of the replacement is quite ingenious and can be learned
You need to continue to view the source code, learn more writing skills and design skills.
http://www.bkjia.com/PHPjc/323049.html www.bkjia.com true http://www.bkjia.com/PHPjc/323049.html techarticle str_replace-substring substitution [str_replace] mixed str_replace (mixed $search, mixed $replace, mixed $subject [, int nbsp; All search in subject is replaced by replace ...