Une explication de certains comportements étranges de la fonction strtr en PHP

不言
Libérer: 2023-04-01 21:42:01
original
1525 Les gens l'ont consulté

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");
Copier après la connexion

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;}
Copier après la connexion

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","");
Copier après la connexion

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)));
Copier après la connexion

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;}
Copier après la connexion
.

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");
Copier après la connexion

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);}
Copier après la connexion

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 PHP

Ce 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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!