PHP 5.3, Suhosin and UTF-8


PHP 5.3, Suhosin and UTF-8

我正在努力寻找一个解决方案来继续使用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_translationphp.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>