ホームページ  >  記事  >  バックエンド開発  >  PHP 関数の部分文字列の置換 str_replace_PHP チュートリアル

PHP 関数の部分文字列の置換 str_replace_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:31:28919ブラウズ

str_replace 部分文字列置換 [str_replace]
mixed str_replace ( mixed $検索 , 混合 $replace , 混合 $subject [, int &] $count ] )
php関数 str_replace : 文字列または配列を返します。文字列または配列は、結局のところ、subjectsearchreplaceの結果に置き換えられたものです。

これで、この関数の使用法をいくつか知ることができます。 str_replace("#", "-", "dizaz#7#final")、str_replace(array('#', '$'), "-" 、 "dizaz#7$final") など。これらの呼び出しメソッドについて、[PHP カーネルを深く理解する] という観点から、PHP 内でどのように実装されているのかをここで簡単に分析してみます。

テストコード:

コードをコピーします コードは次のとおりです:

$object = "dizaz#7#final"
$res = str_replace("#", "-"; , $object );
echo $res;


上記と同様に、文字「#」を文字「-」に置き換えることから始めます。

準備作業:

PHP ソース コードを http://www.php.net からダウンロードします
コードを読み取るための独自のツールを作成します [VIM+CSCOPE を使用します] また、Linux ユーザーは、ソース コード ツール kscope [google]
コンパイル ツール [gcc]、デバッグ ツール [gdb]、および GDB グラフィカル ポート DDD も非常に優れています。PHP ソース コードをコンパイルするには、 --enable-debug [ を使用することを忘れないでください。もちろん、私も合格したいと思っています。/configure --help PHP が提供するコンパイル オプションのいくつかを見てください。多くのことを得ることができます]
分析を開始します:

[PHP カーネルの深い理解] を実行すると、PHP が提供する標準関数が格納されているディレクトリが PHP-SOURCE であることが簡単にわかります。DIR/ext/standard ディレクトリ内で、これは文字列関数であるため、str_replace によって実装されたファイル string.c を簡単に見つけることができます。次に、このファイルを分析します。 [もちろん、CScope で簡単にロックできます。cs find s str_replace を使用します]

定義と実装を確認するためのクエリ:

コードをコピー コードは次のとおりです:
/* {{{ protomixed str_replace(mixed search,mixed replace,mixed subject [, int &replace_count])
干し草の山内のすべての検索を replace に置き換えます */
PHP_FUNCTION(str_replace)
{
php_str_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1)

}
/ * }}} * /

次に、関数 php_str_replace_common function を表示する必要があります

コードをコピーします コードは次のとおりです:

/* {{{ 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 値;
* zend_uint refcount__gc;
* zend_uchar タイプ;
* zend_uchar is_ref__gc;
* };
*
* typedef Union _zvalue_value {
* long lval;
* ダブル dval;
* struct {
* char *val;
* int len;
* } str;
* ハッシュテーブル *ht;
* zend_object_value obj;
* } zvalue_value;
*
* typedef struct _zend_object {
* zend_class_entry *ce;
* ハッシュテーブル * プロパティ;
* ハッシュテーブル * ガード;
* } zend_object;
*
*/
zval **件名、**検索、*置換、**件名エントリ、 **zcount = NULL;
zval *結果;
char *string_key;
uint string_key_len;
ulong num_key;
int カウント = 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(検索);
SEPARATE_ZVAL(置換);
SEPARATE_ZVAL(件名);
/* 文字列を扱っていることを確認し、置換を行ってください。 */
if (Z_TYPE_PP(search) != IS_ARRAY) {
....//代码省滤
} else { /* サブジェクトが配列でない場合 */
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);
}
}
/* }}} */

继续跟追跡php_str_replace_in_subject
复制代代码如下:

/* {{{ in_subject
*/
static void php_str_replace_in_subject(zval *search, zval *replace, zval **subject, zval *result, int case_sensitivity, int *replace_count)
{
zval **search_entry,
**replace_entry = NULL,
temp_result;
char *replace_value = NULL;
int replace_len = 0;
/* 文字列を扱っていることを確認してください。 */
convert_to_string_ex(件名);
Z_TYPE_P(結果) = IS_STRING;
if (Z_STRLEN_PP(件名) == 0) {
ZVAL_STRINGL(結果, "", 0, 1);
戻る;
}
/* 検索が配列の場合 */
if (Z_TYPE_P(search) == IS_ARRAY) {
...//不走这步
} else {
if (Z_STRLEN_P(search) == 1) {
php_char_to_str_ex(Z_STRVAL_PP(subject),//subject の値、つまり dizaz#7#final
Z_STRLEN_PP(subject), //subject の長さを取得します
Z_STRVAL_P( search)[0], //ただ1つある”#”のため、最初の1文字が必要です
Z_STRVAL_P(replace), //所望の代替文字、现在“-”
Z_STRLEN_P(replace), //目标文字の長さ,现在は 1
result, //置換結果
case_sensitivity, //大小写否か否か,默认是 1
replace_count); //替替替次数} else if(z_strlen_p(search)> 1){
z_strval_p(result)= php_stto_str_ex(z_strval_pp(subject)、z_strlen_pp(subject)、
z_strval_p(search)、z_stlen_p(search)、
Z_prval_p(search) replace)、Z_STRLEN_P(replace)、&Z_STRLEN_P(result)、case_sensitivity、replace_count);
} else {
MAKE_COPY_ZVAL(件名, 結果);
}
}
}

に到達しました、私たちの目的は php_char_to_str_ex 関数を完了しました、この関数を分析する必要があるだけで OK です。

代码如下:

/* {{{ 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, int *replace_count)
{
int char_count = 0;
int replaceed = 0;
char *source, *target, *tmp, *source_end=str+len, *tmp_end = NULL; //case_sensitivity = 1
char *p = str, *e = p + len;
//
while ((p = memchr(p, from, (e - p))) {
char_count++
}
} else; を計算します。 {
for (source = str;source if (to lower(*source) == to lower(from)) {
}
}
}
if (char_count == 0 && case_sensitivity ) {
ZVAL_STRINGL(result, str, len, 1);
return
}
//置換後の長さを計算し、結果に格納します。
Z_STRLEN_P(result) = len + (char_count * (to_len - 1));
//メモリを適用し、置換されたデータを保存します
Z_STRVAL_P(result) = target =safe_emalloc(char_count, to_len, len + 1); /結果を文字列に設定します
Z_TYPE_P(result) = IS_STRING;
//ターゲットと結果の値はメモリの同じブロックを指すため、ターゲットのみを処理する必要があります
if (case_sensitivity) {
char *p = str, *e = p + len, *s = str;
while ((p = memchr(p, from, (e - p)))) { //どの文字が出現するかを決定する #
memcpy (target, s, (p - s)); // # の前のデータをターゲットにコピーします
target += p - s;
memcpy(target, to, to_len); // ターゲットの文字をターゲットにコピーします、このときのターゲットは開始ターゲット +p-s]
target += to_len;
s = p;
if (replace_count) {
*replace_count += 1; // 置換の数を設定します。 }
//さらにある場合は続行 ターゲットに追加された後、ターゲットが指すメモリ ブロックはすでに置き換えられたデータです。
if (s < e) {
memcpy(target, s, (e - s));
target += e - s;
}
} else {
for (source = str;source if (to lower(*source) == to lower(from)) {
replaced = 1;
if (replace_count) {
*replace_count += 1;
for (tmp = to, tmp_end = tmp+to_len) tmp < tmp_end;
*ターゲット = *tmp;
} else {
*ターゲット = *ソース;
/* }}} */


上でコメントしたように、これで文字の文字列への置換が完了しました。戻り方や詳しい処理については、PHPの実行処理を相対的に理解している必要があります。
もちろん、gdb を使用して php_char_to_str_ex 関数にブレークポイントを設定し、その詳細な実行プロセスを理解することもできます。
次回は文字列を文字列に置き換える解析についての記事になります。
概要:
結果は zval に保存されます
置換の実装は非常に巧妙であり、学ぶことができます
引き続きソースコードを表示し、さらに執筆スキルと設計スキルを学ぶ必要があります。




http://www.bkjia.com/PHPjc/323049.html

www.bkjia.com

本当

http://www.bkjia.com/PHPjc/323049.html

技術記事

str_replace — 部分文字列置換 [ str_replace ]mixed str_replace (mixed $search ,mixed $replace ,mixed $subject [, int nbsp; subject 内のすべての検索は replace によって置き換えられます...

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。