PHP の strtr 関数の奇妙な動作の説明

不言
リリース: 2023-04-01 21:42:01
オリジナル
1525 人が閲覧しました

この記事では、主に PHP の strtr 関数のいくつかの奇妙な動作について説明します。必要な方は参考にしてください。 PHP の strtr 関数 動作の説明

数日前、友人が strtr 関数にはいくつかの奇妙な動作があるという記事を送ってきました。

PHP のソース コードを見ると、次のような説明を受けました。

[奇妙な動作 1]

まず、この PHP 文字列置換関数 strtr()

strtr(string,from,to)
の 2 つの状態を見てみましょう。または strtr(string,array )
まず、strtr 関数の最初のメソッドについてです。
次の例を見てみましょう。

   echo strtr("I Love you","Lo","lO");
ログイン後にコピー

得られる結果は、

I lOve yOu です。


この結果は私たちに思い出させます

1.strtr 大文字と小文字が区別されます

[ソース コード分析 1]

strtr 関数の最後の実装関数は php_strtr です

   PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen){int i;unsigned char xlat[256]; 
 if ((trlen < 1) || (len < 1)) {return str;} 
 for (i = 0; i < 256; xlat[i] = i, i++); 
 for (i = 0; i < trlen; i++) {xlat[(unsigned char) str_from[i]] = str_to[i];} 
 for (i = 0; i < len; i++) {str[i] = xlat[(unsigned char) str[i]];} 
 return str;}
ログイン後にコピー

関数全体は 256 文字のハッシュ置換を実行します。もちろん、これらの 256 文字には大文字と小文字が含まれます。

[奇妙な動作 2]

2.strtr の置換は非常に特殊です。真ん中の O を見てください。これは明らかに私たちの意図ではありません。 ##[ソースコード分析 2]

原則は上記と同じで、それぞれに当てはまります。対応する文字の置換は文字に基づいているため、置換されるのは文字列ではなく文字です。

[奇妙な動作 3]

この php sttr 関数を説明するために別の特別な例を示します。奇妙な

   echo strtr("I Love you","Love","");
ログイン後にコピー

結果は

I Love you

何も変わりません。したがって、strtr は次の点に注意する必要があります。最後のパラメータである空に置き換えることはできません。パラメータを空の文字列にすることはできません。もちろん、スペースは許可されます。

[ソース コード分析 3]

string.c ファイルの 2833 行目では、呼び出しプログラムが次のとおりであることがわかります。

   php_strtr(Z_STRVAL_P(return_value),
 Z_STRLEN_P(return_value),
 Z_STRVAL_PP(from),
 Z_STRVAL_PP(to),
 MIN(Z_STRLEN_PP(from), 
 Z_STRLEN_PP(to)));
ログイン後にコピー

MIN(Z_STRLEN_PP( from)、Z_STRLEN_PP (to)) は、from と to の 2 つの文字列の長さの最小値です。3 に示すケースでは、結果は 0 になります。php_strtr 関数から、

if ((trlen < 1) || (len < 1)) {return str;}
ログイン後にコピー

When がわかります。長さが 1 未満の場合は、元の文字列を返します。それで。 。 。 。

[奇妙な動作 4]

strtr 関数の別の例

 echo strtr("I Loves you","Love","lOvEA");
ログイン後にコピー

結果は次のとおりです

I lOvEs yOu

3 番目のパラメータの A は結果には表示されないことに注意してください。

[ソース コード分析 3]

理由は 2 番目のパラメータと同様です。 ) は、from と to の両方を取得します。文字列の中で最も小さい長さです。

  static void php_strtr_array(zval *return_value, char *str, int slen, HashTable *hash){
  zval **entry;char  *string_key;
  uint   string_key_len;zval **trans;
  zval   ctmp;ulong num_key;
  int minlen = 128*1024;
  int maxlen = 0, pos, len, found;
  char *key;
  HashPosition hpos;smart_str result = {0};
  HashTable tmp_hash;zend_hash_init(&tmp_hash, zend_hash_num_elements(hash), NULL, NULL, 0);
  zend_hash_internal_pointer_reset_ex(hash, &hpos);
  while (zend_hash_get_current_data_ex(hash, (void **)&entry, &hpos) == SUCCESS) {
  switch (zend_hash_get_current_key_ex(hash, &string_key, &string_key_len, &num_key, 0, &hpos)) {
  case HASH_KEY_IS_STRING:len = string_key_len-1;
  if (len < 1) {
  zend_hash_destroy(&tmp_hash);
  RETURN_FALSE;
  }
  zend_hash_add(&tmp_hash, string_key, string_key_len, entry, sizeof(zval*), NULL);
  if (len > maxlen) {maxlen = len;}
  if (len < minlen) {minlen = len;}break; 
  case HASH_KEY_IS_LONG:Z_TYPE(ctmp) = IS_LONG;Z_LVAL(ctmp) = num_key;
  convert_to_string(&ctmp);len = Z_STRLEN(ctmp);
  zend_hash_add(&tmp_hash, Z_STRVAL(ctmp), len+1, entry, sizeof(zval*), NULL);
  zval_dtor(&ctmp); 
 if (len > maxlen) {
 maxlen = len;}
 if (len < minlen) {
 minlen = len;}break;}
 zend_hash_move_forward_ex(hash, &hpos);} 
 key = emalloc(maxlen+1);pos = 0; 
 while (pos < slen) {
 if ((pos + maxlen) > slen) {maxlen = slen - pos;} 
 
found = 0;memcpy(key, str+pos, maxlen); 
 for (len = maxlen; len >= minlen; len--) {
 key[len] = 0;
 if (zend_hash_find(&tmp_hash, key, len+1, (void**)&trans) == SUCCESS) {
 char *tval;
 int tlen;zval tmp; 
 if (Z_TYPE_PP(trans) != IS_STRING) {
 tmp = **trans;zval_copy_ctor(&tmp);convert_to_string(&tmp);
 tval = Z_STRVAL(tmp);tlen = Z_STRLEN(tmp);
 } else {tval = Z_STRVAL_PP(trans);
 tlen = Z_STRLEN_PP(trans);} 
 
smart_str_appendl(&result, tval, tlen);pos += len;found = 1; 
 if (Z_TYPE_PP(trans) != IS_STRING) {zval_dtor(&tmp);}break;} } 
 if (! found) {smart_str_appendc(&result, str[pos++]);}} 
 
efree(key);zend_hash_destroy(&tmp_hash);smart_str_0(&result);
RETVAL_STRINGL(result.c, result.len, 0);}
ログイン後にコピー

以上が、皆さんの学習に役立つことを願っています。 PHPの中国語サイトです!


関連する推奨事項:

PHP ソース コードの HashTable の分析について

PHP ソース コードの Zend HashTable の分析について

以上がPHP の strtr 関数の奇妙な動作の説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!