Always use UTF-8
P粉964682904
2023-08-27 16:00:18
<p>
I'm setting up a new server and want full UTF-8 support in my web application. I've tried this in the past on existing servers, but always seemed to end up having to fall back to ISO-8859-1. </p>
<p>Where exactly do I need to set the encoding/charset? I know I need to configure Apache, MySQL and PHP to do this - is there some standard checklist I can follow, or maybe troubleshoot where the mismatch occurs? </p>
<p>This applies to new Linux servers running MySQL 5, PHP, 5, and Apache 2. </p>
I would like to add one thing to chazomaticus' excellent answer一个>:
Also don't forget the META tag (like this, or its HTML4 or XHTML version):
This may seem trivial, but IE7 has given me problems before.
I'm doing everything correct; the database, database connection, and Content-Type HTTP headers are all set to UTF-8, which works fine in all other browsers, but Internet Explorer still insists on using the "Western European" encoding .
It turns out that the page is missing the META tag. Adding it solves the problem.
edit:
The W3C actually has a rather large section dedicated to I18N. They have a number of articles related to this issue - describing aspects of HTTP, (X)HTML and CSS:
They recommend using both HTTP headers and HTML meta tags (or XML declarations in the case of XHTML acting as XML).
data storage:
Specify the
utf8mb4
character set on all tables and text columns in your database. This makes MySQL physically store and retrieve values encoded natively in UTF-8. Note that MySQL will implicitly useutf8mb4
encoding if autf8mb4_*
collation is specified (without any explicit character set).In older versions of MySQL (< 5.5.3), you'll unfortunately be forced to use simply
utf8
, which only supports a subset of Unicode characters. I wish I were kidding .data access:
In your application code (e.g. PHP), in whatever DB access method you use, you'll need to set the connection charset to
utf8mb4
. This way, MySQL does no conversion from its native UTF-8 when it hands data off to your application and vice versa.Some drivers provide their own mechanism for configuring the connection character set, which both updates its own internal state and informs MySQL of the encoding to use on the connection - this is usually the preferred approach. In PHP:
If you're using the PDO abstraction layer with PHP ≥ 5.3.6, you can specify
charset
in the DSN:If you're using mysqli, you can call
set_charset()
:If you're stuck with plain mysql but happen to be running PHP ≥ 5.2.3, you can call
mysql_set_charset
.If the driver does not provide its own mechanism for setting the connection character set, you may have to issue a query to tell MySQL how your application expects data on the connection to be encoded:
SET NAMES 'utf8mb4'
.The same consideration regarding
utf8mb4
/utf8
applies as above.Output:
Content-Type: text/html; charset=utf-8
. You can achieve that either by settingdefault_charset
in php.ini (preferred), or manually usingheader()
function.json_encode()
, addJSON_UNESCAPED_UNICODE
as a second parameter.enter:
mb_check_encoding()
does the trick, but you have to use it religiously. There's really no way around this, as malicious clients can submit data in whatever encoding they want, and I haven't found a trick to get PHP to do this for you reliably.Other code notes:
Obviously, all files you will serve (PHP, HTML, JavaScript, etc.) should be encoded using valid UTF-8.
You need to make sure that every time you process a UTF-8 string, you do so safely. This is, unfortunately, the hard part. You'll probably want to make extensive use of PHP's
mbstring
extension.PHP's built-in string operations are not by default UTF-8 safe. There are some things you can safely do with normal PHP string operations (like concatenation) , but for most things you should use the equivalent
mbstring
function.To know what you're doing (read: not screw it up), you really need to understand UTF-8 and how it works at the lowest level possible. Check out any of the links in utf8.com for some great resources on everything you need to know. p>