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

时间:2013-11-20 16:25:53

标签: php c encoding locale ctype

PHP strtolower()函数应该将字符串转换为小写。但是,它说in the PHP Manual(强调补充):

  

返回 string ,所有字母字符都转换为小写。

     

请注意,“字母”由当前区域设置决定。这意味着   在默认的“C”语言环境中,字符如umlaut-A(Ä)   不会被转换。

本手册对此处的编码保持沉默,但众所周知strtolower()会破坏UTF-8字符串,而您应该使用mb_strtolower()代替字符串。

如果mbstring扩展程序不可用,我正在寻找解决方案,并想知道何时使用strtolower()是安全的。

感谢人们评论这个问题给我的指示,似乎PHP源代码的相关部分是调用tolower()库中的ctype.h函数。 library documentation说(重点补充):

  

如果   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'] ) ...

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

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

  1. 字符串为ASCII
  2. 该字符串以ISO-8859-1
  3. 编码
  4. 该字符串使用相应的区域设置进行编码。
  5. 编辑:问题于2013年11月26日完全重写。)

2 个答案:

答案 0 :(得分:0)

它使用http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.2.html中的c函数tolower(参考:ctype.h library)。

您可以在此处查看来源的相关部分:

答案 1 :(得分:0)

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

这就是set_locale(LC_CTYPE, 'C' );不会破坏UTF-8编码字符串的原因,因为它不会改变字节> 127.也就是说,它只会改变US-ASCII字符A-Z的情况。

" C" locale是默认设置的,只有当应用程序的其他部分将其设置为不同的值时,您才需要使用setlocale()显式设置它。

这也解释了为什么将LC_CTYPE设置为UTF8语言环境,例如" de_DE.UTF-8"不会转换" Ä" to" ä":该字母用两个字节0xC3 0x84编码,其中两个字节都作为单个字符(八位字节)传递给tolower() C函数 - 因此它们不变因为在单个字节上,用于降低处理的UTF-8只能处理字符< 128又是有效的A-Z。这实际上就像C语言环境一样。

因此将LC_CTYPE设置为" C"防止使用strtolower()破坏UTF-8字符串。