Home > Backend Development > PHP Tutorial > An explanation of some strange behaviors of the strtr function in PHP

An explanation of some strange behaviors of the strtr function in PHP

不言
Release: 2023-04-01 21:42:01
Original
1574 people have browsed it

This article mainly introduces the explanation of some strange behaviors of strtr function in PHP. It has certain reference value. Now I share it with you. Friends in need can refer to it.

Some strange behaviors of strtr function in PHP Explanation of behavior

A few days ago, a buddy sent me an article to read, saying that the strtr function has some strange behaviors

Looking at the source code of PHP, I got the following explanation:

[Strange Behavior 1]
Let’s first look at the two states of this php string replacement function strtr()
strtr(string,from,to)
or strtr(string,array )
First of all, for the first method of strtr function
Let’s take a look at the following example:

   echo strtr("I Love you","Lo","lO");
Copy after login

The result obtained is
I lOve yOu

This result reminds us

1.strtr It is case-sensitive

[Source Code Analysis 1]
The final implementation function of the strtr function is the php_strtr function in line 2670 of the string.c file. Its source code is as follows:

   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;}
Copy after login

The entire function performs hash replacement on 256 characters. Of course, these 256 characters include uppercase and lowercase letters.

[Strange Behavior 2]

2.strtr Replacement is very special. Please look at the yOu at the back. The O in the middle is replaced. This is obviously not our intention.

[Source Code Analysis 2]

The same principle is as above, it is for each The corresponding replacement of characters is based on characters, so the replacement is characters, not strings

[Strange Behavior Three]

Give another special example to illustrate this php sttr function The weird

   echo strtr("I Love you","Love","");
Copy after login

result is

I Love you

Nothing will change, so strtr needs to pay attention to: it cannot be replaced with empty, which is the last one The parameter cannot be an empty string, of course spaces are allowed.

[Source code analysis three]

In line 2833 of the string.c file, we can see that the calling program is as follows:

   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)));
Copy after login

MIN(Z_STRLEN_PP(from), Z_STRLEN_PP (to)) is the smallest of the lengths of the two strings from and to. In the case shown in three, the result is 0. From the php_strtr function we can see that

if ((trlen < 1) || (len < 1)) {return str;}
Copy after login

When the length is less than 1 Returns the original string. so. . . .

[Strange Behavior 4]

Another example of another case of strtr function

 echo strtr("I Loves you","Love","lOvEA");
Copy after login

The result is

I lOvEs yOu

Pay attention to the A in the third parameter. It does not appear in the result.
[Source code analysis three]
The reason is similar to the second one. MIN(Z_STRLEN_PP(from), Z_STRLEN_PP(to)) takes both from and to. The smallest length among the strings

  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);}
Copy after login

The above is the entire content of this article. I hope it will be helpful to everyone's learning. For more related content, please pay attention to the PHP Chinese website!

Related recommendations:

About the analysis of HashTable in PHP source code

About the analysis of Zend HashTable in PHP source code

The above is the detailed content of An explanation of some strange behaviors of the strtr function in PHP. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template