【问题标题】:PHP 5.3, Suhosin and UTF-8PHP 5.3、Suhosin 和 UTF-8
【发布时间】:2011-10-11 01:27:24
【问题描述】:

我正在努力寻找一种解决方案来继续使用 Suhosin 补丁并使其适用于 UTF-8 表单提交。这是我做的非常简单的测试:

<?php var_dump($_POST); ?>
<form method="post">
    <input name="test" type="text"/>
    <input type="submit" />
</form>

使用字符串 iñtërnâtiônàlizætiøn。 显然,我首先在服务器上启用了 utf-8 标头,并将 Php default_charset 设置为 utf-8,并启用了 mb* 覆盖。 一旦我禁用 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。问题是:这是一个错误还是预期的行为?是否有 Suhosin 补丁的配置参数对多字节字符串有什么神奇作用?

目前我看到的唯一选择是禁用补丁,除非聪明人给出正确的建议。

更新 2

GET 字符串不会损坏,并且可以正确显示在浏览器中。目前只做 POST。

【问题讨论】:

  • 你应该得到某种形式的错误。还要检查您的错误日志。我也强烈建议不要使用 mb_ 函数覆盖。他们会搞砸很多现有的代码。最好在需要时始终显式使用 mb_ 函数。
  • 我看不到任何错误:字符串只是被错误解码
  • 如何解码不正确?你甚至没有在你的问题中提到这一点。添加实际问题的详细信息,而不是“它不起作用”
  • 嘿 Evert,非常感谢您的帮助,无需苛刻。我指定的示例代码非常简单:如果我禁用 suhosin 补丁,我会在浏览器中看到正确显示的字符串,否则我会看到问号:it.rn.ti.n.liz.ti.n
  • @zekus 只是想用 print_r() 代替 var_dump();

标签: php utf-8 suhosin


【解决方案1】:

通过 Google 搜索,我找到了提到的 http://algorytmy.pl/doc/php/ref.mbstring.php

从 PHP 4.3.3 开始,如果 HTML 表单的 enctype 设置为 multipart/form-data 并且 mbstring.encoding_translationphp.ini 中设置为 On,则 POST 变量和上传文件的名称将也可以转换为内部字符编码。但是,转换不会应用于查询键。

这对我来说意义不大,但确实提到了 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??

我注意到的另一个奇怪之处是,如果我将这些 mbstring 值直接设置在 php.ini(而不是 Apache 虚拟主机)中,我无法用 encoding_translation 重现该问题,所以这似乎只是一个问题什么时候使用php_admin_value

【讨论】:

  • 这个解决方案,部分解决了问题:我仍然在调查字符串仍然被 mbstring 和 suhosin 组合损坏的情况。
【解决方案2】:

你试过了吗?

<form accept-charset="UTF-8" method="post">

->http://www.razorvine.net/test/utf8form/utf8pageform.html

【讨论】:

  • 感谢 MasterCassim,但这也不起作用……仍然看到解码错误的字符串。
【解决方案3】:

您是否在 HTML 页面上的元标记中尝试了以下

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" ></meta>

【讨论】:

  • 您好 Roshan,服务器标头始终覆盖 html 元数据,因此无需指定它。无论如何,我也对此进行了测试,但问题仍然存在。
猜你喜欢
  • 2012-06-01
  • 2014-03-10
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 2010-12-16
  • 2012-06-22
  • 2011-07-19
相关资源
最近更新 更多