什么时候使用PHP strtolower()函数安全?

P_E*_*que 5 php c encoding locale ctype

PHP strtolower()函数应该将字符串转换为小写.但是,它在PHP手册中说明(强调添加):

返回字符串,其中所有字母字符都转换为小写.

请注意,' alphabetic'由当前区域设置决定.这意味着在默认的"C"语言环境中,不会转换诸如umlaut-A(Ä)之类的字符.

手册中没有提及编码,但是众所周知,它strtolower()会破坏你应该使用的UTF-8字符串mb_strtolower().

我正在寻找在案件解决方案,其中mbstring扩展不可用,想知道什么时候是安全的使用strtolower().

感谢人们评论这个问题给我的指示,似乎PHP源代码的相关部分是对库中tolower()函数的调用ctype.h.该库文件说,(强调):

如果tolower()的参数表示大写字母,并且存在相应的小写字母(由程序区域设置类别LC_CTYPE中的字符类型信息定义),则结果应为相应的小写字母.

根据我的测试,在PHP中,set_locale( LC_CTYPE, 'C' );诸如Ä(在ISO-8859-1中编码)之类的字符保持不变.但在某些其他语言环境中,该函数返回小写字母ä(同样,在ISO-8859-1中).无论如何,将语言环境更改为使用UTF-8字符集的语言环境不会使PHP strtolower()在UTF-8字符上运行Ä.

考虑到I18N相关问题和多语言环境的数量不断增加,这些信息至关重要.许多应用程序依赖于strtolower()简单的不区分大小写的检查.考虑:

$_POST['username'] = 'Michèlle';
if ( strtolower( $_POST['username'] ) == $database['username'] ) ...
Run Code Online (Sandbox Code Playgroud)

现在,根据编码,语言环境和其他一些变量,上面的代码可以在某些环境中使用,但在其他环境中则不行.

问题是:鉴于PHP strtolower()函数使用ctype.h库的tolower函数,这取决于"程序区域设置类别",何时可以安全地依赖此函数?在下列情况下可以依靠行为吗?

  1. 字符串是ASCII
  2. 该字符串以ISO-8859-1编码
  3. 字符串使用相应的语言环境集以其他编码进行编码.

(编辑:问题在2013年11月26日完全改写.)

hak*_*kre 0

PHP函数strtolower()确实使用了tolower()C 函数,该函数对传递的字符串参数的每个字节(八位字节)进行操作。

\n

这就是为什么setlocale(LC_CTYPE, 'C' );,因为它不会更改 > 127 的字节。也就是说,它只会更改 US-ASCII 字符 AZ 的大小写。

\n

C”区域设置是默认设置的,您不需要使用以下命令显式设置它setlocale(),除非应用程序的其他部分已将其设置为不同的值。

\n

这也解释了为什么设置LC_CTYPE为“ ”之类的 UTF8 区域设置de_DE.UTF-8不会将“ ”转换\xc3\x84为“ \xc3\xa4”:该字母使用两个字节 0xC3 0x84 进行编码,其中两个字节都作为单个字符(八位字节)传递给tolower() C 函数 - 因此它们是未更改,因为在单个字节上,UTF-8 的较低处理只能处理 < 128 的字符,这又实际上仅是 AZ。这实际上类似于 C 语言环境。

\n

因此设置LC_CTYPE为“ C”可防止破坏使用中的 UTF-8 字符串strtolower()

\n