php trim tronqué le code est dû au fait que lors de l'exécution de rtrim, 0x81 sera supprimé, ce qui entraînera un code tronqué. La solution consiste à utiliser la méthode "mb_rtrim($tag, ", ",$encoding)" pour résoudre le problème. code brouillé.
L'environnement d'exploitation de cet article : système Windows7, version PHP7.1, ordinateur DELL G3
Exécutez d'abord le code suivant :
$tag = "互联网产品、"; $text = rtrim($tag, "、"); print_r($text);
Nous pouvons penser que le résultat que nous obtiendrons est un produit Internet, mais le résultat réel est un produit Internet. Pourquoi cela se produit-il ?
Science populaire
Le préfixe mb_ en PHP est constitué de toutes les fonctions multi-octets http://php.net/manual/zh/ref....
Par exemple
$str = "abcd"; print_r(strlen($str).""); // 4 print_r(mb_strlen($str).""); // 4 $str = "周梦康"; print_r(strlen($str).""); // 9 print_r(mb_strlen($str).""); // 3
Les fonctions de la série mb_ fonctionnent sur la base de la granularité de "un caractère composé de plusieurs octets". Sans mb_, elles fonctionnent sur la base du nombre réel d'octets.
Principe
documentation de la fonction trim
string trim ( string $str [, string $character_mask = " " ] )
Cette fonction n'est pas une fonction multi-octets, c'est-à-dire que les caractères multi-octets comme les caractères chinois auront leur tête ou tail Utilisez un seul octet pour faire correspondre le tableau de caractères correspondant au $character_mask suivant. S'il se trouve dans le tableau suivant, supprimez-le et continuez la correspondance. Par exemple :
echo ltrim("bcdf","abc"); // df
est affiché dans la fonction string_print_char dans la démo ci-dessous :
se compose de trois octets 0xe3 0x80 0x81, et
se compose de trois octets 0xe5 0x93 0x81 composition .
Ainsi, lors de l'exécution de rtrim, 0x81 sera supprimé via une comparaison d'octets, ce qui entraînera des caractères tronqués à la fin.
[Apprentissage recommandé : "Tutoriel vidéo PHP"]
Exploration du code source
Afficher le code source de PHP7, puis j'ai extrait la petite démo suivante pour permettre à tout le monde d'apprendre ensemble. En fait, apprendre le code source PHP n'est pas difficile, et vous pouvez faire un peu de progrès chaque jour.
// // main.c // trim // // Created by 周梦康 on 2017/10/18. // Copyright © 2017年 周梦康. All rights reserved. // #include <stdio.h> #include <stdlib.h> #include <string.h> void string_print_char(char *str); void php_charmask(unsigned char *input, size_t len, char *mask); char *ltrim(char *str,char *character_mask); char *rtrim(char *str,char *character_mask); int main(int argc, char const *argv[]) { printf("%s",ltrim("bcdf","abc")); string_print_char("品"); // e5 93 81 string_print_char("、"); // e3 80 81 printf("%s",rtrim("互联网产品、","、")); return 0; } char *ltrim(char *str,char *character_mask) { char *res; char mask[256]; register size_t i; int trimmed = 0; size_t len = strlen(str); php_charmask((unsigned char*)character_mask, strlen(character_mask), mask); for (i = 0; i < len; i++) { if (mask[(unsigned char)str[i]]) { trimmed++; } else { break; } } len -= trimmed; str += trimmed; res = (char *) malloc(sizeof(char) * (len+1)); memcpy(res,str,len); return res; } char *rtrim(char *str,char *character_mask) { char *res; char mask[256]; register size_t i; size_t len = strlen(str); php_charmask((unsigned char*)character_mask, strlen(character_mask), mask); if (len > 0) { i = len - 1; do { if (mask[(unsigned char)str[i]]) { len--; } else { break; } } while (i-- != 0); } res = (char *) malloc(sizeof(char) * (len+1)); memcpy(res,str,len); return res; } void string_print_char(char *str) { unsigned long l = strlen(str); for (int i=0; i < l; i++) { printf("%02hhx ",str[i]); } printf(""); } void php_charmask(unsigned char *input, size_t len, char *mask) { unsigned char *end; unsigned char c; memset(mask, 0, 256); for (end = input+len; input < end; input++) { c = *input; mask[c]= 1; } }
Si vous pensez que la démo n'est pas assez claire, copiez-la et exécutez-la vous-même~
Les étudiants ayant de mauvaises bases en langage C n'ont pas à s'inquiéter, j'écrirai un tutoriel PHP spécial pour les débutants plus tard Une série de courts articles d'introduction au langage C.
Solution
Ensuite, suivons le même modèle et utilisons les propres fonctions multi-octets de PHP pour l'implémenter :
function mb_rtrim($string, $trim, $encoding) { $mask = []; $trimLength = mb_strlen($trim, $encoding); for ($i = 0; $i < $trimLength; $i++) { $item = mb_substr($trim, $i, 1, $encoding); $mask[] = $item; } $len = mb_strlen($string, $encoding); if ($len > 0) { $i = $len - 1; do { $item = mb_substr($string, $i, 1, $encoding); if (in_array($item, $mask)) { $len--; } else { break; } } while ($i-- != 0); } return mb_substr($string, 0, $len, $encoding); } mb_internal_encoding("UTF-8"); $tag = "互联网产品、"; $encoding = mb_internal_encoding(); print_r(mb_rtrim($tag, "、",$encoding));
Bien sûr, vous pouvez également utilisez des expressions régulières. Grâce à l'apprentissage des fonctions ci-dessus, avez-vous appris les fonctions mono-octet et les fonctions multi-octets ?
Code source lié à PHP7
PHP_FUNCTION(trim) { php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3); } PHP_FUNCTION(rtrim) { php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2); } PHP_FUNCTION(ltrim) { php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, int mode) { zend_string *str; zend_string *what = NULL; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(str) Z_PARAM_OPTIONAL Z_PARAM_STR(what) ZEND_PARSE_PARAMETERS_END(); ZVAL_STR(return_value, php_trim(str, (what ? ZSTR_VAL(what) : NULL), (what ? ZSTR_LEN(what) : 0), mode)); } PHPAPI zend_string *php_trim(zend_string *str, char *what, size_t what_len, int mode) { const char *c = ZSTR_VAL(str); size_t len = ZSTR_LEN(str); register size_t i; size_t trimmed = 0; char mask[256]; if (what) { if (what_len == 1) { char p = *what; if (mode & 1) { for (i = 0; i < len; i++) { if (c[i] == p) { trimmed++; } else { break; } } len -= trimmed; c += trimmed; } if (mode & 2) { if (len > 0) { i = len - 1; do { if (c[i] == p) { len--; } else { break; } } while (i-- != 0); } } } else { php_charmask((unsigned char*)what, what_len, mask); if (mode & 1) { for (i = 0; i < len; i++) { if (mask[(unsigned char)c[i]]) { trimmed++; } else { break; } } len -= trimmed; c += trimmed; } if (mode & 2) { if (len > 0) { i = len - 1; do { if (mask[(unsigned char)c[i]]) { len--; } else { break; } } while (i-- != 0); } } } } else { if (mode & 1) { for (i = 0; i < len; i++) { if ((unsigned char)c[i] <= ' ' && (c[i] == ' ' || c[i] == '' || c[i] == '' || c[i] == ' ' || c[i] == '' || c[i] == '')) { trimmed++; } else { break; } } len -= trimmed; c += trimmed; } if (mode & 2) { if (len > 0) { i = len - 1; do { if ((unsigned char)c[i] <= ' ' && (c[i] == ' ' || c[i] == '' || c[i] == '' || c[i] == ' ' || c[i] == '' || c[i] == '')) { len--; } else { break; } } while (i-- != 0); } } } if (ZSTR_LEN(str) == len) { return zend_string_copy(str); } else { return zend_string_init(c, len, 0); } } /* {{{ php_charmask * Fills a 256-byte bytemask with input. You can specify a range like 'a..z', * it needs to be incrementing. * Returns: FAILURE/SUCCESS whether the input was correct (i.e. no range errors) */ static inline int php_charmask(unsigned char *input, size_t len, char *mask) { unsigned char *end; unsigned char c; int result = SUCCESS; memset(mask, 0, 256); for (end = input+len; input < end; input++) { c=*input; if ((input+3 < end) && input[1] == '.' && input[2] == '.' && input[3] >= c) { memset(mask+c, 1, input[3] - c + 1); input+=3; } else if ((input+1 < end) && input[0] == '.' && input[1] == '.') { /* Error, try to be as helpful as possible: (a range ending/starting with '.' won't be captured here) */ if (end-len >= input) { /* there was no 'left' char */ php_error_docref(NULL, E_WARNING, "Invalid '..'-range, no character to the left of '..'"); result = FAILURE; continue; } if (input+2 >= end) { /* there is no 'right' char */ php_error_docref(NULL, E_WARNING, "Invalid '..'-range, no character to the right of '..'"); result = FAILURE; continue; } if (input[-1] > input[2]) { /* wrong order */ php_error_docref(NULL, E_WARNING, "Invalid '..'-range, '..'-range needs to be incrementing"); result = FAILURE; continue; } /* FIXME: better error (a..b..c is the only left possibility?) */ php_error_docref(NULL, E_WARNING, "Invalid '..'-range"); result = FAILURE; continue; } else { mask[c]=1; } } return result; } /* }}} */
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!