PHP strtr 根本不起作用
Posted
技术标签:
【中文标题】PHP strtr 根本不起作用【英文标题】:PHP strtr does not work at all 【发布时间】:2012-03-14 23:11:46 【问题描述】:即使我输入
echo strtr("-äåö-", "äåö", "xxx");
它无法正常工作,它会输出此>xxx¥x¶<
,但是当我使用下面的示例时,它根本不会翻译任何内容,它会保留原始的曼波珍宝。
如果我输入表单 ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑŐŰÜÒÓÔÕÖØÝߟàáâãäåçèéêëìíîïñòóôõőöøšűùúûüýÿž
并单击翻译,它会输出相同的字符串,而 æ œ
根本不会翻译。
<form method="POST">
<input style="width:500px;" type="text" name="first_name" />
<input style="width:500px;" type="text" name="last_name" />
<input type="submit" name="submit" value="translate" />
</form>
<?php
$dict = array(
"Æ" => "AE",
"æ" => "ae",
"Œ" => "OE",
"œ" => "oe"
);
$first = strtr($_POST['first_name'], $dict);
$last = strtr($_POST['last_name'], $dict);
$first = strtr($first,
"ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑŐŰÜÒÓÔÕÖØÝߟàáâãäåçèéêëìíîïñòóôõőöøšűùúûüýÿž",
"AAAAAACEEEEIIIINOUUOOOOOOYSYaaaaaaceeeeiiiinooooooosuuuuuyyz");
$last = strtr($last,
"ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑŐŰÜÒÓÔÕÖØÝߟàáâãäåçèéêëìíîïñòóôõőöøšűùúûüýÿž",
"AAAAAACEEEEIIIINOUUOOOOOOYSYaaaaaaceeeeiiiinooooooosuuuuuyyz");
echo $first." --- ";
echo $last;
?>
即使我在代码之上添加
foreach ($_POST as $key => $value)
$POST[$key] = iconv(mb_detect_encoding($_POST["first_name"]), "ASCII//TRANSLIT", $POST[$value]);
并粘贴AAAAAACEEEEIIIINOUUOOOOOOYSYaaaaaaceeeeiiiinooooooosuuuuuyyz
,结果是这样的yAyAyAyEyEyIyIyNyUyOyOyOyYyYyayauaueyeyiyiynyoyoyoysyuuuyyyzy�y�y�y�y�y�y�y�y�y�y�y�y�y�y�y�y�y�uay�yuuzu�y�y�y�y�y�y�u�
没关系,因为没有人知道它为什么不起作用,我只是非常成功地使用了str_replace
和str_ireplace
,无需担心编码问题。
编辑:我的错误编码对 str_replace 也很重要。我在html页面上使用过
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
【问题讨论】:
你介意我问你为什么觉得有必要用 ASCII 替换有效的 UTF-8 字符吗? 我不太关心字符编码。所以如果我得到 äåö 它不会是 UTF-8 它会是什么编码? 【参考方案1】:strtr
带函数原型
string strtr ( string $str , string $from , string $to )
仅适用于单字节编码(例如 ISO-8859-1)。
header("Content-Type: text/plain; charset=ISO-8859-1");
$str = "\x2d\xe4\xe5\xf6\x2d"; // ISO-8859-1: -äåö-
$from = "\xe4\xe5\xf6"; // ISO-8859-1: äåö
$to = "\x78\x78\x78"; // ISO-8859-1: xxx
dump($str, "ISO-8859-1"); // length in octets: 5
dump($from, "ISO-8859-1"); // length in octets: 3
dump($to, "ISO-8859-1"); // length in octets: 3
print strtr($str, $from, $to); // -xxx-
输出:
-: 2d
ä: e4
å: e5
ö: f6
-: 2d
length (encoding: ISO-8859-1): 5
length in octets (8-bit-byte): 5
ä: e4
å: e5
ö: f6
length (encoding: ISO-8859-1): 3
length in octets (8-bit-byte): 3
x: 78
x: 78
x: 78
length (encoding: ISO-8859-1): 3
length in octets (8-bit-byte): 3
-xxx-
如果您使用多字节字符,例如从 UTF-8 你可能会得到一个混乱的字符串:
header("Content-Type: text/plain; charset=UTF-8");
$str = "\x2d\xc3\xa4\xc3\xa5\xc3\xb6\x2d"; // UTF-8: -äåö-
$from = "\xc3\xa4\xc3\xa5\xc3\xb6"; // UTF-8: äåö
$to = "\x78\x78\x78"; // UTF-8: xxx
dump($str, "UTF-8"); // length in octets: 8
dump($from, "UTF-8"); // length in octets: 6
dump($to, "UTF-8"); // length in octets: 3
// > If from and to have different lengths, the extra characters in the longer
// > of the two are ignored. The length of str will be the same as the return
// > value's.
// http://de.php.net/manual/en/function.strtr.php
// This means that the $from-string gets cropped to "\xc3\xa4\xc3" (16 bit of
// the first char [ä] and the first 8 bit of the second char [å]):
strtr($str, $from, $to) === strtr($str, "\xc3\xa4\xc3", $to); // true
print strtr($str, $from, $to); // -xxx�x�-
输出:
-: 2d
ä: c3a4
å: c3a5
ö: c3b6
-: 2d
length (encoding: UTF-8): 5
length in octets (8-bit-byte): 8
ä: c3a4
å: c3a5
ö: c3b6
length (encoding: UTF-8): 3
length in octets (8-bit-byte): 6
x: 78
x: 78
x: 78
length (encoding: UTF-8): 3
length in octets (8-bit-byte): 3
-xxx�x�-
对于像 UTF-8 这样的多字节编码,您必须使用第二个函数原型:
string strtr ( string $str , array $replace_pairs )
header("Content-Type: text/plain");
$str = "-äåö-"; // UTF-8 \x2d\xc3\xa4\xc3\xa5\xc3\xb6\x2d
$replace_pairs = array(
"ä" /* UTF-8 \xc3\xa4 */ => "x",
"å" /* UTF-8 \xc3\xa5 */ => "x",
"ö" /* UTF-8 \xc3\xb6 */ => "x"
);
print strtr($str, $replace_pairs); // -xxx-
如果编码不匹配,您必须使用iconv 进行转换:
header("Content-Type: text/plain");
$str = "\x2d\xe4\xe5\xf6\x2d"; // ISO-8859-1 -äåö-
$str = iconv("ISO-8859-1", "UTF-8", $str);
$replace_pairs = array(
"ä" /* UTF-8 \xc3\xa4 */ => "x",
"å" /* UTF-8 \xc3\xa5 */ => "x",
"ö" /* UTF-8 \xc3\xb6 */ => "x"
);
print strtr($str, $replace_pairs); // -xxx-
函数转储:
// outputs the hexvalue for each char for the given encoding
function dump($data, $encoding)
for($i = 0, $len = iconv_strlen($data, $encoding); $i < $len; ++$i)
$char = iconv_substr($data, $i, 1, $encoding);
printf("%s: %s\n", $char, bin2hex($char));
printf("length (encoding: %s): %d\n", $encoding, $len);
printf("length in octets (8-bit-byte): %d\n\n", strlen($data));
【讨论】:
strtr
的第二个函数原型是str_replace()
的别名?【参考方案2】:
你试过 mb_strstr:http://php.net/manual/en/function.mb-strstr.php
此函数支持多字节字符编码。
【讨论】:
他说的是strtr()
,而不是strstr()
。
我的目标是使用“strtr”,我不知道什么是单字节或多字节字符编码如何更改?【参考方案3】:
听起来您可能有相互竞争的编码。如果您的浏览器正在提交 UTF8,但您的文件保存在(例如)8859-1 中,则您的字符将不匹配并且翻译将失败。此外,查看the doc page,一些cmets 建议首先在您的输入字符串上使用utf8_decode()
。 utf8_decode()
本身可能会做你想做的事。
UTF8 是多字节编码(实际上是可变字节编码)。诸如÷
或ï
之类的字符具有超过256 的Unicode 代码点,需要将其编码为两个或多个字节,均高于128,以标识该字符。我怀疑你将不得不了解更多关于 Unicode 的知识。 utf8_encode
还有另一种解释。
编辑:自从我与编码搏斗已经有一段时间了。您应该查看iconv()
以获得更通用的重新编码。
【讨论】:
以上是关于PHP strtr 根本不起作用的主要内容,如果未能解决你的问题,请参考以下文章
PHP HybridAuth 社交登录根本不起作用。重定向到 ?hauth.start=Facebook&hauth.time