이 글은 주로 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
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;}
【이상한 행동 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!