PHP中的字串、編碼、UTF-8
最近看了不少編碼方面的文章,所以分二篇博文說下“PHP、字符串、編碼、UTF-8”相關知識,本篇博文是上半部分,分為四大塊內容,分別是「字串的定義與使用」、「字串轉換」、「PHP 字串的本質」、「多位元組字串」。上半部比較基礎、。
字串的定義和使用
PHP 中能夠透過四種方法設定字串:
單引號字串
。字串沒有變數解析功能和特殊字元轉義功能。例如$str='hellonworld',其中的n並沒有換行功能。
雙引號字串
雙引號字串具備單引號字串沒有的變數解析功能和特殊字元轉義功能。
個人對於十六進制和八進制的字串特殊轉義很感興趣,特別補充:
\[0-7]{1,3} #八进制表达方式 \x[0-9A-Fa-f]{1,2} #十六进制表达方式
heredoc
這種表達式類似於Python 中包含多行的字串,就能夠定義字串。其語法定義很嚴格,使用起來需要注意。
$str=<<<EOD hello\n world EOD;
Nowdoc
Nowdoc類似於單引號字串,不會解析變數。比較適合定義一大段文字且無需對其中的特殊字元進行轉義。
變數解析
PHP字串最強大的部分就是變數解析,可以在運行時根據上下文解析變數(這才是解釋型語言),可以產生很多妙用。
簡單的變數解析就是在字串中可以包含“變數”,“數組”,“物件屬性”,複雜的語法規則就是使用{}符號來進行操作(組成一個表達式)。
透過一個例子看看變數解析的強大之處
class beers { const softdrink = 'softdrink'; public static $ale = 'ale'; public $data = array(1,3,"k"=>4); } $softdrink = "softdrink"; $ale = "ale"; $arr = array("arr1","arr2","arr3"=>"arr4","arr4"=>array(1,2)); $arr4 = "arr4"; $obj = new beers; echo "line1:{$arr[1]}\n"; echo "line2:{$arr['arr4'][0]}\n"; echo "line3:{$obj->data[1]}\n"; echo "line4:{${$arr['arr3']}}\n"; echo "line5:{${$arr['arr3']}[1]}\n"; echo "line6:{${beers::softdrink}}\n"; echo "line7:{${beers::$ale}}\n";
字串轉換
PHP 語言比 Python 簡單的另一個原因就是類型的隱式轉換,會簡化很多操作,這裡透過字串轉換來說明。
字串類型強制轉換
$var = 10 ; $dvar = (string)$var ; echo $dvar . "_" . gettype($dvar);
strval()函數是取得變數的字串值:
$var = 10.2 ; $dvar = strval($var) ; echo gettype($var) . "_" . $dvar . "_" . gettype($dvar);
settype()函數是設定變數的的值轉換成字串的時候會遵循一定的規則,例如一個布林值boolean 的TRUE 被轉換成string 的「1」。相關規則最好還是理解下。
自動型別轉換上面的二個轉換屬於顯示轉換,而更要關注的是自動型別轉換,在一個需要字串的表達式中,會自動轉換為型,具體見例子:
$str = "10hello"; settype($str, "integer"); echo $str ;
PHP 字串的本質
引用PHP 文件的解釋:
PHP 中的string 的實作方式是由位元組組成的陣列再加上一個整數指明緩衝區長度。並無如何將位元組轉換成字元的訊息,由程式設計師來決定。字串由什麼值構成沒有限制,包括值為 0 的位元組可以出現在字串的任何位置。PHP並不特別指明字串的編碼,那字串到底是怎麼編碼的呢,這取決於程式設計師。字串會依照 PHP 檔案的編碼來對字串進行編碼。例如你的檔案編碼是 GBK,那你程式碼內容都是 GBK的。
補充二進位安全這個概念,其值為 0 (NULL)的位元組可以處於字串任何位置,而 PHP 的部分非二進位函數底層是呼叫的 C 函數,會把 NULL 後面的字元忽略。
只要 PHP 的檔案編碼是能相容 ASCII 的,那麼字串操作就可以很好的被處理。但是字串操作本質上還是Native 的(不管檔案編碼是什麼),所以在使用的時候需要注意:
- 某些函數假定字串是以單字節編碼的,但並不需要將位元組解釋為特定的字元。如 sbustr() 函數。
- 很多函數是需要顯示的傳遞編碼參數,不然會從 PHP.INI 檔案中取得預設值,例如 htmlentities() 函數。
- 還有一些函數和本地區域有關,這些函數也只能是單字節操作的。
- 一般情況下,雖然PHP 內部不支持Unicode 字符,但是支持UTF-8 編碼,絕大部分情況下不會有什麼問題,但是下列的情況可能就處理不了了:
- 非UTF -8 編碼字串如何進行轉換
- 一個UTF-8 編碼的網頁,但是用戶在提交表單的時候,可能使用GBK 的編碼(不遵守meta tag)
- 一個UTF-8 編碼的PHP文件,使用strlen("中國")回傳的是6 而不是實際的字元數(2)
- 那麼如何解決該問題呢? PHP 提供了 mbstring 擴充功能 !
多位元組字串
mbstring 擴充預設不是開啟的,安裝的時候需要 --enable-mbstring。
我們先看看 PHP.INI 中對於 mbstring 指令的配置,花了好久才逐步明白。
mbstring.language 這個參數我就理解為UTF-8 了
mbstring.internal_encoding 這個編碼和PHP 檔案編碼沒有關係,只是在大部分mbstring 函數裡面需要指定待處理字串的編碼,如不顯示指定,預設就取得該參數的值,該參數的值在高版本PHP 中以default_charset 參數取代了。
mbstring.http_input 此參數指定 HTTP input 的預設編碼(不包含 GET 參數)。一般和 HTML 頁面的編碼保持一致,該參數的值以 default_charset 參數取代。
mbstring.http_output 該參數誤導我了,HTTP output 是什麼,PHP 輸出不就是頁面,怎麼會有這概念?
mbstring.encoding_translation,這個參數重點說下,預設是關閉的,假如打開,PHP 會對POST 變數和上傳檔案的名稱自動轉換編碼為mbstring.internal_encoding 指定的值,不過大家我沒有試驗過,大家可以上傳一個中文名的檔案。建議關閉,讓程式設計師來處理相關問題。
後面看看 mbstring 擴充的一些函數:
mb_http_input():偵測 HTTP input 字元編碼,覺得對於上傳的檔案名稱有必要處理。
mb_convert_encoding():比較常用的函數,注意第三個參數。
mb_detect_order():設定/取得字元編碼的偵測順序。
mb_list_encodings():傳回系統支援的編碼清單。
重點說明下:PHP 檔案支援的編碼有一定要,要相容於 ASCII。
但不要使用 BIG-5 作為 PHP 檔案編碼,尤其字串以 identifiers 或 literals 形式出現,假如實在 PHP 檔案編碼要是 BIG-5,那麼對於輸入輸出的內容盡量轉換為 UTF-8。
Zend Multibyte
最後說下 Zend Multibyte 這個概念,理解的不是特別深刻,首先不要和 mbstring 擴展混在一塊。 Zend Multibyte 模式預設是關閉的,可以透過 zend.multibyte 指令開啟。然後透過 declare() 函數來指定 PHP 解析器的編碼。
那這個指令出現的意義是什麼?上面說過PHP 檔案的編碼需要是相容ASCII 的,那麼類似於BIG-5 這樣的非相容ASCII 編碼怎麼辦,可以透過這個指令來操作,當PHP 解析器讀取mbstring.script_encoding 編碼並用該編碼來解析PHP 檔案。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

SOLID原則在PHP開發中的應用包括:1.單一職責原則(SRP):每個類只負責一個功能。 2.開閉原則(OCP):通過擴展而非修改實現變化。 3.里氏替換原則(LSP):子類可替換基類而不影響程序正確性。 4.接口隔離原則(ISP):使用細粒度接口避免依賴不使用的方法。 5.依賴倒置原則(DIP):高低層次模塊都依賴於抽象,通過依賴注入實現。

在PHPStorm中如何進行CLI模式的調試?在使用PHPStorm進行開發時,有時我們需要在命令行界面(CLI)模式下調試PHP�...

PHP8.1中的枚舉功能通過定義命名常量增強了代碼的清晰度和類型安全性。 1)枚舉可以是整數、字符串或對象,提高了代碼可讀性和類型安全性。 2)枚舉基於類,支持面向對象特性,如遍歷和反射。 3)枚舉可用於比較和賦值,確保類型安全。 4)枚舉支持添加方法,實現複雜邏輯。 5)嚴格類型檢查和錯誤處理可避免常見錯誤。 6)枚舉減少魔法值,提升可維護性,但需注意性能優化。

如何在系統重啟後自動設置unixsocket的權限每次系統重啟後,我們都需要執行以下命令來修改unixsocket的權限:sudo...

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。
