2013-11-20 43 views
5

的PHP strtolower()功能應該將字符串轉換爲小寫。但是,它說in the PHP Manual(強調):什麼時候可以安全使用PHP strtolower()函數?

返回與轉換爲小寫所有字母。

請注意'字母'由當前語言環境決定。這意味着 ,在即默認的「C」區域,字符,如變音符-A(A) 將不被轉換。

該手冊是沉默的編碼這裏,但已知strtolower()將損壞UTF-8字符串,在這裏你都應該使用mb_strtolower()代替。

我正在尋找一個解決方案,其中mbstring擴展不可用,並且想知道何時可以安全使用strtolower()

感謝評論此問題的人給我的指示,似乎PHP源的相關部分似乎是調用ctype.h函數庫中的tolower()函數。所述library documentation說(強調):

如果 參數的tolower的()表示一個大寫字母,且存在 一個對應的小寫字母(如由字符類型信息在 程序語言環境類別LC_CTYPE定義),結果應爲相應的 小寫字母。

根據我的測試,在PHP與set_locale(LC_CTYPE, 'C');字符,如Ä(在ISO-8859-1編碼)是保持不變。但在其他一些語言環境中,該函數返回小寫字母ä(再次,在ISO-8859-1中)。總之,改變區域設置一個使用UTF-8字符集做出的UTF-8字符Ä PHP strtolower()工作。

考慮到國際化相關的問題和語言環境的越來越多,這些信息可能是非常重要的。許多應用程序依賴strtolower()進行簡單的不區分大小寫的檢查。試想一下:

$_POST['username'] = 'Michèlle'; 
if (strtolower($_POST['username']) == $database['username']) ... 

現在,根據編碼,語言環境,也許一些其他變量,上面的代碼會在某些環境中工作,而不是在別人。

現在的問題是:鑑於PHP strtolower()函數使用ctype.h庫的tolower函數,它依賴於「程序語言環境類別」,何時可以安全地指望此函數?在下列情況下,這種行爲能夠被計算在內嗎?

  1. 該字符串是ASCII
  2. 該字符串在ISO-8859-1
  3. 編碼的字符串在一些其它編碼與相應區域集編碼。

編輯:問題26完全改寫2013年十一月)

+0

PHP是開源的,所以在源代碼中找到它。 –

+0

[這是相關部分的源代碼](http://lxr.php.net/xref/PHP_TRUNK/ext/standard/string.c#1397)。 –

+1

@AmalMurali其實,這裏的工作是在這裏完成的:http://lxr.php.net/xref/PHP_TRUNK/ext/standard/string.c#1376 –

回答

0

strtolower() PHP函數不使用在它的實現中的tolower() C函數在傳遞的字符串的每個單字節(八位字節)儀表。

這就是爲什麼set_locale(LC_CTYPE, 'C');不會破壞UTF-8編碼的字符串,因爲它不會改變字節> 127.也就是說,它只會改變US-ASCII字符A-Z的情況。

的「C」區域設置爲默認設置,你不需要用setlocale()明確設置它,只有當應用程序的其他部分已經將其設置爲不同的值。

這也解釋了爲什麼設置LC_CTYPE到UTF8區域設置,如「de_DE.UTF-8」不會轉換「Ä」到「ä」:這封信進行編碼雙字節0xc3的0x84這其中既有作爲單個字符傳遞(八位)到tolower() C函數 - 因此它們沒有改變,因爲在單個字節上,UTF-8到較低的處理只能處理字符< 128,這些字符再次實際上只有AZ。這與C語言環境非常相似。

因此,將LC_CTYPE設置爲「C」可防止使用strtolower()破壞正在使用的UTF-8字符串。

0

它使用c函數tolower(參照http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.2.html)從ctype.h library

您可以查看源這裏的相關章節:

+0

從您提供的鏈接:「如果字符匹配適當的條件,然後它被轉換。[...]如果字符是一個大寫字符(A到Z),然後它被轉換爲小寫字母(a到z) 「這顯然不是全部的事實,因爲我的系統中的strtolower()會將(ISO-8859-1編碼)'Ä'轉換爲'ä'。 –

+0

@ HeikkiU嗯,我在看源代碼,'php_strtolower'真的很簡單。如果您有C/C++測試環境,請嘗試直接使用'tolower'重現這些結果。我唯一能看到的另一件事是'strtolower'調用'zend_parse_parameters',但我沒有看到任何內容會指示值的一些變化,導致'tolower'的行爲與正常不同。 –

+0

沒有選擇進行測試。但是必須有更多的東西,否則手冊只會說「將A-Z轉換爲A-Z」,不是嗎?而且,在你提到它之前,我沒有啓用mbstring重載。 –

相關問題