我正在努力寻找一个解决方案来继续使用Suhosin补丁,并使其与UTF-8表单提交工作。这是我做的一个非常简单的测试:
<?php var_dump($_POST); ?>
<form method="post">
<input name="test" type="text"/>
<input type="submit" />
</form>
使用字符串internationalizætiøn 。显然,我首先在服务器上启用了utf-8报头,并将Php default_charset设置为utf-8,同时启用了mb* override。只要我禁用Suhosin补丁并重新提交表单,一切都可以正常工作。
我做了更多的测试只是为了确定:
$test = $_POST['test'];
var_dump(mb_detect_encoding($test, "UTF-8", true));
// Returns true if $string is valid UTF-8 and false otherwise.
function is_utf8($string) {
// From http://w3.org/International/questions/qa-forms-utf-8.html
return preg_match('%^(?:
['x09'x0A'x0D'x20-'x7E] # ASCII
| ['xC2-'xDF]['x80-'xBF] # non-overlong 2-byte
| 'xE0['xA0-'xBF]['x80-'xBF] # excluding overlongs
| ['xE1-'xEC'xEE'xEF]['x80-'xBF]{2} # straight 3-byte
| 'xED['x80-'x9F]['x80-'xBF] # excluding surrogates
| 'xF0['x90-'xBF]['x80-'xBF]{2} # planes 1-3
| ['xF1-'xF3]['x80-'xBF]{3} # planes 4-15
| 'xF4['x80-'x8F]['x80-'xBF]{2} # plane 16
)*$%xs', $string);
} // function is_utf8
var_dump(is_utf8($test));
和两个测试都在启用Suhosin补丁时返回false,否则返回true。问题是:这是一个bug还是预期的行为?Suhosin补丁是否有一个配置参数,可以对多字节字符串做一些神奇的事情?
在这一点上,我看到的唯一的选择是禁用补丁,除非一个聪明的头脑给出正确的建议。
更新2
GET字符串不会被损坏,并在浏览器中正确显示。目前只做POST。
从谷歌搜索,我发现http://algorytmy.pl/doc/php/ref.mbstring.php提到
从PHP 4.3.3开始,如果HTML表单的enctype设置为multipart/form-data并且
mbstring.encoding_translation
在php.ini
中设置为On,则POST'ed变量和上传文件的名称也将被转换为内部字符编码。但是,该转换不应用于查询键。
这对我来说意义不大,但它确实提到了POST变量,这似乎是问题的关键。
我发现,如果我在我的Apache虚拟主机设置这个,我可以重现你的问题:
php_admin_value mbstring.language "Neutral"
php_admin_value mbstring.encoding_translation "On"
php_admin_value mbstring.http_input "UTF-8"
php_admin_value mbstring.http_output "UTF-8"
php_admin_value mbstring.detect_order "auto"
php_admin_value mbstring.substitute_character "none"
php_admin_value mbstring.internal_encoding "UTF-8"
php_admin_value mbstring.func_overload "7"
php_admin_value default_charset "UTF-8"
作为参考,这是我用来重现问题的php测试页面:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<pre><?php echo $_POST['test'];?></pre>
<form method="post">
<input name="test" type="text"/>
<input type="submit" />
</form>
Test string to use: iñtërnâtiônàlizætiøn
</body>
</html>
我试着注释掉下面的mbstring设置(或关闭它):
; Disable HTTP Input conversion (PHP 4.3.0 or higher)
mbstring.encoding_translation = Off
这似乎解决了这个问题,即使它对我来说没有多大意义,因为内部字符编码是 utf-8?
我注意到的另一个奇怪的是,如果我直接在php.ini
中设置这些mbstring
值(而不是Apache虚拟主机),我无法再现encoding_translation
的问题,所以只有在使用php_admin_value
时似乎才会出现问题?
你试过了吗?
<form accept-charset="UTF-8" method="post">
-> http://www.razorvine.net/test/utf8form/utf8pageform.html
您是否尝试在以下HTML页面中添加您的meta标签
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" ></meta>