使 PHP 脚本完全 Unicode 友好的声明

Posted

技术标签:

【中文标题】使 PHP 脚本完全 Unicode 友好的声明【英文标题】:Declaration to make PHP script completely Unicode-friendly 【发布时间】:2011-08-11 12:39:42 【问题描述】:

记住在 php 中完成所有你需要做的事情才能让它与 Unicode 一起正常工作太棘手、乏味且容易出错,所以我正在寻找让 PHP 神奇地绝对升级的技巧从 musty old ASCII byte mode现代 Unicode 字符模式 的所有可能,只需使用一个简单的声明即可。

我们的想法是现代化 PHP 脚本以使用 Unicode,而不必用一堆令人困惑的替代函数调用和特殊的正则表达式来弄乱源代码。一切都应该使用 Unicode“做正确的事”,不问任何问题。

鉴于目标是最大限度地减少 Unicode, 该声明必须至少 做这些事情(加上我忘记的任何其他有助于总体目标的事情) :

PHP 脚本源本身被认为是 UTF-8 格式(例如,字符串和正则表达式)。

所有输入和输出都会根据需要自动转换为 UTF-8,并带有标准化选项(例如,所有输入标准化为 NFD,所有输出标准化为 NFC)。

所有具有 Unicode 版本的函数都使用这些函数(例如,Collator::sort 用于 sort)。

所有字节函数(例如,strlenstrstrstrpossubstr)都像相应的字符函数(例如,mb_strlenmb_strstrmb_strpos)一样工作,和mb_substr)。

所有正则表达式和正则表达式函数都可以透明地在 Unicode 上工作(即,就像所有预产者都隐式添加了 /u 一样,\w\b\s 之类的东西都在 Unicode 上工作 the way The Unicode Standard requires them to work, 等等)。

为了额外的功劳:),我希望有一种方法可以将这个声明“升级”到完整的字形模式。这样字节或字符函数就变成了字形函数(例如,@ 987654336@、grapheme_strstrgrapheme_strposgrapheme_substr),并且正则表达式的东西适用于正确的字素(即,. - 甚至 [^abc] - 匹配一个 Unicode 字素簇,无论它有多少代码点包含等)。

【问题讨论】:

【参考方案1】:

所有字节函数(例如,strlen、strstr、strpos 和 substr)都像相应的字符函数(例如,mb_strlen、mb_strstr、mb_strpos 和 mb_substr)一样工作。

这不是个好主意。

Unicode 字符串不能透明地替换字节字符串。即使您将所有人类可读的文本正确地处理为 Unicode,字节字符串在处理不基于字符的文件和网络数据以及与显式使用字节的系统交互时仍有重要用途。

例如,吐出一个标头'Content-Length: '.strlen($imageblob),如果突然使用代码点语义,你就会崩溃。

您仍然需要同时拥有mb_strlen strlen,并且您必须知道在每种情况下哪个是正确的;没有一个开关可以让您自动做正确的事情。

这就是为什么 IMO 使用可以用字节或代码点语义处理的单个字符串数据类型的方法通常是错误的。为字节字符串(具有字节语义)和字符串(具有 Unicode 代码点语义 (*))提供单独数据类型的语言往往更加一致。

(*: 或 UTF-16 代码单元语义,如果运气不好)

【讨论】:

Perl 似乎在所有事情上都与length 相处融洽。您有时只需要将内部逻辑字符编码为 UTF-8:print "Content-Length: ", length(utf8_encode($payload))。但这种情况很少见,所以让正常的 strlen 是字节而不是字符是 Huffman 的失败:短的东西应该是常见的。【参考方案2】:

full-unicode 正是 PHP 6 的想法——一年多前取消。 p>

所以,不,没有办法得到所有这些——除非使用正确的函数,并记住字符与字节不同。

不过,第四点可能对您有所帮助的一件事是mbstring 扩展的Function Overloading Feature (引用)

mbstring 支持一个'函数 重载'功能,使您 将多字节意识添加到这样的 无需修改代码的应用程序 通过重载多字节对应物 关于标准字符串函数。 例如,mb_substr() 是 调用而不是substr() if 启用函数重载。

【讨论】:

真的吗?它被取消了? 既然现在几乎整个网络都是 Unicode,为什么会有人想要取消如此重要的事情呢? :( 如果还没有办法做到这一点(我以为已经有),那么我也会接受一个显示如何编写这样一个东西的答案。 它有(即使我不确定“取消”是否是正确的词,这是基本思想);见news.php.net/php.internals/47120;;;如何编写诸如“all in unicode”之类的代码?嗯,这就是 PHP 6 的想法——还有很多工作...... 如果有mbstring.func_overload,在我看来应该有办法让它适用于其他功能,包括grapheme_*。同样,已弃用的mb_regex_set_options 似乎正是我们所需要的——除了它不包括/upreg_*。为什么工作量这么大?问题是 PHP 的模块/扩展机制不够丰富,无法让这些扩展自然且易于编写吗?你不能在某个地方的表格中添加一些东西,尤其是在第一种情况下?谢谢你,帕斯卡。 我想你可以使用一些机制,比如 mbstring 使用的重载,来重新定义所有 PHP 函数;但我让你想象用 C 语言重新编码所有这些函数需要多少时间;-) (这是 PHP 6 开发的一部分,顺便说一句,检查所有 PHP 函数以确保他们将使用 unicode)

以上是关于使 PHP 脚本完全 Unicode 友好的声明的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 输出 Unicode 字符

在Haskell中查找Char的Unicode脚本

PHP 使页面标题对URL非常友好

友好 URL 的 .htaccess

如何通过php查询使URL友好SEO [重复]

使用PHP json_encode时输出阿拉伯语(Unicode)字符