Heim  >  Artikel  >  Backend-Entwicklung  >  So lösen Sie das Problem der PHP-Trimmung verstümmelter Zeichen

So lösen Sie das Problem der PHP-Trimmung verstümmelter Zeichen

藏色散人
藏色散人Original
2021-03-04 17:58:122594Durchsuche

php verstümmelten Code trimmen liegt daran, dass beim Ausführen von rtrim 0x81 entfernt wird, was zu verstümmeltem Code führt. Die Lösung besteht darin, die Methode „mb_rtrim($tag, ",",$encoding)“ zu verwenden, um den verstümmelten Code zu lösen.

So lösen Sie das Problem der PHP-Trimmung verstümmelter Zeichen

Die Betriebsumgebung dieses Artikels: Windows7-System, PHP7.1-Version, DELL G3-Computer

Führen Sie zuerst den folgenden Code aus:

$tag = "互联网产品、";
$text = rtrim($tag, "、");
print_r($text);

Wir denken vielleicht, dass das Ergebnis, das wir erhalten, ein Internetprodukt ist, aber Das eigentliche Ergebnis ist ein Internetprodukt. Warum passiert das?

Populärwissenschaft

Das mb_-Präfix in PHP steht für alle Multibyte-Funktionen http://php.net/manual/zh/ref....

Zum Beispiel beginnt die

$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

mb_-Reihe von Funktionen mit „ multiple „Ein aus Bytes bestehendes Zeichen“ wird mit einer Granularität verarbeitet, und ohne mb_ wird es basierend auf der tatsächlichen Anzahl von Bytes verarbeitet.

Prinzip

Trim-Funktionsdokument

string trim ( string $str [, string $character_mask = " " ] )

Diese Funktion ist keine Multibyte-Funktion, das heißt, für Multibyte-Zeichen wie chinesische Schriftzeichen wird das einzelne Byte des Kopfes oder Endes verwendet, um mit dem abzugleichen char, das dem nachfolgenden $character_mask-Array entspricht, wird abgeglichen. Wenn es sich im folgenden Array befindet, löschen Sie es und fahren Sie mit dem Abgleich fort. Zum Beispiel:

echo ltrim("bcdf","abc"); // df

Wie in der Funktion string_print_char in der Demo unten gezeigt:

besteht aus drei Bytes 0xe3 0x80 0x81 und

besteht aus drei Bytes 0xe5 0x93 0x81.

Bei der Ausführung von rtrim wird 0x81 durch den Bytevergleich entfernt, was am Ende zu verstümmelten Zeichen führt.

[Empfohlenes Lernen: „PHP-Video-Tutorial“]

Erkundung des Quellcodes

Sehen Sie sich den Quellcode von PHP7 an und extrahieren Sie dann die folgende kleine Demo, damit alle gemeinsam lernen können Quellcode ist nicht schwierig. Machen Sie jeden Tag ein wenig Fortschritte.

//
// 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;
}
}

Wenn Sie denken, dass die Demo nicht klar genug ist, kopieren Sie sie und führen Sie sie selbst aus~

Studenten mit schlechten C-Sprachkenntnissen müssen sich keine Sorgen machen, ich werde eine Reihe von Einführungsartikeln schreiben, damit PHP-Neulinge lernen können C-Sprache später.

Lösung

Dann folgen wir demselben Muster und verwenden die PHP-eigenen Multibyte-Funktionen, um es zu implementieren:

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));

Natürlich können Sie dafür auch reguläre Ausdrücke verwenden. Haben Sie durch das obige Funktionslernen Einzelbyte-Funktionen und Mehrbyte-Funktionen gelernt?

PHP7-bezogener Quellcode

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] <= &#39; &#39; &&
(c[i] == &#39; &#39; || c[i] == &#39;&#39; || c[i] == &#39;&#39; || c[i] == &#39; &#39; || c[i] == &#39;&#39; || c[i] == &#39;&#39;)) {
trimmed++;
} else {
break;
}
}
len -= trimmed;
c += trimmed;
}
if (mode & 2) {
if (len > 0) {
i = len - 1;
do {
if ((unsigned char)c[i] <= &#39; &#39; &&
(c[i] == &#39; &#39; || c[i] == &#39;&#39; || c[i] == &#39;&#39; || c[i] == &#39; &#39; || c[i] == &#39;&#39; || c[i] == &#39;&#39;)) {
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 &#39;a..z&#39;,
* 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] == &#39;.&#39; && input[2] == &#39;.&#39;
&& input[3] >= c) {
memset(mask+c, 1, input[3] - c + 1);
input+=3;
} else if ((input+1 < end) && input[0] == &#39;.&#39; && input[1] == &#39;.&#39;) {
/* Error, try to be as helpful as possible:
(a range ending/starting with &#39;.&#39; won&#39;t be captured here) */
if (end-len >= input) { /* there was no &#39;left&#39; char */
php_error_docref(NULL, E_WARNING, "Invalid &#39;..&#39;-range, no character to the left of &#39;..&#39;");
result = FAILURE;
continue;
}
if (input+2 >= end) { /* there is no &#39;right&#39; char */
php_error_docref(NULL, E_WARNING, "Invalid &#39;..&#39;-range, no character to the right of &#39;..&#39;");
result = FAILURE;
continue;
}
if (input[-1] > input[2]) { /* wrong order */
php_error_docref(NULL, E_WARNING, "Invalid &#39;..&#39;-range, &#39;..&#39;-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 &#39;..&#39;-range");
result = FAILURE;
continue;
} else {
mask[c]=1;
}
}
return result;
}
/* }}} */

Das obige ist der detaillierte Inhalt vonSo lösen Sie das Problem der PHP-Trimmung verstümmelter Zeichen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn