我的部落格執行以下**:
$tag = "網際網路產品、";
$text = rtrim($tag, "、");
print_r($text);
我們可能以為會得到的結果是網際網路產品
,實際結果是網際網路產�
。為什麼會這樣呢?
php 裡使用mb_
字首的都是多位元組函式
比如
$str = "abcd";
print_r(strlen($str)."\n"); // 4
print_r(mb_strlen($str)."\n"); // 4
$str = "周夢康";
print_r(strlen($str)."\n"); // 9
print_r(mb_strlen($str)."\n"); // 3
mb_
系列函式是以「多個位元組組成的乙個字元」為顆粒度來操作的,不帶mb_
則是按實際的位元組數來操作的。
trim
函式文件
string trim ( string $str [, string $character_mask = " \t\n\r\0\x0b" ] )
該函式不是多位元組函式,也就是說,漢字這樣的多位元組字元,會拿其頭或尾的單位元組來和後面的$character_mask
對應的char陣列進行匹配,如果在後面的陣列中,則刪掉,繼續匹配。比如:
echo ltrim("bcdf","abc"); // df
如下面的 demo 中的函式string_print_char
所示:
、
由0xe3 0x80 0x81
三位元組組成,
品
由0xe5 0x93 0x81
三位元組組成。
所以在執行rtrim
的時候,通過位元組比對,會將0x81
去掉,導致了最後出現了亂碼。
檢視 php7 的原始碼,然後提煉出下面的小 demo ,方便大家一起學習,其實php原始碼的學習並不難,每天進步一點點。
//
// main.c
// trim
//// created by 周夢康 on 2017/10/18.
//#include #include #include 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 *ar**)
char *ltrim(char *str,char *character_mask)
else
}len -= trimmed;
str += trimmed;
res = (char *) malloc(sizeof(char) * (len+1));
memcpy(res,str,len);
return res;
}char *rtrim(char *str,char *character_mask)
else
} while (i-- != 0);
}res = (char *) malloc(sizeof(char) * (len+1));
memcpy(res,str,len);
return res;
}void string_print_char(char *str)
printf("\n");
}void php_charmask(unsigned char *input, size_t len, char *mask)
}
如果覺得 demo 還不夠清晰的,複製下來,自己執行一次吧~
c 語言基礎較差的同學也不用擔心,我準備後面專門寫乙個php小白學習 c 語言的系列入門短文哈。
那麼我們就依葫蘆畫瓢,用 php 本身的多位元組函式來實現下吧:
function mb_rtrim($string, $trim, $encoding)
$len = mb_strlen($string, $encoding);
if ($len > 0) else
} 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));
當然你也可以使用正則來做。通過上面的函式學習,單位元組函式和多位元組函式,你學會了嗎?
php_function(trim)
php_function(rtrim)
php_function(ltrim)
static void php_do_trim(internal_function_parameters, int mode)
phpapi zend_string *php_trim(zend_string *str, char *what, size_t what_len, int mode)
else
}len -= trimmed;
c += trimmed;
}if (mode & 2) else
} while (i-- != 0);}}
} else else
}len -= trimmed;
c += trimmed;
}if (mode & 2) else
} while (i-- != 0);}}
}} else else
}len -= trimmed;
c += trimmed;
}if (mode & 2) else
} while (i-- != 0);}}
}if (zstr_len(str) == len) else
}
/* else if ((input+1 < end) && input[0] == '.' && input[1] == '.')
if (input+2 >= end)
if (input[-1] > input[2])
/* fixme: better error (a..b..c is the only left possibility?) */
php_error_docref(null, e_warning, "invalid '..'-range");
result = failure;
continue;
} else
}return result;
}/* }}} */
PHP 原始碼探秘 為什麼 trim 會導致亂碼
我的部落格 執行以下 tag 網際網路產品 text rtrim tag,print r text 我們可能以為會得到的結果是網際網路產品,實際結果是網際網路產 為什麼會這樣呢?php 裡使用mb 字首的都是多位元組函式 比如 str abcd print r strlen str n 4 prin...
Mybatis原始碼分析 trim標籤
在第乙個trim標籤中,存在prefix屬性,那麼語句拼湊為 where id 檢查suffix和suffixoverrides,suffixoverrides值為空,那麼不做任何處理,此時會繼續拼接suffix的值,所以sql語句變成where id and 在第二個trim標籤中,存在 pref...
php原始碼是什麼
php原始碼是什麼?php原始碼指的就是php源 源 是用特定程式語言編寫的人類可讀文字,源 的目標是為可以轉換為機器語言的計算機設定準確的規則和規範。因此,源 是程式和 的基礎。php即 超文字預處理器 是一種通用開源指令碼語言。php是在伺服器端執行的指令碼語言,與c語言類似,是常用的 程式語言...