Cet article présente principalement l'explication de certains comportements étranges de la fonction strtr en PHP. Il a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer
Quelques comportements étranges de strtr. fonction en PHP Explication du comportement
Il y a quelques jours, un copain m'a envoyé un article à lire, disant que la fonction strtr a des comportements étranges
En regardant le code source de PHP, je a obtenu l'explication suivante :
[Comportement étrange 1]
Tout d'abord, jetons un coup d'œil aux deux états de cette fonction de remplacement de chaîne php strtr()
strtr(string,from,to)
ou strtr(string,array )
Tout d'abord, pour la première méthode de la fonction strtr
Regardons l'exemple suivant :
echo strtr("I Love you","Lo","lO");
Le résultat obtenu est
Je t'aime
Ce résultat rappelle que notre
1.strtr est sensible à la casse
[Analyse du code source 1] La fonction d'implémentation finale de la fonction
strtr est la fonction php_strtr à la ligne 2670 du fichier string.c, et son code source comme suit :
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;}
La fonction entière effectue un remplacement de hachage sur 256 caractères. Bien entendu, ces 256 caractères incluent les majuscules et les minuscules. lettres
[Comportement étrange 2]
2. Le remplacement de strtr est très spécial Faites attention au yOu à l'arrière qui est remplacé. intention.
[Analyse du code source 2]
Le même principe que ci-dessus. Il remplace chaque caractère en conséquence, en unités de caractères, donc il remplace les caractères, pas les chaînes
[ Comportement étrange 3]
Donnez un autre exemple spécial pour illustrer L'étrangeté de cette fonction php sttr
echo strtr("I Love you","Love","");
se traduit par
Je t'aime
qui ne changera rien, il faut donc noter strtr : il ne peut pas être remplacé par empty , c'est-à-dire que le dernier paramètre ne peut pas être une chaîne vide, bien sûr, les espaces sont autorisés.
[Analyse du code source trois]
Dans la ligne 2833 du fichier string.c, on peut voir que le programme appelant est le suivant :
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)) est la plus petite des longueurs des deux chaînes from et to. Dans le cas illustré à la figure 3, le résultat est 0. À partir de la fonction php_strtr, nous pouvons voir
if ((trlen < 1) || (len < 1)) {return str;}
Lorsque la longueur est inférieure à 1, la chaîne d'origine est renvoyée. donc. . . .
[Strange Behaviour 4]
Un autre exemple de fonction strtr
echo strtr("I Loves you","Love","lOvEA");
Le résultat est
Je t'aime
Payer attention au troisième paramètre A, qui n'apparaît pas dans le résultat
[Analyse du code source trois]
La raison est similaire à la deuxième, MIN(Z_STRLEN_PP(from), Z_STRLEN_PP(to)) prend le from et à La plus petite des deux longueurs de chaîne
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);}
Ce qui précède est l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'apprentissage de chacun. Pour plus de contenu connexe, veuillez faire attention au chinois PHP. site web!
Recommandations associées :
À propos de l'analyse de HashTable dans le code source PHP
À propos de l'analyse de Zend HashTable dans le code source PHP
À propos de l'analyse de Zend HashTable dans le code source PHPCe qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!