$_POST将从utf-8转换为äöü;等


$_POST will convert from utf-8 to ä ö ü etc

我是新来的,所以如果我做错了什么,我道歉。

我有一个表单,可以将用户输入提交到另一个页面。用户应键入ä、ö、é等。我已在文档中放置了以下所有内容:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
header('Content-Type:text/html; charset=UTF-8');
<form action="whatever.php" accept-charset="UTF-8">

我甚至尝试过:

ini_set('default_charset', 'UTF-8');

当其他页面加载时,我需要检查用户输入的内容,比如:

if ( $_POST['field'] == $check ) {
  ...
}

但是,如果他输入类似于"München"的内容,PHP会将"Má¼nchen"与"Mü的nchen"进行比较,并且永远不会触发TRUE,即使它应该触发TRUE。由于到处都指定了UTF-8,我猜服务器正在转换为其他版本(我在另一个线程上读到的Windows-1252),因为它不支持或未配置为UTF-8。在加载到生产环境之前,我在本地服务器上使用Apache;我没有更改(也不知道如何更改)任何默认设置。我一直在使用Windows7,用Notepad++编辑,用ANSI编码我的文件。如果我bin2hex('München'),我得到"4dc3bc6e6368656e"。

如果I echo $_POST['field'];,它将正确显示"München"。

我到处寻找解释,我只发现我应该包括那些我已经有的标签/标题。

非常感谢您的帮助。

您同时面临许多不同的问题,让我们从最简单的问题开始。

问题1)你说echo $_POST['field'];会正确显示吗?你说"展示"是什么意思?它可以在两种情况下正确显示:

  • 字段为UTF-8,并且您的页面已声明为UTF-8,浏览器将其显示为UTF-8,或者
  • 该字段为Latin-1,浏览器已决定(通过自动检测启发法)您的页面为Latin--1

所以,事实上echo $_POST['field'];是正确的告诉你什么都没有。

问题2)您正在使用

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
header('Content-Type:text/html; charset=UTF-8');

这是PHP代码吗?如果是,那将是一个错误,因为在发送任何字节之前必须设置标头。如果这样做,就不会设置Content-Type头,PHP应该会生成一个警告。

问题3)您正在使用

<form action="whatever.php" accept-charset="UTF-8">

如果某些浏览器(主要是IE)可以强制数据以ASCII或ISO Latin-1格式发送,则会忽略accept-charset。因此,数据将采用UTF-8格式,并声明为ISO Latin-1或ISO Latin--1,并以ISO Latin-1发送(但第二种情况不是您的情况)。

看看https://stackoverflow.com/a/8547004/449288看看如何解决这个问题。

问题4)你在比较哪些字符串?例如,如果你有

$city = "München"
$_POST['city'] == $city

此代码的结果将取决于PHP文件的编码。如果文件以ISO Latin-1编码,并且$_POST正确地包含UTF-8数据,则==将比较不同的字节并返回false。

另一个可能有用的解决方案是在Apache中,您可以在配置文件(httpd.conf)或名为AddDefaultCharset的.htaccess中放置指令。它看起来像这样:

AddDefaultCharset utf-8

http://httpd.apache.org/docs/2.0/mod/core.html#adddefaultcharset

这将覆盖任何其他默认字符集。

我在php.ini文件中更改了"mbstring.detect_order=pass",并且我使用了

我在表单和文件中多次使用Unicode字符。到目前为止我没有任何问题。尝试执行以下步骤并检查结果:

  1. 从HTML表单代码中删除header('Content-Type:text/html; charset=UTF-8');
  2. 使用您的表单就像不使用accept-charset="UTF-8"<form action="whatever.php">一样。(最好在表单标记中插入发送数据的方法)
  3. 在目标页面(whatever.php)中,在<head>标记中再次插入<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

我总是像这里提到的那样做我的项目,我对Unicode字符串没有任何问题。

这是由于PHP文件的字符编码。

硬编码的München与源文件的字符编码一起存储,在本例中为ANSI,当将该值与$_POST变量中提供的UTF-8编码值进行比较时,两者自然会有所不同。

你的问题的解决方案是:

  1. 使用与源文件相同的编码来提供和处理内容,在这种情况下可能是windows-1252
    • 对于初学者来说,这将包括每当提供HTML数据时将content="text/html; charset=UTF-8"更改为content="text/html; charset=windows-1252"
  2. 避免所有可能受UTF-8windows-1252之间的字符编码问题影响的硬编码值,或多或少只有包含英文字母和数字的硬编码的值。
    • 任何UTF-8值都必须从确保它们是UTF-8编码的源读取(例如,将UTF-8设置为存储编码和连接编码的数据库)
  3. 将所有硬编码赋值包装在utf8_encode()中,例如$value = utf8_encode ('München');
  4. 将源文件的编码更改为UTF-8
    • 这可以通过多种方式实现,一个像样的文本编辑器将能够做到这一点,或者可以使用出色的libiconv,尤其是用于批处理

解决方案1或4将是我的首选解决方案,尤其是在多人参与项目的情况下。

附带说明一下,一些文本编辑器(尤其是Notepad++)可以选择使用UTF-8UTF-8 without BOMBOM(字节顺序标记)在UTF-8中毫无意义,并且在用PHP编写头文件时(通常在执行重定向时)会引起问题。这是因为BOM正好在初始<?php的前面,导致服务器发送BOM,就像前面有任何其他字符一样。不同的是,您会注意到前面有一个字符,但不会显示BOM
经验法则:始终使用UTF-8而不使用BOM