この記事では、主に 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");
この結果は私たちに思い出させます
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;}
echo strtr("I Love you","Love","");
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)));
if ((trlen < 1) || (len < 1)) {return str;}
echo strtr("I Loves you","Love","lOvEA");
[ソース コード分析 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 ソース コードの HashTable の分析について
PHP ソース コードの Zend HashTable の分析について
以上がPHP の strtr 関数の奇妙な動作の説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。