php常用编码UTF-8设置

简介

目前,PHP 仍未在底层实现对 Unicode 的支持。虽然有很多途径可以确保 UTF-8 字符串能够被正确地处理,但这并不是很简单的事情,通常需要对 Web 应用进行全方面的检查,从 HTML 到 SQL 再到 PHP。我们将争取进行一个简洁实用的总结。

PHP 层面的 UTF-8

最基本的字符串操作,像是连结两个字符串或将字符串赋值给变量,并不需要对 UTF-8 做特别的处理。然而大多数字符串的函数,像 strpos() 和 strlen(),确实需要特别的处理。这些函数名中通常包含 mb_*:比如,mb_strpos() 和 mb_strlen()。这些 mb_* 字符串是由 Multibyte String Extension 提供支持的,它专门为操作 Unicode 字符串而特别进行了设计。

在操作 Unicode 字符串时,请你务必使用 mb_* 函数。例如,如果你对一个 UTF-8 字符串使用 substr(),那返回的结果中有很大可能会包含一些乱码。正确的方式是使用 mb_substr()。

最难的地方在于每次都要记得使用 mb_* 函数。如果你哪怕只有一次忘记了使用,你的 Unicode 字符串就有在接下来的过程中变成乱码的风险。

不是所有的字符串函数都有一个对应的 mb_* 函数。如果你想要的功能没有对应的 mb_* 函数的话,那只能说你运气不佳了。

你应该在你所有的 PHP 脚本(或全局包含的脚本)的开头使用 mb_internal_encoding() 函数,然后紧接着在会对浏览器进行输出的脚本中使用 mb_http_output()。在每一个脚本当中明确声明字符串的编码可以免去很多日后的烦恼。

另外,许多对字符串进行操作的函数都有一个可选的参数用来指定字符串编码。当可以设定这类参数时,你应该始终明确指定使用 UTF-8。例如,htmlentities() 有一个字符编码的选项,你应该始终将其设为 UTF-8。从 PHP 5.4.0 开始, htmlentities() 和 htmlspecialchars() 的编码都已经被默认设为了 UTF-8。

数据库层面的 UTF-8

如果你使用 PHP 来操作到 MySQL,有些时候即使你做到了上面的每一点,你的字符串仍可能面临在数据库中以非 UTF-8 的格式进行存储的问题。

为了确保你的字符串从 PHP 到 MySQL都使用 UTF-8,请检查确认你的数据库和数据表都设定为 utf8mb4 字符集和整理,并且确保你的 PDO 连接请求也使用了 utf8mb4 字符集。请看下方的示例代码,这是 非常重要 的。

请注意为了完整的 UTF-8 支持,你必须使用 utf8mb4 而不是 utf8!你会在进一步阅读中找到原因。

浏览器层面的 UTF-8

使用 mb_http_output() 函数来确保 PHP 向浏览器输出 UTF-8 格式的字符串。

随后浏览器需要接收 HTTP 应答来指定页面是由 UTF-8 进行编码的。以前这一步是通过在页面 标签下包含字符集 标签实现的,这是一种可行的方式。但更好的做法是在 Content-Type 响应头中进行设置,因为这样做的速度会更快。

<?php
// Tell PHP that we're using UTF-8 strings until the end of the script
mb_internal_encoding('UTF-8');

// Tell PHP that we'll be outputting UTF-8 to the browser
mb_http_output('UTF-8');

// Our UTF-8 test string
$string = 'Êl síla erin lû e-govaned vîn.';

// Transform the string in some way with a multibyte function
// Note how we cut the string at a non-Ascii character for demonstration purposes
$string = mb_substr($string, 0, 15);

// Connect to a database to store the transformed string
// See the PDO example in this document for more information
// Note the `charset=utf8mb4` in the Data Source Name (DSN)
$link = new PDO(
    'mysql:host=your-hostname;dbname=your-db;charset=utf8mb4',
    'your-username',
    'your-password',
    array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_PERSISTENT => false
    )
);

// Store our transformed string as UTF-8 in our database
// Your DB and tables are in the utf8mb4 character set and collation, right?
$handle = $link->prepare('insert into ElvishSentences (Id, Body) values (?, ?)');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->bindValue(2, $string);
$handle->execute();

// Retrieve the string we just stored to prove it was stored correctly
$handle = $link->prepare('select * from ElvishSentences where Id = ?');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->execute();

// Store the result into an object that we'll output later in our HTML
$result = $handle->fetchAll(\PDO::FETCH_OBJ);

header('Content-Type: text/html; charset=UTF-8');
?><!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>UTF-8 test page</title>
    </head>
    <body>
        <?php
        foreach($result as $row){
            print($row->Body);  // This should correctly output our transformed UTF-8 string to the browser
        }
        ?>
    </body>
</html>
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值