>  기사  >  백엔드 개발  >  PHP에서 strtr 함수의 이상한 동작에 대한 설명

PHP에서 strtr 함수의 이상한 동작에 대한 설명

不言
不言원래의
2018-06-28 16:19:201495검색

이 글은 주로 PHP의 strtr 함수에 대한 몇 가지 이상한 동작에 대한 설명을 소개합니다. 이제 특정 참조 값이 있어 도움이 필요한 친구들에게 참고할 수 있습니다.

PHP의 strtr 함수의 이상한 동작에 대한 설명

며칠 전 한 친구가 strtr 함수에 이상한 동작이 있다는 기사를 보냈습니다.

PHP 소스 코드를 보고 다음 설명을 확인하세요.

[이상한 동작 1]
먼저 이 PHP 문자열 대체 함수의 두 가지 상태를 살펴보겠습니다. strtr()
strtr(string ,from, to)
또는 strtr(string,array)
우선 strtr 함수의 첫 번째 방법에 집중하세요
다음 예를 살펴보겠습니다.

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

결과는# 🎜🎜#I Love yOu

이 결과는 다음과 같습니다

1.strtr 대소문자를 구분합니다

【소스코드 분석 1】#🎜 🎜#strtr 함수의 최종 구현 함수는 string.c 파일의 2670행에 있는 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;}

전체 물론 이 256자 중 대문자와 소문자를 포함하여

【이상한 행동 2】

2에 대한 해시 대체입니다. .뒤에 있는 yOu를 주목하세요. 이것은 분명히 원래 의도가 아닙니다

원칙은 다음과 같습니다. 위와 동일하며 각 문자를 상응하게 대체하며 단위는 문자이므로 대체는 문자열이 아닌 문자입니다

【이상한 행동 3】

특별한 예 이 PHP sttr 함수의 이상한 점을 설명합니다

   echo strtr("I Love you","Love","");

Results 그것은

I Love you

이며 아무것도 변하지 않을 것이므로 strtr이 지불해야 할 금액은 무엇입니까? 주의할 점은 빈 값으로 대체할 수 없다는 것입니다. 즉, 마지막 매개변수는 빈 문자열이 될 수 없습니다. 물론 공백도 허용됩니다.

【소스 코드 분석 3】

string.c 파일의 2833번째 줄에서 호출 프로그램이 다음과 같은 것을 볼 수 있습니다.

   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))는 from과 to의 두 문자열 길이 중 가장 작은 것입니다. 3에 표시된 경우 결과는 0입니다. php_strtr 함수에서 #🎜🎜을 볼 수 있습니다. #
if ((trlen < 1) || (len < 1)) {return str;}

길이가 1보다 작으면 원래 문자열을 반환합니다. 그래서. . . .

【이상한 행동 4】

strtr 함수의 또 다른 예

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

결과는

너를 사랑해# 🎜🎜#

세 번째 매개변수의 A가 결과에 나타나지 않는다는 점에 유의하세요

[소스코드 분석 3]

이유는 두 번째 매개변수인 MIN(Z_STRLEN_PP(from) 과 유사합니다. Z_STRLEN_PP(to))는 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 중국어 웹사이트를 팔로우하세요!

관련 권장 사항:



PHP 소스 코드의 HashTable 분석 정보

PHP 정보 Zend HashTable의 소스 코드 분석

위 내용은 PHP에서 strtr 함수의 이상한 동작에 대한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.