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
函数,这取决于“程序区域设置类别”,何时可以安全地依赖此函数?在下列情况下可以指望这种行为吗?
(编辑:问题于2013年11月26日完全重写。)
答案 0 :(得分:0)
它使用http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.2.html中的c函数tolower
(参考:ctype.h library)。
您可以在此处查看来源的相关部分:
strtolower
:http://lxr.php.net/xref/PHP_TRUNK/ext/standard/string.c#1393 tolower
- http://lxr.php.net/xref/PHP_TRUNK/ext/standard/string.c#1376 php_strtolower
的地方
答案 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字符串。