我是新来的,所以如果我做错了什么,我道歉。
我有一个表单,可以将用户输入提交到另一个页面。用户应键入ä、ö、é等。我已在文档中放置了以下所有内容:
<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字符。到目前为止我没有任何问题。尝试执行以下步骤并检查结果:
- 从HTML表单代码中删除
header('Content-Type:text/html; charset=UTF-8');
- 使用您的表单就像不使用
accept-charset="UTF-8"
的<form action="whatever.php">
一样。(最好在表单标记中插入发送数据的方法) - 在目标页面(whatever.php)中,在
<head>
标记中再次插入<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
我总是像这里提到的那样做我的项目,我对Unicode字符串没有任何问题。
这是由于PHP文件的字符编码。
硬编码的München
与源文件的字符编码一起存储,在本例中为ANSI
,当将该值与$_POST
变量中提供的UTF-8编码值进行比较时,两者自然会有所不同。
你的问题的解决方案是:
- 使用与源文件相同的编码来提供和处理内容,在这种情况下可能是
windows-1252
。- 对于初学者来说,这将包括每当提供HTML数据时将
content="text/html; charset=UTF-8"
更改为content="text/html; charset=windows-1252"
- 对于初学者来说,这将包括每当提供HTML数据时将
- 避免所有可能受
UTF-8
和windows-1252
之间的字符编码问题影响的硬编码值,或多或少只有仅包含英文字母和数字的硬编码的值。- 任何
UTF-8
值都必须从确保它们是UTF-8
编码的源读取(例如,将UTF-8
设置为存储编码和连接编码的数据库)
- 任何
- 将所有硬编码赋值包装在
utf8_encode()
中,例如$value = utf8_encode ('München');
- 将源文件的编码更改为
UTF-8
。- 这可以通过多种方式实现,一个像样的文本编辑器将能够做到这一点,或者可以使用出色的libiconv,尤其是用于批处理
解决方案1或4将是我的首选解决方案,尤其是在多人参与项目的情况下。
附带说明一下,一些文本编辑器(尤其是Notepad++
)可以选择使用UTF-8
或UTF-8 without BOM
。BOM
(字节顺序标记)在UTF-8
中毫无意义,并且在用PHP编写头文件时(通常在执行重定向时)会引起问题。这是因为BOM
正好在初始<?php
的前面,导致服务器发送BOM
,就像前面有任何其他字符一样。不同的是,您会注意到前面有一个字符,但不会显示BOM
经验法则:始终使用UTF-8而不使用BOM