Maison  >  Article  >  développement back-end  >  Une explication de certains comportements étranges de la fonction strtr en PHP

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

不言
不言original
2018-06-28 16:19:201497parcourir

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

Déclaration:
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