歡迎您光臨本站 註冊首頁

初步了解 PHP V6 中的新特性

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
本文詳細闡述 PHP V6 中的新特性。了解為什麼它更加容易使用、更加安全和更加適合國際化。新的特性包括增強對 Unicode 的支持、刪除了幾個函數、改進擴展、引擎添加內容、OO 函數的改變和 PHP 擴展。

簡介

“PHP 的特性” 簡單介紹了 PHP V6 中的新特性。在本文中,了解這些讓 PHP V6 更加容易使用、更加安全和更加適合國際化的新特性。本文探索改進的 Unicode 支持,刪除了幾個函數、改進的擴展、引擎添加內容、改進的面向對象函數和 PHP V6 中的一些擴展。





增強對 Unicode 的支持

PHP V6 中的主要特性是增強對 Unicode 的支持。目前,PHP 實際上是一個二進位處理器。PHP V5 沒有提供原生的 Unicode 支持;它假定所有字元的長度都為 1 位元組,這在處理非拉丁字元時會出現問題。您可以轉換到 Unicode,但需要使用 mbstring 擴展,而默認的 PHP V5 或外部工具(比如 iconv)都不支持該擴展。

PHP V5 有時不能正確顯示文本,這取決於字元編碼。Unicode 是由 Unicode Consortium 開發的行業標準,它能表示所有語言、程序和平台上的每一個字元。各個行業和標準都廣泛支持 Unicode,這使得實現國際化多語言應用程序成為可能。Unicode 可以使用多種字元編碼表示,最常見的是 UTF-8、UTF-16 和 UTF-32。

PHP V6 原生地支持 Unicode (UTF-8),因此它的引擎、擴展和 API 都支持 Unicode。儘管已經添加將所有二進位字元串作為不同類型處理的支持,PHP V6 仍然能夠將字元串作為 Unicode 處理。在 PHP V6 中,字元串的字面量為 Unicode,允許使用 Unicode 標識符,並且它的函數能夠理解 Unicode 文本。PHP V6 能夠在需要時支持 Unicode 字元串和其他編碼之間的轉換,並支持對 UTF-8 文件進行讀寫。下面給出一個從 UTF-8 文件讀取內容的例子:

$input = fopen('inputfile.txt', 'rt');  $str = fread($input, 100); // returns 100 Unicode characters

向 UTF-8 文本文件寫一個 Unicode 字元串 $uni:

$output = fopen('outputfile.txt', 'wt');  fwrite($fp, $uni); // writes out data in UTF-8 encoding

Unicode 模式

在 PHP V5 中,可以根據需求將 Unicode 模式設置為打開或關閉。這表明非 Unicode 和 Unicode 變體類、方法和函數名必須存儲在符號表中,這導致更多的開銷。PHP V6 在 php.ini 中提供一個伺服器通用的配置設置,以啟用或禁用 Unicode 模式。

Opcode 緩存用於緩存已編譯的 PHP 代碼。
伺服器通用的配置使引擎的某個部分的實現更加容易,引起的 opcode 緩存問題更少,並且提高運行速度,因為不需要在運行時轉換符號名。

PHP V6 保留了禁用 Unicode 模式的選項,因為一些字元串函數的 Unicode 實現變慢了 300%,這使整個應用程序的速度變慢 25%。PHP V6 在 php.ini 中提供一個運行時配置選項,用於啟用或禁用 Unicode 語義。默認設置為 on。

unicode.semantics = on           

將 unicode.semantics 設置為 off 並不意味著不使用 Unicode。當設置為 off 時,您仍然可用訪問 Unicode 特性。當 Unicode 語義設置為 off,字元串的字面量是 8 位的字元串;1 個字元等於 1 個位元組。

unicode.semantics = off  $str = "Hello, world!";// ASCII encoding  echo strlen($str);//result is 13

如果設置為 unicode.semantics=on,那麼字元串字面量使用 Unicode 類型。當 Unicode 語義設置為 on 時,一個字元可能 > 1 個位元組。

unicode.semantics = on  $str = "Hello, world!";// Unicode string  echo strlen($str);// result is 13  

PHP V6 中的 unicode.runtime_encoding 配置選項指定在運行時執行 Unicode 和二進位字元串之間的轉換時使用哪種編碼。例如,將運行時編碼設置為 iso-8859-1。

unicode.runtime_encoding = iso-8859-1  

當與尚未支持 Unicode 的函數連接時,仍然需要使用運行時編碼。PHP 腳本可以採用各種編碼方式。PHP V6 提供 unicode.script_encoding 配置選項來指定腳本的編碼。不管腳本的編碼是什麼,生成的字元串字面量都為 Unicode 類型。

 unicode.script_encoding = iso-8859-1  $uni = ""; // Unicode string  unicode.script_encoding = utf-8  $uni = "Atildel"; // also Unicode string  

您還可以將 declare() 語句作為 PHP 腳本的第一個語句,這樣也可以設置腳本的編碼。declare() 構造器覆蓋 php.ini 設置。declare() 設置不會傳播到文件。

 unicode.script_encoding = utf-8  declare(encoding="iso-8859-1");  $uni = "Atildel";// read as ISO-8859-1 string  include "inputfile.php";// file is read as UTF-8  

unicode.output_encoding 配置選項指定標準輸出流所使用的編碼,包括 echo、print 和 var_dump() 函數。輸出流的編碼被即時轉換。unicode.output_encoding 配置選項不影響二進位字元串。

 unicode.output_encoding = utf-8   unicode.script_encoding = iso-8859-1  $unicode = "Atildel"; // Unicode string (from ISO-8859-1)  echo $unicode; // converts $unicode to UTF-8 encoding  echo b"Atildel"; // no conversion, raw contents  

如果啟用了 Unicode 語義,HTTP 輸入必須轉換為 Unicode。GET 請求沒有編碼,並且也很少指定 POST 請求的編碼。PHP V6 提供 unicode.http_input_encoding 配置選項來指定將 HTTP 輸入轉換為哪種 Unicode 編碼。例如,將 HTTP 輸入轉換為 UTF-8:

unicode.http_input_encoding = utf-8 

PHP 將嘗試根據 unicode.http_input_encoding 設置進行解碼。如果解碼失敗,PHP 將使用原始的二進位數據填充請求數組。unicode.filename_encoding 配置選項指定文件系統上文件和目錄名的編碼。

unicode.filename_encoding = utf-8               

當輸入和輸出文件名時,與文件系統相關的函數執行所需的轉換。PHP V6 提供 unicode.fallback_encoding 配置選項來指定 fallback 編碼。

unicode.fallback_encoding = iso-8859-1  

當沒有給其他編碼分配值時,將使用 fallback 編碼。fallback 編碼的默認值是 UTF-8。在 PHP V6 中,您可以使用不同的字元編碼;當啟用 unicode.semantics 選項時,PHP V6 將所有字元串字面量轉換為 Unicode 字元串。您可以無縫地對輸入和輸出使用不同的字元。PHP V6 根據 php.ini 中指定的配置選項對 HTTP 輸入和輸出進行編碼。資料庫和用戶代理程序能夠收到所需的字元編碼,而不需使用任何轉換函數。

您不一定要使用 Unicode 開發腳本來處理和輸出 Unicode,但我們推薦這麼做。如前所述,通過 unicode.script_encoding 配置選項指定腳本編碼。為了在數據中(比如 MySQL)存儲 Unicode 數據,資料庫不需要配置為 UTF-8 編碼,但這樣做比較好。MySQL 資料庫被配置為運行不同的字符集,PHP V6 將以 Unicode 編碼發送查詢,而 MySQL 將嘗試轉換它。

兩種字元串類型

PHP V5 的字元串類型實現有很多字元串類型(二進位、字元串和 Unicode),並且有很多內部引擎函數和幫助函數的實現。PHP V6 只有兩種字元串類型:二進位和 Unicode。unicode.semantics 轉換(switch)決定字元串字面量的默認類型。如果啟用了 unicode.semantics,默認的字元串字面量就為 Unicode。如果禁用該語義轉換,默認字元串字面量的類型就為二進位。您可以顯式地在 Unicode 和二進位字元串類型之間轉換,也可以隱式地進行轉換。使用 unicode.runtime_encoding 配置選項進行隱式轉換。表 1 顯示了如何進行顯式轉換。


表 1. 轉換字元串類型
類型轉換 描述
(binary) 轉換到二進位字元串類型
(unicode) 轉換到 Unicode 字元串類型
(string) 如果 unicode.semantics 設置為 on,就轉換到 Unicode 字元串類型,否則轉換到二進位字元串類型

PHP V6 在內部使用 IS_STRING 表示二進位字元串數據,以及使用 IS_UNICODE 表示 Unicode 字元串數據。

在擴展中支持 Unicode

PHP V6 包含了 Unicode/API,擴展可以藉助它實現 Unicode 支持。需要向擴展模塊結構添加一個標誌,以表明它是否支持 Unicode。如果擴展不支持 Unicode,並且在 PHP 中啟用了 Unicode 語義,那麼在啟動時將不載入它。Unicode 支持被添加到 PHP 數據對象中 (PDO)。

ICU 庫

International Components for Unicode (ICU) 是一組提供 Unicode 和全球化支持的庫。PHP V6 需要使用 ICU,但 ICU 是一個大型的庫,將增加 PHP 的下載體積。PHP 要求使用 ICU V3.4,並且要求發布版提供 ICU 庫。

文件名編碼

不同的文件名可能使用不同的字符集進行編碼。例如,Windows 文件名使用 UTF-16 編碼。filename_encoding 設置指定期望的文件名編碼。當 read 函數(比如 readdir() 和 readfile())遇到其編碼在 filename_encoding 中不存在的文件名時,將返回一個二進位字元串。

緩存校對器

校對器(Collator)用於比較字元串。打開和關閉校對器需要引入開銷。PHP V6 緩存了校對器,但限制存儲在緩存中的對象數量,以防止使用過多的內存。PHP V6 在線程/進程通用緩存中存儲最近打開的 3 個校對器。

基於位置的函數

對於使用系統位置的 PHP 函數,由於位置名在不同的平台中不一致甚至不可用,因此這是一個問題。PHP V6 僅在合適的地方使用基於位置的函數。基於位置的函數包括 strtoupper/strtolower 和 stristr 等。strtoupper 函數將字母表中的字元都轉換為大寫的。“字母表的字元順序” 由當前的位置決定。

字符集轉換錯誤

在字元編碼之間執行轉換可能發生轉換錯誤,因為並不是源字元串中的所有字元都有必要存儲在目標字元串中。PHP V6 為字符集轉換失敗提供一個額外的錯誤模式,它會在失敗時拋出異常。PHP V6 為處理轉換錯誤引入了兩個新的 php.ini 配置選項:unicode.from_error_mode 和 unicode.from_error_subst_char。

unicode.from_error_mode = U_INVALID_SUBSTITUTE  unicode.from_error_subst_char = 3f

unicode.from_error_subst_char 選項為無效的字元串指定了代替字元串的十六進位值;它的默認值是 3f。

unicode.from_error_mode 選項指定錯誤模式,它在遇到無效字元串時採取行動。表 2 顯示了 unicode.from_error_mode 可能使用的值。


表 2. unicode.from_error_mode 值
常量 說明
U_INVALID_STOP 0 遇到第一個無效字元時停止
U_INVALID_SKIP 1 跳過無效字元
U_INVALID_SUBSTITUTE 2 替換無效字元;默認值
U_INVALID_ESCAPE 3 對無效字元進行轉義





刪除了幾個函數

這個小節概述了在 PHP V6 中刪除的幾個函數。

刪除了 register_globals

PHP V5 在 php.ini 中使用 register_globals 配置選項從環境和 HTTP 請求參數定義變數。不過,register_globals 生成不安全的代碼。因此,在 PHP V6 中刪除了 register_globals。

register_globals 生成不安全代碼的方式之一是 authenticate.php,它使用 $auth 變數對用戶進行身份驗證。因為 $auth 沒有被初始化,所以它的值可能通過使用 register_globals 注入變數來定義,比如 GET authenticate.php?auth=1。

<?php  if (authenticated_user()) {      $auth = true;  }  if ($auth) {      include "/data.php";  }  ?>              

register_globals 注入的變數也可能在會話中生成不安全的代碼。看看以下代碼,當設置了 $username 變數時,將在用戶會話中顯示一條歡迎消息。但是,當啟用 register_globals 時,可能會使用 HTTP 請求參數注入 $username 變數。

<?php  if (isset(
本文詳細闡述 PHP V6 中的新特性。了解為什麼它更加容易使用、更加安全和更加適合國際化。新的特性包括增強對 Unicode 的支持、刪除了幾個函數、改進擴展、引擎添加內容、OO 函數的改變和 PHP 擴展。

簡介

“PHP 的特性” 簡單介紹了 PHP V6 中的新特性。在本文中,了解這些讓 PHP V6 更加容易使用、更加安全和更加適合國際化的新特性。本文探索改進的 Unicode 支持,刪除了幾個函數、改進的擴展、引擎添加內容、改進的面向對象函數和 PHP V6 中的一些擴展。





增強對 Unicode 的支持

PHP V6 中的主要特性是增強對 Unicode 的支持。目前,PHP 實際上是一個二進位處理器。PHP V5 沒有提供原生的 Unicode 支持;它假定所有字元的長度都為 1 位元組,這在處理非拉丁字元時會出現問題。您可以轉換到 Unicode,但需要使用 mbstring 擴展,而默認的 PHP V5 或外部工具(比如 iconv)都不支持該擴展。

PHP V5 有時不能正確顯示文本,這取決於字元編碼。Unicode 是由 Unicode Consortium 開發的行業標準,它能表示所有語言、程序和平台上的每一個字元。各個行業和標準都廣泛支持 Unicode,這使得實現國際化多語言應用程序成為可能。Unicode 可以使用多種字元編碼表示,最常見的是 UTF-8、UTF-16 和 UTF-32。

PHP V6 原生地支持 Unicode (UTF-8),因此它的引擎、擴展和 API 都支持 Unicode。儘管已經添加將所有二進位字元串作為不同類型處理的支持,PHP V6 仍然能夠將字元串作為 Unicode 處理。在 PHP V6 中,字元串的字面量為 Unicode,允許使用 Unicode 標識符,並且它的函數能夠理解 Unicode 文本。PHP V6 能夠在需要時支持 Unicode 字元串和其他編碼之間的轉換,並支持對 UTF-8 文件進行讀寫。下面給出一個從 UTF-8 文件讀取內容的例子:

$input = fopen('inputfile.txt', 'rt');  $str = fread($input, 100); // returns 100 Unicode characters

向 UTF-8 文本文件寫一個 Unicode 字元串 $uni:

$output = fopen('outputfile.txt', 'wt');  fwrite($fp, $uni); // writes out data in UTF-8 encoding

Unicode 模式

在 PHP V5 中,可以根據需求將 Unicode 模式設置為打開或關閉。這表明非 Unicode 和 Unicode 變體類、方法和函數名必須存儲在符號表中,這導致更多的開銷。PHP V6 在 php.ini 中提供一個伺服器通用的配置設置,以啟用或禁用 Unicode 模式。

Opcode 緩存用於緩存已編譯的 PHP 代碼。
伺服器通用的配置使引擎的某個部分的實現更加容易,引起的 opcode 緩存問題更少,並且提高運行速度,因為不需要在運行時轉換符號名。

PHP V6 保留了禁用 Unicode 模式的選項,因為一些字元串函數的 Unicode 實現變慢了 300%,這使整個應用程序的速度變慢 25%。PHP V6 在 php.ini 中提供一個運行時配置選項,用於啟用或禁用 Unicode 語義。默認設置為 on。

unicode.semantics = on           

將 unicode.semantics 設置為 off 並不意味著不使用 Unicode。當設置為 off 時,您仍然可用訪問 Unicode 特性。當 Unicode 語義設置為 off,字元串的字面量是 8 位的字元串;1 個字元等於 1 個位元組。

unicode.semantics = off  $str = "Hello, world!";// ASCII encoding  echo strlen($str);//result is 13

如果設置為 unicode.semantics=on,那麼字元串字面量使用 Unicode 類型。當 Unicode 語義設置為 on 時,一個字元可能 > 1 個位元組。

unicode.semantics = on  $str = "Hello, world!";// Unicode string  echo strlen($str);// result is 13  

PHP V6 中的 unicode.runtime_encoding 配置選項指定在運行時執行 Unicode 和二進位字元串之間的轉換時使用哪種編碼。例如,將運行時編碼設置為 iso-8859-1。

unicode.runtime_encoding = iso-8859-1  

當與尚未支持 Unicode 的函數連接時,仍然需要使用運行時編碼。PHP 腳本可以採用各種編碼方式。PHP V6 提供 unicode.script_encoding 配置選項來指定腳本的編碼。不管腳本的編碼是什麼,生成的字元串字面量都為 Unicode 類型。

 unicode.script_encoding = iso-8859-1  $uni = ""; // Unicode string  unicode.script_encoding = utf-8  $uni = "Atildel"; // also Unicode string  

您還可以將 declare() 語句作為 PHP 腳本的第一個語句,這樣也可以設置腳本的編碼。declare() 構造器覆蓋 php.ini 設置。declare() 設置不會傳播到文件。

 unicode.script_encoding = utf-8  declare(encoding="iso-8859-1");  $uni = "Atildel";// read as ISO-8859-1 string  include "inputfile.php";// file is read as UTF-8  

unicode.output_encoding 配置選項指定標準輸出流所使用的編碼,包括 echo、print 和 var_dump() 函數。輸出流的編碼被即時轉換。unicode.output_encoding 配置選項不影響二進位字元串。

 unicode.output_encoding = utf-8   unicode.script_encoding = iso-8859-1  $unicode = "Atildel"; // Unicode string (from ISO-8859-1)  echo $unicode; // converts $unicode to UTF-8 encoding  echo b"Atildel"; // no conversion, raw contents  

如果啟用了 Unicode 語義,HTTP 輸入必須轉換為 Unicode。GET 請求沒有編碼,並且也很少指定 POST 請求的編碼。PHP V6 提供 unicode.http_input_encoding 配置選項來指定將 HTTP 輸入轉換為哪種 Unicode 編碼。例如,將 HTTP 輸入轉換為 UTF-8:

unicode.http_input_encoding = utf-8 

PHP 將嘗試根據 unicode.http_input_encoding 設置進行解碼。如果解碼失敗,PHP 將使用原始的二進位數據填充請求數組。unicode.filename_encoding 配置選項指定文件系統上文件和目錄名的編碼。

unicode.filename_encoding = utf-8               

當輸入和輸出文件名時,與文件系統相關的函數執行所需的轉換。PHP V6 提供 unicode.fallback_encoding 配置選項來指定 fallback 編碼。

unicode.fallback_encoding = iso-8859-1  

當沒有給其他編碼分配值時,將使用 fallback 編碼。fallback 編碼的默認值是 UTF-8。在 PHP V6 中,您可以使用不同的字元編碼;當啟用 unicode.semantics 選項時,PHP V6 將所有字元串字面量轉換為 Unicode 字元串。您可以無縫地對輸入和輸出使用不同的字元。PHP V6 根據 php.ini 中指定的配置選項對 HTTP 輸入和輸出進行編碼。資料庫和用戶代理程序能夠收到所需的字元編碼,而不需使用任何轉換函數。

您不一定要使用 Unicode 開發腳本來處理和輸出 Unicode,但我們推薦這麼做。如前所述,通過 unicode.script_encoding 配置選項指定腳本編碼。為了在數據中(比如 MySQL)存儲 Unicode 數據,資料庫不需要配置為 UTF-8 編碼,但這樣做比較好。MySQL 資料庫被配置為運行不同的字符集,PHP V6 將以 Unicode 編碼發送查詢,而 MySQL 將嘗試轉換它。

兩種字元串類型

PHP V5 的字元串類型實現有很多字元串類型(二進位、字元串和 Unicode),並且有很多內部引擎函數和幫助函數的實現。PHP V6 只有兩種字元串類型:二進位和 Unicode。unicode.semantics 轉換(switch)決定字元串字面量的默認類型。如果啟用了 unicode.semantics,默認的字元串字面量就為 Unicode。如果禁用該語義轉換,默認字元串字面量的類型就為二進位。您可以顯式地在 Unicode 和二進位字元串類型之間轉換,也可以隱式地進行轉換。使用 unicode.runtime_encoding 配置選項進行隱式轉換。表 1 顯示了如何進行顯式轉換。


表 1. 轉換字元串類型
類型轉換 描述
(binary) 轉換到二進位字元串類型
(unicode) 轉換到 Unicode 字元串類型
(string) 如果 unicode.semantics 設置為 on,就轉換到 Unicode 字元串類型,否則轉換到二進位字元串類型

PHP V6 在內部使用 IS_STRING 表示二進位字元串數據,以及使用 IS_UNICODE 表示 Unicode 字元串數據。

在擴展中支持 Unicode

PHP V6 包含了 Unicode/API,擴展可以藉助它實現 Unicode 支持。需要向擴展模塊結構添加一個標誌,以表明它是否支持 Unicode。如果擴展不支持 Unicode,並且在 PHP 中啟用了 Unicode 語義,那麼在啟動時將不載入它。Unicode 支持被添加到 PHP 數據對象中 (PDO)。

ICU 庫

International Components for Unicode (ICU) 是一組提供 Unicode 和全球化支持的庫。PHP V6 需要使用 ICU,但 ICU 是一個大型的庫,將增加 PHP 的下載體積。PHP 要求使用 ICU V3.4,並且要求發布版提供 ICU 庫。

文件名編碼

不同的文件名可能使用不同的字符集進行編碼。例如,Windows 文件名使用 UTF-16 編碼。filename_encoding 設置指定期望的文件名編碼。當 read 函數(比如 readdir() 和 readfile())遇到其編碼在 filename_encoding 中不存在的文件名時,將返回一個二進位字元串。

緩存校對器

校對器(Collator)用於比較字元串。打開和關閉校對器需要引入開銷。PHP V6 緩存了校對器,但限制存儲在緩存中的對象數量,以防止使用過多的內存。PHP V6 在線程/進程通用緩存中存儲最近打開的 3 個校對器。

基於位置的函數

對於使用系統位置的 PHP 函數,由於位置名在不同的平台中不一致甚至不可用,因此這是一個問題。PHP V6 僅在合適的地方使用基於位置的函數。基於位置的函數包括 strtoupper/strtolower 和 stristr 等。strtoupper 函數將字母表中的字元都轉換為大寫的。“字母表的字元順序” 由當前的位置決定。

字符集轉換錯誤

在字元編碼之間執行轉換可能發生轉換錯誤,因為並不是源字元串中的所有字元都有必要存儲在目標字元串中。PHP V6 為字符集轉換失敗提供一個額外的錯誤模式,它會在失敗時拋出異常。PHP V6 為處理轉換錯誤引入了兩個新的 php.ini 配置選項:unicode.from_error_mode 和 unicode.from_error_subst_char。

unicode.from_error_mode = U_INVALID_SUBSTITUTE  unicode.from_error_subst_char = 3f

unicode.from_error_subst_char 選項為無效的字元串指定了代替字元串的十六進位值;它的默認值是 3f。

unicode.from_error_mode 選項指定錯誤模式,它在遇到無效字元串時採取行動。表 2 顯示了 unicode.from_error_mode 可能使用的值。


表 2. unicode.from_error_mode 值
常量 說明
U_INVALID_STOP 0 遇到第一個無效字元時停止
U_INVALID_SKIP 1 跳過無效字元
U_INVALID_SUBSTITUTE 2 替換無效字元;默認值
U_INVALID_ESCAPE 3 對無效字元進行轉義





刪除了幾個函數

這個小節概述了在 PHP V6 中刪除的幾個函數。

刪除了 register_globals

PHP V5 在 php.ini 中使用 register_globals 配置選項從環境和 HTTP 請求參數定義變數。不過,register_globals 生成不安全的代碼。因此,在 PHP V6 中刪除了 register_globals。

register_globals 生成不安全代碼的方式之一是 authenticate.php,它使用 $auth 變數對用戶進行身份驗證。因為 $auth 沒有被初始化,所以它的值可能通過使用 register_globals 注入變數來定義,比如 GET authenticate.php?auth=1。

<?php  if (authenticated_user()) {      $auth = true;  }  if ($auth) {      include "/data.php";  }  ?>              

register_globals 注入的變數也可能在會話中生成不安全的代碼。看看以下代碼,當設置了 $username 變數時,將在用戶會話中顯示一條歡迎消息。但是,當啟用 register_globals 時,可能會使用 HTTP 請求參數注入 $username 變數。

___FCKpd___14

所有使用 register_globals 的函數都被刪除了,比如 session_register。如果需要導入請求變數,可以使用 import_request_variables。或者使用 $_POST、$_GET、$_COOKIE 和 $_REQUEST 變數。如果設置了 register_globals,PHP V6 將在啟動時拋出 E_CORE_ERROR。

刪除了 magic_quotes

在 PHP V5 中,當啟用了 magic_quotes 配置選項時,它會在輸入數據中自動將所有單引號(')、雙引號(")、反斜杠(\)和 NULL 字元轉義為帶反斜杠的(\)PHP 腳本。Magic Quotes 減少了 SQL 注入(一種能夠篡改 SQL 命令的技術)的風險。Magic Quotes 便於將數據插入到資料庫中。不 使用 Magic Quotes 的理由是考慮到移植性、性能和方便性。

您需要知道是否關閉了 Magic Quotes。如果 Magic Quotes 處於 on,而您認為它處於 off,應用程序就會出現額外的斜杠。如果 Magic Quotes 處於 off,而您認為它處於 on,應用程序就可能遭受 SQL 注入攻擊。Magic Quotes 會損害性能,因為並不是所有轉義數據都被插入到資料庫。一個更好的代替辦法是在運行時使用轉義函數,比如 addslashes。Magic Quotes 可能帶來不便,因為並不是所有數據都需要轉義。可以使用 stripslashes 函數刪除多餘的斜杠。

PHP V6 不再支持 magic_quotes、magic_quotes_sybase 和 magic_quotes_gpc 設置。如果在啟動時發現這些設置,PHP 將發出一個 E_CORE_ERROR。此外,還刪除了 get_magic_quotes_gpc() 函數。

刪除了 safe_mode

在 PHP V5 中,safe_mode 配置選項可用於解決與共享伺服器有關的安全問題。它確保需要打開或包含的文件的用戶必須與執行這些文件的腳本的用戶相同。safe_mode 並不是絕對安全的。

考慮這樣一個場景,一個應用程序使用 Web 伺服器的 ID 並生成緩存文件或映像。如果該應用程序由客戶機用戶載入,PHP 腳本將不能打開緩存文件或映像,因為用戶 ID 不匹配。並且,safe_mode 可以繞過庫。

在 PHP V6 中刪除了 safe_mode 選項。如果檢測到 safe_mode 設置,將拋出 E_CORE_ERROR。open_basedir 配置仍然可用,它限制 PHP 可以在特定目錄樹中打開的文件。

刪除不贊成使用的行為

在 PHP V6 中刪除了一些在早期的 PHP 版本中不贊成使用的行為。allow_call_time_pass_reference 配置指定在運行時通過引用傳遞參數時是否發出警告,它在 PHP V5 中就不推薦使用。在 PHP V6 中刪除了 allow_call_time_pass_reference。

如果要指定哪個參數是通過引用傳遞的,更好的方法是使用聲明函數。在 PHP V6 中,call-time-pass-by-reference 將拋出一個 E_STRICT 錯誤。在 PHP V6 中,“var” 已經成為 “public” 的別名,並且刪除了 E_STRICT 警告。受 "new lt;object-name>" 的影響,也刪除了 return-by-reference。通過引用賦值 “new” 將拋出一個 E_STRICT 錯誤。例如,下面的語句將拋出 E_STRICT 錯誤:

<?php $classA =& new ClassA();?>

刪除了 zend.ze1_compatibility_mode

zend.ze1_compatibility_mode 配置啟用了與 Zend Engine V1 (PHP V4) 的兼容性,它是在 PHP V5 引入的,方便了從 PHP V4 遷移到 PHP V5。

在 PHP V6 中,已經刪除了 zend.ze1_compatibility_mode 特性,如果檢測到該設置,將拋出 E_CORE_ERROR。

刪除了 Freetype 1 和 GD 1 庫

FreeType 1 和 GD 1 是老版本的字體呈現和圖像處理庫。它們不再受到維護,並且已被更新版本的 FreeType 和 GD 代替。在 PHP V6 中,刪除了對 FreeType 1 和 GD 1 庫的支持。

默認情況下不啟用 dl()

dl (string $library) 函數用於在運行時載入 PHP 擴展。在 PHP V5 中,可以在 php.ini 配置文件中啟用或禁用 dl() 函數:enable_dl = On。

dl() 函數會給從未載入過的模塊帶來問題。dl() 函數不能在多線程伺服器中正常工作,比如 IIS 或 Zeus,因為在這些伺服器中會自動禁用它。不過 dl() 函數在 PHP Command Line Interface (CLI) Server Application Programming Interface (SAPI) 中非常有用。

在 PHP V6 中,dl() 函數在默認情況下是禁用的,但並沒有刪除它。SAPI 層可能會顯式地註冊 dl() 函數。

FastCGI 模式

FastCGI 提供很高的性能,如果禁用,將導致雜亂的代碼。在 PHP V6 中不能禁用 FastCGI。

刪除了 register_long_arrays

當啟用 register_long_arrays 配置選項時,將註冊很長的超級全局變數 — $HTTP_*_VARS 變數。$HTTP_*_VARS 變數是在 PHP V5 中為了向後兼容性而引入的,但不是必要的。使用更短的變數 $_GET、$_POST 和 $_SERVER 代替它會更好。在新的 PHP 版本中,register_long_arrays 設置和 $HTTP_*_VARS 沒有得到好評。

在 PHP V6 中,刪除了 register_long_arrays 設置和 $HTTP_*_VARS 全局變數,如果檢測到 register_long_arrays,將拋出 E_CORE_ERROR。

刪除 break $var

動態的 break 操作數不起作用,如以下示例所示:

for (..) { $var = rand(1, 2); break $var; }

在 PHP V6 中,刪除了動態的 break 操作數。取而代之的是,您可以為 $var 分配一個數字,如下所示:

for (..) { $var = rand(1, 2); break 1; }





改進擴展

擴展是 PHP 的主要組件。在 PHP V6 中,有幾個組件得到了改進。

包含在核心發布版中的 XML 擴展

XMLReader 擴展提供一個 XML 解析器,用於閱讀 XML 文件,該解析器在內部基於 SAX 解析。XMLWriter 為寫 XML 文件提供一個 API。XMLReader 和 XMLWriter 使 XML 文件的讀寫更加容易。PHP V5 的核心發布版沒有包含 XMLReader 和 XMLWriter。

PHP V6 將在核心發布版中包含 XMLReader 和 XMLWriter 擴展,並且默認啟用這兩個擴展。

正則表達式擴展

PHP V5.x 為正則表達式提供兩個庫:ereg 和 Perl Compatible Regular Expression (PCRE)。ereg 庫支持 Portable Operating System Interface (POSIX) 正則表達式,而 PCRE 擴展支持與 Perl 兼容的語法。打包的 ereg 庫會造成問題,因此被轉換成擴展並從核心發布版移動到 PHP Extension Community Library (PECL)。

PCRE 擴展提供更多的特性,並且比 ereg 擴展快。PCRE 擴展在默認情況下是啟用的,並且不可以禁用它。一些核心的 PHP 函數使用 POSIX 正則表達式。因為刪除了 ereg 庫,所以這些函數將使用 PCRE 表達式重新編寫。PCRE 表達式提供一些與 ereg 庫等效的函數。


表 3. PCRE 擴展中的等效函數
ereg() 函數 等效的 PCRE 函數
ereg() preg_match()
ereg_replace() preg_replace()

MIME 類型檢查擴展

在 PHP V5 中,mime_magic 擴展用於媒體類型(media-type)檢測,但不是很可靠。PECL 為 MIME 類型檢查提供另一個擴展:Fileinfo。mime_magic 擴展將從核心發布版移動到 PECL。Fileinfo 擴展將添加到核心發布版,並默認啟用。

默認啟用 SOAP 擴展

SOAP 擴展(ext/soap)用於開發使用 Web 服務的 PHP 應用程序,包括 SOAP 伺服器和 SOAP 客戶機。在 PHP V5 中,SOAP 擴展不是默認啟用的;開發人員必須配置 SOAP 擴展。在 PHP V6 中,默認啟用 SOAP 擴展。PHP V6 還實現一些安全擴展。





引擎的添加內容

在 PHP V6,將添加 64 位的整數,同時保留 32 位整數。64 位引擎的轉換名為 int64。將使用一個靜態標籤擴展 break 關鍵字。將從 ?: 操作符丟棄中間參數。例如,在下面的表達式中,如果 $_GET['var'] 計算為 true,則 $var 設置為 3。如果 $_GET['var'] 計算為 false 或沒有設置,則 $var 設置為 $_GET['var']。

            $var = 
本文詳細闡述 PHP V6 中的新特性。了解為什麼它更加容易使用、更加安全和更加適合國際化。新的特性包括增強對 Unicode 的支持、刪除了幾個函數、改進擴展、引擎添加內容、OO 函數的改變和 PHP 擴展。

簡介

“PHP 的特性” 簡單介紹了 PHP V6 中的新特性。在本文中,了解這些讓 PHP V6 更加容易使用、更加安全和更加適合國際化的新特性。本文探索改進的 Unicode 支持,刪除了幾個函數、改進的擴展、引擎添加內容、改進的面向對象函數和 PHP V6 中的一些擴展。





增強對 Unicode 的支持

PHP V6 中的主要特性是增強對 Unicode 的支持。目前,PHP 實際上是一個二進位處理器。PHP V5 沒有提供原生的 Unicode 支持;它假定所有字元的長度都為 1 位元組,這在處理非拉丁字元時會出現問題。您可以轉換到 Unicode,但需要使用 mbstring 擴展,而默認的 PHP V5 或外部工具(比如 iconv)都不支持該擴展。

PHP V5 有時不能正確顯示文本,這取決於字元編碼。Unicode 是由 Unicode Consortium 開發的行業標準,它能表示所有語言、程序和平台上的每一個字元。各個行業和標準都廣泛支持 Unicode,這使得實現國際化多語言應用程序成為可能。Unicode 可以使用多種字元編碼表示,最常見的是 UTF-8、UTF-16 和 UTF-32。

PHP V6 原生地支持 Unicode (UTF-8),因此它的引擎、擴展和 API 都支持 Unicode。儘管已經添加將所有二進位字元串作為不同類型處理的支持,PHP V6 仍然能夠將字元串作為 Unicode 處理。在 PHP V6 中,字元串的字面量為 Unicode,允許使用 Unicode 標識符,並且它的函數能夠理解 Unicode 文本。PHP V6 能夠在需要時支持 Unicode 字元串和其他編碼之間的轉換,並支持對 UTF-8 文件進行讀寫。下面給出一個從 UTF-8 文件讀取內容的例子:

$input = fopen('inputfile.txt', 'rt');  $str = fread($input, 100); // returns 100 Unicode characters

向 UTF-8 文本文件寫一個 Unicode 字元串 $uni:

$output = fopen('outputfile.txt', 'wt');  fwrite($fp, $uni); // writes out data in UTF-8 encoding

Unicode 模式

在 PHP V5 中,可以根據需求將 Unicode 模式設置為打開或關閉。這表明非 Unicode 和 Unicode 變體類、方法和函數名必須存儲在符號表中,這導致更多的開銷。PHP V6 在 php.ini 中提供一個伺服器通用的配置設置,以啟用或禁用 Unicode 模式。

Opcode 緩存用於緩存已編譯的 PHP 代碼。
伺服器通用的配置使引擎的某個部分的實現更加容易,引起的 opcode 緩存問題更少,並且提高運行速度,因為不需要在運行時轉換符號名。

PHP V6 保留了禁用 Unicode 模式的選項,因為一些字元串函數的 Unicode 實現變慢了 300%,這使整個應用程序的速度變慢 25%。PHP V6 在 php.ini 中提供一個運行時配置選項,用於啟用或禁用 Unicode 語義。默認設置為 on。

unicode.semantics = on           

將 unicode.semantics 設置為 off 並不意味著不使用 Unicode。當設置為 off 時,您仍然可用訪問 Unicode 特性。當 Unicode 語義設置為 off,字元串的字面量是 8 位的字元串;1 個字元等於 1 個位元組。

unicode.semantics = off  $str = "Hello, world!";// ASCII encoding  echo strlen($str);//result is 13

如果設置為 unicode.semantics=on,那麼字元串字面量使用 Unicode 類型。當 Unicode 語義設置為 on 時,一個字元可能 > 1 個位元組。

unicode.semantics = on  $str = "Hello, world!";// Unicode string  echo strlen($str);// result is 13  

PHP V6 中的 unicode.runtime_encoding 配置選項指定在運行時執行 Unicode 和二進位字元串之間的轉換時使用哪種編碼。例如,將運行時編碼設置為 iso-8859-1。

unicode.runtime_encoding = iso-8859-1  

當與尚未支持 Unicode 的函數連接時,仍然需要使用運行時編碼。PHP 腳本可以採用各種編碼方式。PHP V6 提供 unicode.script_encoding 配置選項來指定腳本的編碼。不管腳本的編碼是什麼,生成的字元串字面量都為 Unicode 類型。

 unicode.script_encoding = iso-8859-1  $uni = ""; // Unicode string  unicode.script_encoding = utf-8  $uni = "Atildel"; // also Unicode string  

您還可以將 declare() 語句作為 PHP 腳本的第一個語句,這樣也可以設置腳本的編碼。declare() 構造器覆蓋 php.ini 設置。declare() 設置不會傳播到文件。

 unicode.script_encoding = utf-8  declare(encoding="iso-8859-1");  $uni = "Atildel";// read as ISO-8859-1 string  include "inputfile.php";// file is read as UTF-8  

unicode.output_encoding 配置選項指定標準輸出流所使用的編碼,包括 echo、print 和 var_dump() 函數。輸出流的編碼被即時轉換。unicode.output_encoding 配置選項不影響二進位字元串。

 unicode.output_encoding = utf-8   unicode.script_encoding = iso-8859-1  $unicode = "Atildel"; // Unicode string (from ISO-8859-1)  echo $unicode; // converts $unicode to UTF-8 encoding  echo b"Atildel"; // no conversion, raw contents  

如果啟用了 Unicode 語義,HTTP 輸入必須轉換為 Unicode。GET 請求沒有編碼,並且也很少指定 POST 請求的編碼。PHP V6 提供 unicode.http_input_encoding 配置選項來指定將 HTTP 輸入轉換為哪種 Unicode 編碼。例如,將 HTTP 輸入轉換為 UTF-8:

unicode.http_input_encoding = utf-8 

PHP 將嘗試根據 unicode.http_input_encoding 設置進行解碼。如果解碼失敗,PHP 將使用原始的二進位數據填充請求數組。unicode.filename_encoding 配置選項指定文件系統上文件和目錄名的編碼。

unicode.filename_encoding = utf-8               

當輸入和輸出文件名時,與文件系統相關的函數執行所需的轉換。PHP V6 提供 unicode.fallback_encoding 配置選項來指定 fallback 編碼。

unicode.fallback_encoding = iso-8859-1  

當沒有給其他編碼分配值時,將使用 fallback 編碼。fallback 編碼的默認值是 UTF-8。在 PHP V6 中,您可以使用不同的字元編碼;當啟用 unicode.semantics 選項時,PHP V6 將所有字元串字面量轉換為 Unicode 字元串。您可以無縫地對輸入和輸出使用不同的字元。PHP V6 根據 php.ini 中指定的配置選項對 HTTP 輸入和輸出進行編碼。資料庫和用戶代理程序能夠收到所需的字元編碼,而不需使用任何轉換函數。

您不一定要使用 Unicode 開發腳本來處理和輸出 Unicode,但我們推薦這麼做。如前所述,通過 unicode.script_encoding 配置選項指定腳本編碼。為了在數據中(比如 MySQL)存儲 Unicode 數據,資料庫不需要配置為 UTF-8 編碼,但這樣做比較好。MySQL 資料庫被配置為運行不同的字符集,PHP V6 將以 Unicode 編碼發送查詢,而 MySQL 將嘗試轉換它。

兩種字元串類型

PHP V5 的字元串類型實現有很多字元串類型(二進位、字元串和 Unicode),並且有很多內部引擎函數和幫助函數的實現。PHP V6 只有兩種字元串類型:二進位和 Unicode。unicode.semantics 轉換(switch)決定字元串字面量的默認類型。如果啟用了 unicode.semantics,默認的字元串字面量就為 Unicode。如果禁用該語義轉換,默認字元串字面量的類型就為二進位。您可以顯式地在 Unicode 和二進位字元串類型之間轉換,也可以隱式地進行轉換。使用 unicode.runtime_encoding 配置選項進行隱式轉換。表 1 顯示了如何進行顯式轉換。


表 1. 轉換字元串類型
類型轉換 描述
(binary) 轉換到二進位字元串類型
(unicode) 轉換到 Unicode 字元串類型
(string) 如果 unicode.semantics 設置為 on,就轉換到 Unicode 字元串類型,否則轉換到二進位字元串類型

PHP V6 在內部使用 IS_STRING 表示二進位字元串數據,以及使用 IS_UNICODE 表示 Unicode 字元串數據。

在擴展中支持 Unicode

PHP V6 包含了 Unicode/API,擴展可以藉助它實現 Unicode 支持。需要向擴展模塊結構添加一個標誌,以表明它是否支持 Unicode。如果擴展不支持 Unicode,並且在 PHP 中啟用了 Unicode 語義,那麼在啟動時將不載入它。Unicode 支持被添加到 PHP 數據對象中 (PDO)。

ICU 庫

International Components for Unicode (ICU) 是一組提供 Unicode 和全球化支持的庫。PHP V6 需要使用 ICU,但 ICU 是一個大型的庫,將增加 PHP 的下載體積。PHP 要求使用 ICU V3.4,並且要求發布版提供 ICU 庫。

文件名編碼

不同的文件名可能使用不同的字符集進行編碼。例如,Windows 文件名使用 UTF-16 編碼。filename_encoding 設置指定期望的文件名編碼。當 read 函數(比如 readdir() 和 readfile())遇到其編碼在 filename_encoding 中不存在的文件名時,將返回一個二進位字元串。

緩存校對器

校對器(Collator)用於比較字元串。打開和關閉校對器需要引入開銷。PHP V6 緩存了校對器,但限制存儲在緩存中的對象數量,以防止使用過多的內存。PHP V6 在線程/進程通用緩存中存儲最近打開的 3 個校對器。

基於位置的函數

對於使用系統位置的 PHP 函數,由於位置名在不同的平台中不一致甚至不可用,因此這是一個問題。PHP V6 僅在合適的地方使用基於位置的函數。基於位置的函數包括 strtoupper/strtolower 和 stristr 等。strtoupper 函數將字母表中的字元都轉換為大寫的。“字母表的字元順序” 由當前的位置決定。

字符集轉換錯誤

在字元編碼之間執行轉換可能發生轉換錯誤,因為並不是源字元串中的所有字元都有必要存儲在目標字元串中。PHP V6 為字符集轉換失敗提供一個額外的錯誤模式,它會在失敗時拋出異常。PHP V6 為處理轉換錯誤引入了兩個新的 php.ini 配置選項:unicode.from_error_mode 和 unicode.from_error_subst_char。

unicode.from_error_mode = U_INVALID_SUBSTITUTE  unicode.from_error_subst_char = 3f

unicode.from_error_subst_char 選項為無效的字元串指定了代替字元串的十六進位值;它的默認值是 3f。

unicode.from_error_mode 選項指定錯誤模式,它在遇到無效字元串時採取行動。表 2 顯示了 unicode.from_error_mode 可能使用的值。


表 2. unicode.from_error_mode 值
常量 說明
U_INVALID_STOP 0 遇到第一個無效字元時停止
U_INVALID_SKIP 1 跳過無效字元
U_INVALID_SUBSTITUTE 2 替換無效字元;默認值
U_INVALID_ESCAPE 3 對無效字元進行轉義





刪除了幾個函數

這個小節概述了在 PHP V6 中刪除的幾個函數。

刪除了 register_globals

PHP V5 在 php.ini 中使用 register_globals 配置選項從環境和 HTTP 請求參數定義變數。不過,register_globals 生成不安全的代碼。因此,在 PHP V6 中刪除了 register_globals。

register_globals 生成不安全代碼的方式之一是 authenticate.php,它使用 $auth 變數對用戶進行身份驗證。因為 $auth 沒有被初始化,所以它的值可能通過使用 register_globals 注入變數來定義,比如 GET authenticate.php?auth=1。

<?php  if (authenticated_user()) {      $auth = true;  }  if ($auth) {      include "/data.php";  }  ?>              

register_globals 注入的變數也可能在會話中生成不安全的代碼。看看以下代碼,當設置了 $username 變數時,將在用戶會話中顯示一條歡迎消息。但是,當啟用 register_globals 時,可能會使用 HTTP 請求參數注入 $username 變數。

<?php  if (isset(
本文詳細闡述 PHP V6 中的新特性。了解為什麼它更加容易使用、更加安全和更加適合國際化。新的特性包括增強對 Unicode 的支持、刪除了幾個函數、改進擴展、引擎添加內容、OO 函數的改變和 PHP 擴展。

簡介

“PHP 的特性” 簡單介紹了 PHP V6 中的新特性。在本文中,了解這些讓 PHP V6 更加容易使用、更加安全和更加適合國際化的新特性。本文探索改進的 Unicode 支持,刪除了幾個函數、改進的擴展、引擎添加內容、改進的面向對象函數和 PHP V6 中的一些擴展。





增強對 Unicode 的支持

PHP V6 中的主要特性是增強對 Unicode 的支持。目前,PHP 實際上是一個二進位處理器。PHP V5 沒有提供原生的 Unicode 支持;它假定所有字元的長度都為 1 位元組,這在處理非拉丁字元時會出現問題。您可以轉換到 Unicode,但需要使用 mbstring 擴展,而默認的 PHP V5 或外部工具(比如 iconv)都不支持該擴展。

PHP V5 有時不能正確顯示文本,這取決於字元編碼。Unicode 是由 Unicode Consortium 開發的行業標準,它能表示所有語言、程序和平台上的每一個字元。各個行業和標準都廣泛支持 Unicode,這使得實現國際化多語言應用程序成為可能。Unicode 可以使用多種字元編碼表示,最常見的是 UTF-8、UTF-16 和 UTF-32。

PHP V6 原生地支持 Unicode (UTF-8),因此它的引擎、擴展和 API 都支持 Unicode。儘管已經添加將所有二進位字元串作為不同類型處理的支持,PHP V6 仍然能夠將字元串作為 Unicode 處理。在 PHP V6 中,字元串的字面量為 Unicode,允許使用 Unicode 標識符,並且它的函數能夠理解 Unicode 文本。PHP V6 能夠在需要時支持 Unicode 字元串和其他編碼之間的轉換,並支持對 UTF-8 文件進行讀寫。下面給出一個從 UTF-8 文件讀取內容的例子:

$input = fopen('inputfile.txt', 'rt');  $str = fread($input, 100); // returns 100 Unicode characters

向 UTF-8 文本文件寫一個 Unicode 字元串 $uni:

$output = fopen('outputfile.txt', 'wt');  fwrite($fp, $uni); // writes out data in UTF-8 encoding

Unicode 模式

在 PHP V5 中,可以根據需求將 Unicode 模式設置為打開或關閉。這表明非 Unicode 和 Unicode 變體類、方法和函數名必須存儲在符號表中,這導致更多的開銷。PHP V6 在 php.ini 中提供一個伺服器通用的配置設置,以啟用或禁用 Unicode 模式。

Opcode 緩存用於緩存已編譯的 PHP 代碼。
伺服器通用的配置使引擎的某個部分的實現更加容易,引起的 opcode 緩存問題更少,並且提高運行速度,因為不需要在運行時轉換符號名。

PHP V6 保留了禁用 Unicode 模式的選項,因為一些字元串函數的 Unicode 實現變慢了 300%,這使整個應用程序的速度變慢 25%。PHP V6 在 php.ini 中提供一個運行時配置選項,用於啟用或禁用 Unicode 語義。默認設置為 on。

unicode.semantics = on           

將 unicode.semantics 設置為 off 並不意味著不使用 Unicode。當設置為 off 時,您仍然可用訪問 Unicode 特性。當 Unicode 語義設置為 off,字元串的字面量是 8 位的字元串;1 個字元等於 1 個位元組。

unicode.semantics = off  $str = "Hello, world!";// ASCII encoding  echo strlen($str);//result is 13

如果設置為 unicode.semantics=on,那麼字元串字面量使用 Unicode 類型。當 Unicode 語義設置為 on 時,一個字元可能 > 1 個位元組。

unicode.semantics = on  $str = "Hello, world!";// Unicode string  echo strlen($str);// result is 13  

PHP V6 中的 unicode.runtime_encoding 配置選項指定在運行時執行 Unicode 和二進位字元串之間的轉換時使用哪種編碼。例如,將運行時編碼設置為 iso-8859-1。

unicode.runtime_encoding = iso-8859-1  

當與尚未支持 Unicode 的函數連接時,仍然需要使用運行時編碼。PHP 腳本可以採用各種編碼方式。PHP V6 提供 unicode.script_encoding 配置選項來指定腳本的編碼。不管腳本的編碼是什麼,生成的字元串字面量都為 Unicode 類型。

 unicode.script_encoding = iso-8859-1  $uni = ""; // Unicode string  unicode.script_encoding = utf-8  $uni = "Atildel"; // also Unicode string  

您還可以將 declare() 語句作為 PHP 腳本的第一個語句,這樣也可以設置腳本的編碼。declare() 構造器覆蓋 php.ini 設置。declare() 設置不會傳播到文件。

 unicode.script_encoding = utf-8  declare(encoding="iso-8859-1");  $uni = "Atildel";// read as ISO-8859-1 string  include "inputfile.php";// file is read as UTF-8  

unicode.output_encoding 配置選項指定標準輸出流所使用的編碼,包括 echo、print 和 var_dump() 函數。輸出流的編碼被即時轉換。unicode.output_encoding 配置選項不影響二進位字元串。

 unicode.output_encoding = utf-8   unicode.script_encoding = iso-8859-1  $unicode = "Atildel"; // Unicode string (from ISO-8859-1)  echo $unicode; // converts $unicode to UTF-8 encoding  echo b"Atildel"; // no conversion, raw contents  

如果啟用了 Unicode 語義,HTTP 輸入必須轉換為 Unicode。GET 請求沒有編碼,並且也很少指定 POST 請求的編碼。PHP V6 提供 unicode.http_input_encoding 配置選項來指定將 HTTP 輸入轉換為哪種 Unicode 編碼。例如,將 HTTP 輸入轉換為 UTF-8:

unicode.http_input_encoding = utf-8 

PHP 將嘗試根據 unicode.http_input_encoding 設置進行解碼。如果解碼失敗,PHP 將使用原始的二進位數據填充請求數組。unicode.filename_encoding 配置選項指定文件系統上文件和目錄名的編碼。

unicode.filename_encoding = utf-8               

當輸入和輸出文件名時,與文件系統相關的函數執行所需的轉換。PHP V6 提供 unicode.fallback_encoding 配置選項來指定 fallback 編碼。

unicode.fallback_encoding = iso-8859-1  

當沒有給其他編碼分配值時,將使用 fallback 編碼。fallback 編碼的默認值是 UTF-8。在 PHP V6 中,您可以使用不同的字元編碼;當啟用 unicode.semantics 選項時,PHP V6 將所有字元串字面量轉換為 Unicode 字元串。您可以無縫地對輸入和輸出使用不同的字元。PHP V6 根據 php.ini 中指定的配置選項對 HTTP 輸入和輸出進行編碼。資料庫和用戶代理程序能夠收到所需的字元編碼,而不需使用任何轉換函數。

您不一定要使用 Unicode 開發腳本來處理和輸出 Unicode,但我們推薦這麼做。如前所述,通過 unicode.script_encoding 配置選項指定腳本編碼。為了在數據中(比如 MySQL)存儲 Unicode 數據,資料庫不需要配置為 UTF-8 編碼,但這樣做比較好。MySQL 資料庫被配置為運行不同的字符集,PHP V6 將以 Unicode 編碼發送查詢,而 MySQL 將嘗試轉換它。

兩種字元串類型

PHP V5 的字元串類型實現有很多字元串類型(二進位、字元串和 Unicode),並且有很多內部引擎函數和幫助函數的實現。PHP V6 只有兩種字元串類型:二進位和 Unicode。unicode.semantics 轉換(switch)決定字元串字面量的默認類型。如果啟用了 unicode.semantics,默認的字元串字面量就為 Unicode。如果禁用該語義轉換,默認字元串字面量的類型就為二進位。您可以顯式地在 Unicode 和二進位字元串類型之間轉換,也可以隱式地進行轉換。使用 unicode.runtime_encoding 配置選項進行隱式轉換。表 1 顯示了如何進行顯式轉換。


表 1. 轉換字元串類型
類型轉換 描述
(binary) 轉換到二進位字元串類型
(unicode) 轉換到 Unicode 字元串類型
(string) 如果 unicode.semantics 設置為 on,就轉換到 Unicode 字元串類型,否則轉換到二進位字元串類型

PHP V6 在內部使用 IS_STRING 表示二進位字元串數據,以及使用 IS_UNICODE 表示 Unicode 字元串數據。

在擴展中支持 Unicode

PHP V6 包含了 Unicode/API,擴展可以藉助它實現 Unicode 支持。需要向擴展模塊結構添加一個標誌,以表明它是否支持 Unicode。如果擴展不支持 Unicode,並且在 PHP 中啟用了 Unicode 語義,那麼在啟動時將不載入它。Unicode 支持被添加到 PHP 數據對象中 (PDO)。

ICU 庫

International Components for Unicode (ICU) 是一組提供 Unicode 和全球化支持的庫。PHP V6 需要使用 ICU,但 ICU 是一個大型的庫,將增加 PHP 的下載體積。PHP 要求使用 ICU V3.4,並且要求發布版提供 ICU 庫。

文件名編碼

不同的文件名可能使用不同的字符集進行編碼。例如,Windows 文件名使用 UTF-16 編碼。filename_encoding 設置指定期望的文件名編碼。當 read 函數(比如 readdir() 和 readfile())遇到其編碼在 filename_encoding 中不存在的文件名時,將返回一個二進位字元串。

緩存校對器

校對器(Collator)用於比較字元串。打開和關閉校對器需要引入開銷。PHP V6 緩存了校對器,但限制存儲在緩存中的對象數量,以防止使用過多的內存。PHP V6 在線程/進程通用緩存中存儲最近打開的 3 個校對器。

基於位置的函數

對於使用系統位置的 PHP 函數,由於位置名在不同的平台中不一致甚至不可用,因此這是一個問題。PHP V6 僅在合適的地方使用基於位置的函數。基於位置的函數包括 strtoupper/strtolower 和 stristr 等。strtoupper 函數將字母表中的字元都轉換為大寫的。“字母表的字元順序” 由當前的位置決定。

字符集轉換錯誤

在字元編碼之間執行轉換可能發生轉換錯誤,因為並不是源字元串中的所有字元都有必要存儲在目標字元串中。PHP V6 為字符集轉換失敗提供一個額外的錯誤模式,它會在失敗時拋出異常。PHP V6 為處理轉換錯誤引入了兩個新的 php.ini 配置選項:unicode.from_error_mode 和 unicode.from_error_subst_char。

unicode.from_error_mode = U_INVALID_SUBSTITUTE  unicode.from_error_subst_char = 3f

unicode.from_error_subst_char 選項為無效的字元串指定了代替字元串的十六進位值;它的默認值是 3f。

unicode.from_error_mode 選項指定錯誤模式,它在遇到無效字元串時採取行動。表 2 顯示了 unicode.from_error_mode 可能使用的值。


表 2. unicode.from_error_mode 值
常量 說明
U_INVALID_STOP 0 遇到第一個無效字元時停止
U_INVALID_SKIP 1 跳過無效字元
U_INVALID_SUBSTITUTE 2 替換無效字元;默認值
U_INVALID_ESCAPE 3 對無效字元進行轉義





刪除了幾個函數

這個小節概述了在 PHP V6 中刪除的幾個函數。

刪除了 register_globals

PHP V5 在 php.ini 中使用 register_globals 配置選項從環境和 HTTP 請求參數定義變數。不過,register_globals 生成不安全的代碼。因此,在 PHP V6 中刪除了 register_globals。

register_globals 生成不安全代碼的方式之一是 authenticate.php,它使用 $auth 變數對用戶進行身份驗證。因為 $auth 沒有被初始化,所以它的值可能通過使用 register_globals 注入變數來定義,比如 GET authenticate.php?auth=1。

<?php  if (authenticated_user()) {      $auth = true;  }  if ($auth) {      include "/data.php";  }  ?>              

register_globals 注入的變數也可能在會話中生成不安全的代碼。看看以下代碼,當設置了 $username 變數時,將在用戶會話中顯示一條歡迎消息。但是,當啟用 register_globals 時,可能會使用 HTTP 請求參數注入 $username 變數。

___FCKpd___14

所有使用 register_globals 的函數都被刪除了,比如 session_register。如果需要導入請求變數,可以使用 import_request_variables。或者使用 $_POST、$_GET、$_COOKIE 和 $_REQUEST 變數。如果設置了 register_globals,PHP V6 將在啟動時拋出 E_CORE_ERROR。

刪除了 magic_quotes

在 PHP V5 中,當啟用了 magic_quotes 配置選項時,它會在輸入數據中自動將所有單引號(')、雙引號(")、反斜杠(\)和 NULL 字元轉義為帶反斜杠的(\)PHP 腳本。Magic Quotes 減少了 SQL 注入(一種能夠篡改 SQL 命令的技術)的風險。Magic Quotes 便於將數據插入到資料庫中。不 使用 Magic Quotes 的理由是考慮到移植性、性能和方便性。

您需要知道是否關閉了 Magic Quotes。如果 Magic Quotes 處於 on,而您認為它處於 off,應用程序就會出現額外的斜杠。如果 Magic Quotes 處於 off,而您認為它處於 on,應用程序就可能遭受 SQL 注入攻擊。Magic Quotes 會損害性能,因為並不是所有轉義數據都被插入到資料庫。一個更好的代替辦法是在運行時使用轉義函數,比如 addslashes。Magic Quotes 可能帶來不便,因為並不是所有數據都需要轉義。可以使用 stripslashes 函數刪除多餘的斜杠。

PHP V6 不再支持 magic_quotes、magic_quotes_sybase 和 magic_quotes_gpc 設置。如果在啟動時發現這些設置,PHP 將發出一個 E_CORE_ERROR。此外,還刪除了 get_magic_quotes_gpc() 函數。

刪除了 safe_mode

在 PHP V5 中,safe_mode 配置選項可用於解決與共享伺服器有關的安全問題。它確保需要打開或包含的文件的用戶必須與執行這些文件的腳本的用戶相同。safe_mode 並不是絕對安全的。

考慮這樣一個場景,一個應用程序使用 Web 伺服器的 ID 並生成緩存文件或映像。如果該應用程序由客戶機用戶載入,PHP 腳本將不能打開緩存文件或映像,因為用戶 ID 不匹配。並且,safe_mode 可以繞過庫。

在 PHP V6 中刪除了 safe_mode 選項。如果檢測到 safe_mode 設置,將拋出 E_CORE_ERROR。open_basedir 配置仍然可用,它限制 PHP 可以在特定目錄樹中打開的文件。

刪除不贊成使用的行為

在 PHP V6 中刪除了一些在早期的 PHP 版本中不贊成使用的行為。allow_call_time_pass_reference 配置指定在運行時通過引用傳遞參數時是否發出警告,它在 PHP V5 中就不推薦使用。在 PHP V6 中刪除了 allow_call_time_pass_reference。

如果要指定哪個參數是通過引用傳遞的,更好的方法是使用聲明函數。在 PHP V6 中,call-time-pass-by-reference 將拋出一個 E_STRICT 錯誤。在 PHP V6 中,“var” 已經成為 “public” 的別名,並且刪除了 E_STRICT 警告。受 "new lt;object-name>" 的影響,也刪除了 return-by-reference。通過引用賦值 “new” 將拋出一個 E_STRICT 錯誤。例如,下面的語句將拋出 E_STRICT 錯誤:

<?php $classA =& new ClassA();?>

刪除了 zend.ze1_compatibility_mode

zend.ze1_compatibility_mode 配置啟用了與 Zend Engine V1 (PHP V4) 的兼容性,它是在 PHP V5 引入的,方便了從 PHP V4 遷移到 PHP V5。

在 PHP V6 中,已經刪除了 zend.ze1_compatibility_mode 特性,如果檢測到該設置,將拋出 E_CORE_ERROR。

刪除了 Freetype 1 和 GD 1 庫

FreeType 1 和 GD 1 是老版本的字體呈現和圖像處理庫。它們不再受到維護,並且已被更新版本的 FreeType 和 GD 代替。在 PHP V6 中,刪除了對 FreeType 1 和 GD 1 庫的支持。

默認情況下不啟用 dl()

dl (string $library) 函數用於在運行時載入 PHP 擴展。在 PHP V5 中,可以在 php.ini 配置文件中啟用或禁用 dl() 函數:enable_dl = On。

dl() 函數會給從未載入過的模塊帶來問題。dl() 函數不能在多線程伺服器中正常工作,比如 IIS 或 Zeus,因為在這些伺服器中會自動禁用它。不過 dl() 函數在 PHP Command Line Interface (CLI) Server Application Programming Interface (SAPI) 中非常有用。

在 PHP V6 中,dl() 函數在默認情況下是禁用的,但並沒有刪除它。SAPI 層可能會顯式地註冊 dl() 函數。

FastCGI 模式

FastCGI 提供很高的性能,如果禁用,將導致雜亂的代碼。在 PHP V6 中不能禁用 FastCGI。

刪除了 register_long_arrays

當啟用 register_long_arrays 配置選項時,將註冊很長的超級全局變數 — $HTTP_*_VARS 變數。$HTTP_*_VARS 變數是在 PHP V5 中為了向後兼容性而引入的,但不是必要的。使用更短的變數 $_GET、$_POST 和 $_SERVER 代替它會更好。在新的 PHP 版本中,register_long_arrays 設置和 $HTTP_*_VARS 沒有得到好評。

在 PHP V6 中,刪除了 register_long_arrays 設置和 $HTTP_*_VARS 全局變數,如果檢測到 register_long_arrays,將拋出 E_CORE_ERROR。

刪除 break $var

動態的 break 操作數不起作用,如以下示例所示:

for (..) { $var = rand(1, 2); break $var; }

在 PHP V6 中,刪除了動態的 break 操作數。取而代之的是,您可以為 $var 分配一個數字,如下所示:

for (..) { $var = rand(1, 2); break 1; }





改進擴展

擴展是 PHP 的主要組件。在 PHP V6 中,有幾個組件得到了改進。

包含在核心發布版中的 XML 擴展

XMLReader 擴展提供一個 XML 解析器,用於閱讀 XML 文件,該解析器在內部基於 SAX 解析。XMLWriter 為寫 XML 文件提供一個 API。XMLReader 和 XMLWriter 使 XML 文件的讀寫更加容易。PHP V5 的核心發布版沒有包含 XMLReader 和 XMLWriter。

PHP V6 將在核心發布版中包含 XMLReader 和 XMLWriter 擴展,並且默認啟用這兩個擴展。

正則表達式擴展

PHP V5.x 為正則表達式提供兩個庫:ereg 和 Perl Compatible Regular Expression (PCRE)。ereg 庫支持 Portable Operating System Interface (POSIX) 正則表達式,而 PCRE 擴展支持與 Perl 兼容的語法。打包的 ereg 庫會造成問題,因此被轉換成擴展並從核心發布版移動到 PHP Extension Community Library (PECL)。

PCRE 擴展提供更多的特性,並且比 ereg 擴展快。PCRE 擴展在默認情況下是啟用的,並且不可以禁用它。一些核心的 PHP 函數使用 POSIX 正則表達式。因為刪除了 ereg 庫,所以這些函數將使用 PCRE 表達式重新編寫。PCRE 表達式提供一些與 ereg 庫等效的函數。


表 3. PCRE 擴展中的等效函數
ereg() 函數 等效的 PCRE 函數
ereg() preg_match()
ereg_replace() preg_replace()

MIME 類型檢查擴展

在 PHP V5 中,mime_magic 擴展用於媒體類型(media-type)檢測,但不是很可靠。PECL 為 MIME 類型檢查提供另一個擴展:Fileinfo。mime_magic 擴展將從核心發布版移動到 PECL。Fileinfo 擴展將添加到核心發布版,並默認啟用。

默認啟用 SOAP 擴展

SOAP 擴展(ext/soap)用於開發使用 Web 服務的 PHP 應用程序,包括 SOAP 伺服器和 SOAP 客戶機。在 PHP V5 中,SOAP 擴展不是默認啟用的;開發人員必須配置 SOAP 擴展。在 PHP V6 中,默認啟用 SOAP 擴展。PHP V6 還實現一些安全擴展。





引擎的添加內容

在 PHP V6,將添加 64 位的整數,同時保留 32 位整數。64 位引擎的轉換名為 int64。將使用一個靜態標籤擴展 break 關鍵字。將從 ?: 操作符丟棄中間參數。例如,在下面的表達式中,如果 $_GET['var'] 計算為 true,則 $var 設置為 3。如果 $_GET['var'] 計算為 false 或沒有設置,則 $var 設置為 $_GET['var']。

___FCKpd___18

如果 $_GET['var'] 沒有設置,將拋出 E_NOTICE。PHP V6 將規定對多維數組使用 foreach 語法。

<?php  $a = array(array(1, 2), array(3, 4));  foreach( $a as $k => list($a, $b)) {}  ?>

在 PHP V5 中,{} 和 [] 都可用於訪問字元串和數組元素中的字元。在 PHP V6 中,將刪除 {},並且繼續使用 [],而 [] 操作符將支持 substr()/array_slice() 函數。在 PHP V6 中,microtime() 在默認情況下返回一個浮點值。





OO 函數

在 PHP V6 中對 OO 函數進行了一些改進。添加了關鍵字 static:: 用於延遲靜態綁定,這意味著將執行運行時靜態數字計算。

支持名稱空間

PHP V5 不支持名稱空間,而是在一個全局名稱空間中定義所有函數和變數。PHP V6 通過關鍵字 namespace 添加對名稱空間的支持。為了定義一個已經定義的類名或函數名,必須使用名稱空間將新的類或函數與已經存在的類或函數區分開來。XMLReader 是一個已經存在的類,但是假設您仍然想定義另一個 XMLReader。您應該這樣定義 XMLReader 類:

<?php  namespace XmlNamespace {       class XMLReader {     }}  $reader = new XmlNamespace\XMLReader();  $reader2= new XMLReader();  ?>

為了在 XmlNamespace 中調用 XMLReader 類,需要使用前綴 XmlNamespace\。名稱空間中可以包含類和函數,但不能包含變數。

支持類型提示返回值

PHP V5 僅支持類型提示(其中定義了類型)參數。PHP V6 支持類型提示返回值。

靜態和動態方法調用

在 PHP V5 中,可以對方法進行靜態或動態調用,而不管它是否標記為 static。例如,在下面的清單中,進行了靜態和動態方法的調用:

<?php   class classA {       static function aStatic() { echo "static function\n"; }         function bDynamic() { echo "dynamic function\n"; }}  classA::aStatic("static call");  classA::bDynamic("static call");  $classA = new classA;  $classA->aStatic("dynamic call");  $classA->bDynamic("dynamic call");  ?>

在 PHP V6 中,使用靜態調用語法調用動態函數將拋出一個 E_FATAL 錯誤,反之亦然。





PHP 的添加內容

opcode 緩存改善了性能。另一個 PHP cache(APC)擴展曾經使用過一段時間,它也將添加到核心 PHP 發布版。默認情況下將不啟用 APC 擴展。提供其他安全性的 Hardened PHP 補丁的一些特性已經合併到 PHP。

現在,許多 PHP 擴展甚至對可修復錯誤使用 E_ERROR。E_ERROR 終止腳本的運行。因此,在 PHP V6 中,擴展中僅對不可修復的錯誤使用 E_ERROR。E_STRICT 錯誤表明這是語言級別的警告或錯誤,目前還沒有包含在 E_ALL 中。在 PHP V6 中,已經將 E_STRICT 添加到 E_ALL。在 PHP V6 中,將為 PHP 添加 MySQL 原生驅動器。並且添加對大於 2 GB 的文件的支持。

在 PHP V6 中,將刪除 ASP 樣式的標記 (<% %>)。但會保留 PHP 短標記 (<? ?>)。





結束語

本文介紹了 PHP V6 中的新特性和已更改的特性。其中最主要的特性就是對 Unicode 的支持。刪除了一些配置選項,比如 register_globals、magic_quotes、safe_mode 和 register_long_arrays。改進了擴展支持和 OO 函數。PHP V5.3 支持 PHP V6 的 50% 的特性。(責任編輯:A6)

SESSION['username'])) { echo "Welcome {
本文詳細闡述 PHP V6 中的新特性。了解為什麼它更加容易使用、更加安全和更加適合國際化。新的特性包括增強對 Unicode 的支持、刪除了幾個函數、改進擴展、引擎添加內容、OO 函數的改變和 PHP 擴展。

簡介

“PHP 的特性” 簡單介紹了 PHP V6 中的新特性。在本文中,了解這些讓 PHP V6 更加容易使用、更加安全和更加適合國際化的新特性。本文探索改進的 Unicode 支持,刪除了幾個函數、改進的擴展、引擎添加內容、改進的面向對象函數和 PHP V6 中的一些擴展。





增強對 Unicode 的支持

PHP V6 中的主要特性是增強對 Unicode 的支持。目前,PHP 實際上是一個二進位處理器。PHP V5 沒有提供原生的 Unicode 支持;它假定所有字元的長度都為 1 位元組,這在處理非拉丁字元時會出現問題。您可以轉換到 Unicode,但需要使用 mbstring 擴展,而默認的 PHP V5 或外部工具(比如 iconv)都不支持該擴展。

PHP V5 有時不能正確顯示文本,這取決於字元編碼。Unicode 是由 Unicode Consortium 開發的行業標準,它能表示所有語言、程序和平台上的每一個字元。各個行業和標準都廣泛支持 Unicode,這使得實現國際化多語言應用程序成為可能。Unicode 可以使用多種字元編碼表示,最常見的是 UTF-8、UTF-16 和 UTF-32。

PHP V6 原生地支持 Unicode (UTF-8),因此它的引擎、擴展和 API 都支持 Unicode。儘管已經添加將所有二進位字元串作為不同類型處理的支持,PHP V6 仍然能夠將字元串作為 Unicode 處理。在 PHP V6 中,字元串的字面量為 Unicode,允許使用 Unicode 標識符,並且它的函數能夠理解 Unicode 文本。PHP V6 能夠在需要時支持 Unicode 字元串和其他編碼之間的轉換,並支持對 UTF-8 文件進行讀寫。下面給出一個從 UTF-8 文件讀取內容的例子:

$input = fopen('inputfile.txt', 'rt');  $str = fread($input, 100); // returns 100 Unicode characters

向 UTF-8 文本文件寫一個 Unicode 字元串 $uni:

$output = fopen('outputfile.txt', 'wt');  fwrite($fp, $uni); // writes out data in UTF-8 encoding

Unicode 模式

在 PHP V5 中,可以根據需求將 Unicode 模式設置為打開或關閉。這表明非 Unicode 和 Unicode 變體類、方法和函數名必須存儲在符號表中,這導致更多的開銷。PHP V6 在 php.ini 中提供一個伺服器通用的配置設置,以啟用或禁用 Unicode 模式。

Opcode 緩存用於緩存已編譯的 PHP 代碼。
伺服器通用的配置使引擎的某個部分的實現更加容易,引起的 opcode 緩存問題更少,並且提高運行速度,因為不需要在運行時轉換符號名。

PHP V6 保留了禁用 Unicode 模式的選項,因為一些字元串函數的 Unicode 實現變慢了 300%,這使整個應用程序的速度變慢 25%。PHP V6 在 php.ini 中提供一個運行時配置選項,用於啟用或禁用 Unicode 語義。默認設置為 on。

unicode.semantics = on           

將 unicode.semantics 設置為 off 並不意味著不使用 Unicode。當設置為 off 時,您仍然可用訪問 Unicode 特性。當 Unicode 語義設置為 off,字元串的字面量是 8 位的字元串;1 個字元等於 1 個位元組。

unicode.semantics = off  $str = "Hello, world!";// ASCII encoding  echo strlen($str);//result is 13

如果設置為 unicode.semantics=on,那麼字元串字面量使用 Unicode 類型。當 Unicode 語義設置為 on 時,一個字元可能 > 1 個位元組。

unicode.semantics = on  $str = "Hello, world!";// Unicode string  echo strlen($str);// result is 13  

PHP V6 中的 unicode.runtime_encoding 配置選項指定在運行時執行 Unicode 和二進位字元串之間的轉換時使用哪種編碼。例如,將運行時編碼設置為 iso-8859-1。

unicode.runtime_encoding = iso-8859-1  

當與尚未支持 Unicode 的函數連接時,仍然需要使用運行時編碼。PHP 腳本可以採用各種編碼方式。PHP V6 提供 unicode.script_encoding 配置選項來指定腳本的編碼。不管腳本的編碼是什麼,生成的字元串字面量都為 Unicode 類型。

 unicode.script_encoding = iso-8859-1  $uni = ""; // Unicode string  unicode.script_encoding = utf-8  $uni = "Atildel"; // also Unicode string  

您還可以將 declare() 語句作為 PHP 腳本的第一個語句,這樣也可以設置腳本的編碼。declare() 構造器覆蓋 php.ini 設置。declare() 設置不會傳播到文件。

 unicode.script_encoding = utf-8  declare(encoding="iso-8859-1");  $uni = "Atildel";// read as ISO-8859-1 string  include "inputfile.php";// file is read as UTF-8  

unicode.output_encoding 配置選項指定標準輸出流所使用的編碼,包括 echo、print 和 var_dump() 函數。輸出流的編碼被即時轉換。unicode.output_encoding 配置選項不影響二進位字元串。

 unicode.output_encoding = utf-8   unicode.script_encoding = iso-8859-1  $unicode = "Atildel"; // Unicode string (from ISO-8859-1)  echo $unicode; // converts $unicode to UTF-8 encoding  echo b"Atildel"; // no conversion, raw contents  

如果啟用了 Unicode 語義,HTTP 輸入必須轉換為 Unicode。GET 請求沒有編碼,並且也很少指定 POST 請求的編碼。PHP V6 提供 unicode.http_input_encoding 配置選項來指定將 HTTP 輸入轉換為哪種 Unicode 編碼。例如,將 HTTP 輸入轉換為 UTF-8:

unicode.http_input_encoding = utf-8 

PHP 將嘗試根據 unicode.http_input_encoding 設置進行解碼。如果解碼失敗,PHP 將使用原始的二進位數據填充請求數組。unicode.filename_encoding 配置選項指定文件系統上文件和目錄名的編碼。

unicode.filename_encoding = utf-8               

當輸入和輸出文件名時,與文件系統相關的函數執行所需的轉換。PHP V6 提供 unicode.fallback_encoding 配置選項來指定 fallback 編碼。

unicode.fallback_encoding = iso-8859-1  

當沒有給其他編碼分配值時,將使用 fallback 編碼。fallback 編碼的默認值是 UTF-8。在 PHP V6 中,您可以使用不同的字元編碼;當啟用 unicode.semantics 選項時,PHP V6 將所有字元串字面量轉換為 Unicode 字元串。您可以無縫地對輸入和輸出使用不同的字元。PHP V6 根據 php.ini 中指定的配置選項對 HTTP 輸入和輸出進行編碼。資料庫和用戶代理程序能夠收到所需的字元編碼,而不需使用任何轉換函數。

您不一定要使用 Unicode 開發腳本來處理和輸出 Unicode,但我們推薦這麼做。如前所述,通過 unicode.script_encoding 配置選項指定腳本編碼。為了在數據中(比如 MySQL)存儲 Unicode 數據,資料庫不需要配置為 UTF-8 編碼,但這樣做比較好。MySQL 資料庫被配置為運行不同的字符集,PHP V6 將以 Unicode 編碼發送查詢,而 MySQL 將嘗試轉換它。

兩種字元串類型

PHP V5 的字元串類型實現有很多字元串類型(二進位、字元串和 Unicode),並且有很多內部引擎函數和幫助函數的實現。PHP V6 只有兩種字元串類型:二進位和 Unicode。unicode.semantics 轉換(switch)決定字元串字面量的默認類型。如果啟用了 unicode.semantics,默認的字元串字面量就為 Unicode。如果禁用該語義轉換,默認字元串字面量的類型就為二進位。您可以顯式地在 Unicode 和二進位字元串類型之間轉換,也可以隱式地進行轉換。使用 unicode.runtime_encoding 配置選項進行隱式轉換。表 1 顯示了如何進行顯式轉換。


表 1. 轉換字元串類型
類型轉換 描述
(binary) 轉換到二進位字元串類型
(unicode) 轉換到 Unicode 字元串類型
(string) 如果 unicode.semantics 設置為 on,就轉換到 Unicode 字元串類型,否則轉換到二進位字元串類型

PHP V6 在內部使用 IS_STRING 表示二進位字元串數據,以及使用 IS_UNICODE 表示 Unicode 字元串數據。

在擴展中支持 Unicode

PHP V6 包含了 Unicode/API,擴展可以藉助它實現 Unicode 支持。需要向擴展模塊結構添加一個標誌,以表明它是否支持 Unicode。如果擴展不支持 Unicode,並且在 PHP 中啟用了 Unicode 語義,那麼在啟動時將不載入它。Unicode 支持被添加到 PHP 數據對象中 (PDO)。

ICU 庫

International Components for Unicode (ICU) 是一組提供 Unicode 和全球化支持的庫。PHP V6 需要使用 ICU,但 ICU 是一個大型的庫,將增加 PHP 的下載體積。PHP 要求使用 ICU V3.4,並且要求發布版提供 ICU 庫。

文件名編碼

不同的文件名可能使用不同的字符集進行編碼。例如,Windows 文件名使用 UTF-16 編碼。filename_encoding 設置指定期望的文件名編碼。當 read 函數(比如 readdir() 和 readfile())遇到其編碼在 filename_encoding 中不存在的文件名時,將返回一個二進位字元串。

緩存校對器

校對器(Collator)用於比較字元串。打開和關閉校對器需要引入開銷。PHP V6 緩存了校對器,但限制存儲在緩存中的對象數量,以防止使用過多的內存。PHP V6 在線程/進程通用緩存中存儲最近打開的 3 個校對器。

基於位置的函數

對於使用系統位置的 PHP 函數,由於位置名在不同的平台中不一致甚至不可用,因此這是一個問題。PHP V6 僅在合適的地方使用基於位置的函數。基於位置的函數包括 strtoupper/strtolower 和 stristr 等。strtoupper 函數將字母表中的字元都轉換為大寫的。“字母表的字元順序” 由當前的位置決定。

字符集轉換錯誤

在字元編碼之間執行轉換可能發生轉換錯誤,因為並不是源字元串中的所有字元都有必要存儲在目標字元串中。PHP V6 為字符集轉換失敗提供一個額外的錯誤模式,它會在失敗時拋出異常。PHP V6 為處理轉換錯誤引入了兩個新的 php.ini 配置選項:unicode.from_error_mode 和 unicode.from_error_subst_char。

unicode.from_error_mode = U_INVALID_SUBSTITUTE  unicode.from_error_subst_char = 3f

unicode.from_error_subst_char 選項為無效的字元串指定了代替字元串的十六進位值;它的默認值是 3f。

unicode.from_error_mode 選項指定錯誤模式,它在遇到無效字元串時採取行動。表 2 顯示了 unicode.from_error_mode 可能使用的值。


表 2. unicode.from_error_mode 值
常量 說明
U_INVALID_STOP 0 遇到第一個無效字元時停止
U_INVALID_SKIP 1 跳過無效字元
U_INVALID_SUBSTITUTE 2 替換無效字元;默認值
U_INVALID_ESCAPE 3 對無效字元進行轉義





刪除了幾個函數

這個小節概述了在 PHP V6 中刪除的幾個函數。

刪除了 register_globals

PHP V5 在 php.ini 中使用 register_globals 配置選項從環境和 HTTP 請求參數定義變數。不過,register_globals 生成不安全的代碼。因此,在 PHP V6 中刪除了 register_globals。

register_globals 生成不安全代碼的方式之一是 authenticate.php,它使用 $auth 變數對用戶進行身份驗證。因為 $auth 沒有被初始化,所以它的值可能通過使用 register_globals 注入變數來定義,比如 GET authenticate.php?auth=1。

<?php  if (authenticated_user()) {      $auth = true;  }  if ($auth) {      include "/data.php";  }  ?>              

register_globals 注入的變數也可能在會話中生成不安全的代碼。看看以下代碼,當設置了 $username 變數時,將在用戶會話中顯示一條歡迎消息。但是,當啟用 register_globals 時,可能會使用 HTTP 請求參數注入 $username 變數。

___FCKpd___14

所有使用 register_globals 的函數都被刪除了,比如 session_register。如果需要導入請求變數,可以使用 import_request_variables。或者使用 $_POST、$_GET、$_COOKIE 和 $_REQUEST 變數。如果設置了 register_globals,PHP V6 將在啟動時拋出 E_CORE_ERROR。

刪除了 magic_quotes

在 PHP V5 中,當啟用了 magic_quotes 配置選項時,它會在輸入數據中自動將所有單引號(')、雙引號(")、反斜杠(\)和 NULL 字元轉義為帶反斜杠的(\)PHP 腳本。Magic Quotes 減少了 SQL 注入(一種能夠篡改 SQL 命令的技術)的風險。Magic Quotes 便於將數據插入到資料庫中。不 使用 Magic Quotes 的理由是考慮到移植性、性能和方便性。

您需要知道是否關閉了 Magic Quotes。如果 Magic Quotes 處於 on,而您認為它處於 off,應用程序就會出現額外的斜杠。如果 Magic Quotes 處於 off,而您認為它處於 on,應用程序就可能遭受 SQL 注入攻擊。Magic Quotes 會損害性能,因為並不是所有轉義數據都被插入到資料庫。一個更好的代替辦法是在運行時使用轉義函數,比如 addslashes。Magic Quotes 可能帶來不便,因為並不是所有數據都需要轉義。可以使用 stripslashes 函數刪除多餘的斜杠。

PHP V6 不再支持 magic_quotes、magic_quotes_sybase 和 magic_quotes_gpc 設置。如果在啟動時發現這些設置,PHP 將發出一個 E_CORE_ERROR。此外,還刪除了 get_magic_quotes_gpc() 函數。

刪除了 safe_mode

在 PHP V5 中,safe_mode 配置選項可用於解決與共享伺服器有關的安全問題。它確保需要打開或包含的文件的用戶必須與執行這些文件的腳本的用戶相同。safe_mode 並不是絕對安全的。

考慮這樣一個場景,一個應用程序使用 Web 伺服器的 ID 並生成緩存文件或映像。如果該應用程序由客戶機用戶載入,PHP 腳本將不能打開緩存文件或映像,因為用戶 ID 不匹配。並且,safe_mode 可以繞過庫。

在 PHP V6 中刪除了 safe_mode 選項。如果檢測到 safe_mode 設置,將拋出 E_CORE_ERROR。open_basedir 配置仍然可用,它限制 PHP 可以在特定目錄樹中打開的文件。

刪除不贊成使用的行為

在 PHP V6 中刪除了一些在早期的 PHP 版本中不贊成使用的行為。allow_call_time_pass_reference 配置指定在運行時通過引用傳遞參數時是否發出警告,它在 PHP V5 中就不推薦使用。在 PHP V6 中刪除了 allow_call_time_pass_reference。

如果要指定哪個參數是通過引用傳遞的,更好的方法是使用聲明函數。在 PHP V6 中,call-time-pass-by-reference 將拋出一個 E_STRICT 錯誤。在 PHP V6 中,“var” 已經成為 “public” 的別名,並且刪除了 E_STRICT 警告。受 "new lt;object-name>" 的影響,也刪除了 return-by-reference。通過引用賦值 “new” 將拋出一個 E_STRICT 錯誤。例如,下面的語句將拋出 E_STRICT 錯誤:

___FCKpd___15

刪除了 zend.ze1_compatibility_mode

zend.ze1_compatibility_mode 配置啟用了與 Zend Engine V1 (PHP V4) 的兼容性,它是在 PHP V5 引入的,方便了從 PHP V4 遷移到 PHP V5。

在 PHP V6 中,已經刪除了 zend.ze1_compatibility_mode 特性,如果檢測到該設置,將拋出 E_CORE_ERROR。

刪除了 Freetype 1 和 GD 1 庫

FreeType 1 和 GD 1 是老版本的字體呈現和圖像處理庫。它們不再受到維護,並且已被更新版本的 FreeType 和 GD 代替。在 PHP V6 中,刪除了對 FreeType 1 和 GD 1 庫的支持。

默認情況下不啟用 dl()

dl (string $library) 函數用於在運行時載入 PHP 擴展。在 PHP V5 中,可以在 php.ini 配置文件中啟用或禁用 dl() 函數:enable_dl = On。

dl() 函數會給從未載入過的模塊帶來問題。dl() 函數不能在多線程伺服器中正常工作,比如 IIS 或 Zeus,因為在這些伺服器中會自動禁用它。不過 dl() 函數在 PHP Command Line Interface (CLI) Server Application Programming Interface (SAPI) 中非常有用。

在 PHP V6 中,dl() 函數在默認情況下是禁用的,但並沒有刪除它。SAPI 層可能會顯式地註冊 dl() 函數。

FastCGI 模式

FastCGI 提供很高的性能,如果禁用,將導致雜亂的代碼。在 PHP V6 中不能禁用 FastCGI。

刪除了 register_long_arrays

當啟用 register_long_arrays 配置選項時,將註冊很長的超級全局變數 — $HTTP_*_VARS 變數。$HTTP_*_VARS 變數是在 PHP V5 中為了向後兼容性而引入的,但不是必要的。使用更短的變數 $_GET、$_POST 和 $_SERVER 代替它會更好。在新的 PHP 版本中,register_long_arrays 設置和 $HTTP_*_VARS 沒有得到好評。

在 PHP V6 中,刪除了 register_long_arrays 設置和 $HTTP_*_VARS 全局變數,如果檢測到 register_long_arrays,將拋出 E_CORE_ERROR。

刪除 break $var

動態的 break 操作數不起作用,如以下示例所示:

___FCKpd___16

在 PHP V6 中,刪除了動態的 break 操作數。取而代之的是,您可以為 $var 分配一個數字,如下所示:

___FCKpd___17





改進擴展

擴展是 PHP 的主要組件。在 PHP V6 中,有幾個組件得到了改進。

包含在核心發布版中的 XML 擴展

XMLReader 擴展提供一個 XML 解析器,用於閱讀 XML 文件,該解析器在內部基於 SAX 解析。XMLWriter 為寫 XML 文件提供一個 API。XMLReader 和 XMLWriter 使 XML 文件的讀寫更加容易。PHP V5 的核心發布版沒有包含 XMLReader 和 XMLWriter。

PHP V6 將在核心發布版中包含 XMLReader 和 XMLWriter 擴展,並且默認啟用這兩個擴展。

正則表達式擴展

PHP V5.x 為正則表達式提供兩個庫:ereg 和 Perl Compatible Regular Expression (PCRE)。ereg 庫支持 Portable Operating System Interface (POSIX) 正則表達式,而 PCRE 擴展支持與 Perl 兼容的語法。打包的 ereg 庫會造成問題,因此被轉換成擴展並從核心發布版移動到 PHP Extension Community Library (PECL)。

PCRE 擴展提供更多的特性,並且比 ereg 擴展快。PCRE 擴展在默認情況下是啟用的,並且不可以禁用它。一些核心的 PHP 函數使用 POSIX 正則表達式。因為刪除了 ereg 庫,所以這些函數將使用 PCRE 表達式重新編寫。PCRE 表達式提供一些與 ereg 庫等效的函數。


表 3. PCRE 擴展中的等效函數
ereg() 函數 等效的 PCRE 函數
ereg() preg_match()
ereg_replace() preg_replace()

MIME 類型檢查擴展

在 PHP V5 中,mime_magic 擴展用於媒體類型(media-type)檢測,但不是很可靠。PECL 為 MIME 類型檢查提供另一個擴展:Fileinfo。mime_magic 擴展將從核心發布版移動到 PECL。Fileinfo 擴展將添加到核心發布版,並默認啟用。

默認啟用 SOAP 擴展

SOAP 擴展(ext/soap)用於開發使用 Web 服務的 PHP 應用程序,包括 SOAP 伺服器和 SOAP 客戶機。在 PHP V5 中,SOAP 擴展不是默認啟用的;開發人員必須配置 SOAP 擴展。在 PHP V6 中,默認啟用 SOAP 擴展。PHP V6 還實現一些安全擴展。





引擎的添加內容

在 PHP V6,將添加 64 位的整數,同時保留 32 位整數。64 位引擎的轉換名為 int64。將使用一個靜態標籤擴展 break 關鍵字。將從 ?: 操作符丟棄中間參數。例如,在下面的表達式中,如果 $_GET['var'] 計算為 true,則 $var 設置為 3。如果 $_GET['var'] 計算為 false 或沒有設置,則 $var 設置為 $_GET['var']。

___FCKpd___18

如果 $_GET['var'] 沒有設置,將拋出 E_NOTICE。PHP V6 將規定對多維數組使用 foreach 語法。

___FCKpd___19

在 PHP V5 中,{} 和 [] 都可用於訪問字元串和數組元素中的字元。在 PHP V6 中,將刪除 {},並且繼續使用 [],而 [] 操作符將支持 substr()/array_slice() 函數。在 PHP V6 中,microtime() 在默認情況下返回一個浮點值。





OO 函數

在 PHP V6 中對 OO 函數進行了一些改進。添加了關鍵字 static:: 用於延遲靜態綁定,這意味著將執行運行時靜態數字計算。

支持名稱空間

PHP V5 不支持名稱空間,而是在一個全局名稱空間中定義所有函數和變數。PHP V6 通過關鍵字 namespace 添加對名稱空間的支持。為了定義一個已經定義的類名或函數名,必須使用名稱空間將新的類或函數與已經存在的類或函數區分開來。XMLReader 是一個已經存在的類,但是假設您仍然想定義另一個 XMLReader。您應該這樣定義 XMLReader 類:

___FCKpd___20

為了在 XmlNamespace 中調用 XMLReader 類,需要使用前綴 XmlNamespace\。名稱空間中可以包含類和函數,但不能包含變數。

支持類型提示返回值

PHP V5 僅支持類型提示(其中定義了類型)參數。PHP V6 支持類型提示返回值。

靜態和動態方法調用

在 PHP V5 中,可以對方法進行靜態或動態調用,而不管它是否標記為 static。例如,在下面的清單中,進行了靜態和動態方法的調用:

___FCKpd___21

在 PHP V6 中,使用靜態調用語法調用動態函數將拋出一個 E_FATAL 錯誤,反之亦然。





PHP 的添加內容

opcode 緩存改善了性能。另一個 PHP cache(APC)擴展曾經使用過一段時間,它也將添加到核心 PHP 發布版。默認情況下將不啟用 APC 擴展。提供其他安全性的 Hardened PHP 補丁的一些特性已經合併到 PHP。

現在,許多 PHP 擴展甚至對可修復錯誤使用 E_ERROR。E_ERROR 終止腳本的運行。因此,在 PHP V6 中,擴展中僅對不可修復的錯誤使用 E_ERROR。E_STRICT 錯誤表明這是語言級別的警告或錯誤,目前還沒有包含在 E_ALL 中。在 PHP V6 中,已經將 E_STRICT 添加到 E_ALL。在 PHP V6 中,將為 PHP 添加 MySQL 原生驅動器。並且添加對大於 2 GB 的文件的支持。

在 PHP V6 中,將刪除 ASP 樣式的標記 (<% %>)。但會保留 PHP 短標記 (<? ?>)。





結束語

本文介紹了 PHP V6 中的新特性和已更改的特性。其中最主要的特性就是對 Unicode 的支持。刪除了一些配置選項,比如 register_globals、magic_quotes、safe_mode 和 register_long_arrays。改進了擴展支持和 OO 函數。PHP V5.3 支持 PHP V6 的 50% 的特性。(責任編輯:A6)

SESSION['username']}"; } else { echo "Welcome Guest"; } ?>

所有使用 register_globals 的函數都被刪除了,比如 session_register。如果需要導入請求變數,可以使用 import_request_variables。或者使用 $_POST、$_GET、$_COOKIE 和 $_REQUEST 變數。如果設置了 register_globals,PHP V6 將在啟動時拋出 E_CORE_ERROR。

刪除了 magic_quotes

在 PHP V5 中,當啟用了 magic_quotes 配置選項時,它會在輸入數據中自動將所有單引號(')、雙引號(")、反斜杠(\)和 NULL 字元轉義為帶反斜杠的(\)PHP 腳本。Magic Quotes 減少了 SQL 注入(一種能夠篡改 SQL 命令的技術)的風險。Magic Quotes 便於將數據插入到資料庫中。不 使用 Magic Quotes 的理由是考慮到移植性、性能和方便性。

您需要知道是否關閉了 Magic Quotes。如果 Magic Quotes 處於 on,而您認為它處於 off,應用程序就會出現額外的斜杠。如果 Magic Quotes 處於 off,而您認為它處於 on,應用程序就可能遭受 SQL 注入攻擊。Magic Quotes 會損害性能,因為並不是所有轉義數據都被插入到資料庫。一個更好的代替辦法是在運行時使用轉義函數,比如 addslashes。Magic Quotes 可能帶來不便,因為並不是所有數據都需要轉義。可以使用 stripslashes 函數刪除多餘的斜杠。

PHP V6 不再支持 magic_quotes、magic_quotes_sybase 和 magic_quotes_gpc 設置。如果在啟動時發現這些設置,PHP 將發出一個 E_CORE_ERROR。此外,還刪除了 get_magic_quotes_gpc() 函數。

刪除了 safe_mode

在 PHP V5 中,safe_mode 配置選項可用於解決與共享伺服器有關的安全問題。它確保需要打開或包含的文件的用戶必須與執行這些文件的腳本的用戶相同。safe_mode 並不是絕對安全的。

考慮這樣一個場景,一個應用程序使用 Web 伺服器的 ID 並生成緩存文件或映像。如果該應用程序由客戶機用戶載入,PHP 腳本將不能打開緩存文件或映像,因為用戶 ID 不匹配。並且,safe_mode 可以繞過庫。

在 PHP V6 中刪除了 safe_mode 選項。如果檢測到 safe_mode 設置,將拋出 E_CORE_ERROR。open_basedir 配置仍然可用,它限制 PHP 可以在特定目錄樹中打開的文件。

刪除不贊成使用的行為

在 PHP V6 中刪除了一些在早期的 PHP 版本中不贊成使用的行為。allow_call_time_pass_reference 配置指定在運行時通過引用傳遞參數時是否發出警告,它在 PHP V5 中就不推薦使用。在 PHP V6 中刪除了 allow_call_time_pass_reference。

如果要指定哪個參數是通過引用傳遞的,更好的方法是使用聲明函數。在 PHP V6 中,call-time-pass-by-reference 將拋出一個 E_STRICT 錯誤。在 PHP V6 中,“var” 已經成為 “public” 的別名,並且刪除了 E_STRICT 警告。受 "new lt;object-name>" 的影響,也刪除了 return-by-reference。通過引用賦值 “new” 將拋出一個 E_STRICT 錯誤。例如,下面的語句將拋出 E_STRICT 錯誤:

___FCKpd___15

刪除了 zend.ze1_compatibility_mode

zend.ze1_compatibility_mode 配置啟用了與 Zend Engine V1 (PHP V4) 的兼容性,它是在 PHP V5 引入的,方便了從 PHP V4 遷移到 PHP V5。

在 PHP V6 中,已經刪除了 zend.ze1_compatibility_mode 特性,如果檢測到該設置,將拋出 E_CORE_ERROR。

刪除了 Freetype 1 和 GD 1 庫

FreeType 1 和 GD 1 是老版本的字體呈現和圖像處理庫。它們不再受到維護,並且已被更新版本的 FreeType 和 GD 代替。在 PHP V6 中,刪除了對 FreeType 1 和 GD 1 庫的支持。

默認情況下不啟用 dl()

dl (string $library) 函數用於在運行時載入 PHP 擴展。在 PHP V5 中,可以在 php.ini 配置文件中啟用或禁用 dl() 函數:enable_dl = On。

dl() 函數會給從未載入過的模塊帶來問題。dl() 函數不能在多線程伺服器中正常工作,比如 IIS 或 Zeus,因為在這些伺服器中會自動禁用它。不過 dl() 函數在 PHP Command Line Interface (CLI) Server Application Programming Interface (SAPI) 中非常有用。

在 PHP V6 中,dl() 函數在默認情況下是禁用的,但並沒有刪除它。SAPI 層可能會顯式地註冊 dl() 函數。

FastCGI 模式

FastCGI 提供很高的性能,如果禁用,將導致雜亂的代碼。在 PHP V6 中不能禁用 FastCGI。

刪除了 register_long_arrays

當啟用 register_long_arrays 配置選項時,將註冊很長的超級全局變數 — $HTTP_*_VARS 變數。$HTTP_*_VARS 變數是在 PHP V5 中為了向後兼容性而引入的,但不是必要的。使用更短的變數 $_GET、$_POST 和 $_SERVER 代替它會更好。在新的 PHP 版本中,register_long_arrays 設置和 $HTTP_*_VARS 沒有得到好評。

在 PHP V6 中,刪除了 register_long_arrays 設置和 $HTTP_*_VARS 全局變數,如果檢測到 register_long_arrays,將拋出 E_CORE_ERROR。

刪除 break $var

動態的 break 操作數不起作用,如以下示例所示:

___FCKpd___16

在 PHP V6 中,刪除了動態的 break 操作數。取而代之的是,您可以為 $var 分配一個數字,如下所示:

___FCKpd___17





改進擴展

擴展是 PHP 的主要組件。在 PHP V6 中,有幾個組件得到了改進。

包含在核心發布版中的 XML 擴展

XMLReader 擴展提供一個 XML 解析器,用於閱讀 XML 文件,該解析器在內部基於 SAX 解析。XMLWriter 為寫 XML 文件提供一個 API。XMLReader 和 XMLWriter 使 XML 文件的讀寫更加容易。PHP V5 的核心發布版沒有包含 XMLReader 和 XMLWriter。

PHP V6 將在核心發布版中包含 XMLReader 和 XMLWriter 擴展,並且默認啟用這兩個擴展。

正則表達式擴展

PHP V5.x 為正則表達式提供兩個庫:ereg 和 Perl Compatible Regular Expression (PCRE)。ereg 庫支持 Portable Operating System Interface (POSIX) 正則表達式,而 PCRE 擴展支持與 Perl 兼容的語法。打包的 ereg 庫會造成問題,因此被轉換成擴展並從核心發布版移動到 PHP Extension Community Library (PECL)。

PCRE 擴展提供更多的特性,並且比 ereg 擴展快。PCRE 擴展在默認情況下是啟用的,並且不可以禁用它。一些核心的 PHP 函數使用 POSIX 正則表達式。因為刪除了 ereg 庫,所以這些函數將使用 PCRE 表達式重新編寫。PCRE 表達式提供一些與 ereg 庫等效的函數。


表 3. PCRE 擴展中的等效函數
ereg() 函數 等效的 PCRE 函數
ereg() preg_match()
ereg_replace() preg_replace()

MIME 類型檢查擴展

在 PHP V5 中,mime_magic 擴展用於媒體類型(media-type)檢測,但不是很可靠。PECL 為 MIME 類型檢查提供另一個擴展:Fileinfo。mime_magic 擴展將從核心發布版移動到 PECL。Fileinfo 擴展將添加到核心發布版,並默認啟用。

默認啟用 SOAP 擴展

SOAP 擴展(ext/soap)用於開發使用 Web 服務的 PHP 應用程序,包括 SOAP 伺服器和 SOAP 客戶機。在 PHP V5 中,SOAP 擴展不是默認啟用的;開發人員必須配置 SOAP 擴展。在 PHP V6 中,默認啟用 SOAP 擴展。PHP V6 還實現一些安全擴展。





引擎的添加內容

在 PHP V6,將添加 64 位的整數,同時保留 32 位整數。64 位引擎的轉換名為 int64。將使用一個靜態標籤擴展 break 關鍵字。將從 ?: 操作符丟棄中間參數。例如,在下面的表達式中,如果 $_GET['var'] 計算為 true,則 $var 設置為 3。如果 $_GET['var'] 計算為 false 或沒有設置,則 $var 設置為 $_GET['var']。

___FCKpd___18

如果 $_GET['var'] 沒有設置,將拋出 E_NOTICE。PHP V6 將規定對多維數組使用 foreach 語法。

___FCKpd___19

在 PHP V5 中,{} 和 [] 都可用於訪問字元串和數組元素中的字元。在 PHP V6 中,將刪除 {},並且繼續使用 [],而 [] 操作符將支持 substr()/array_slice() 函數。在 PHP V6 中,microtime() 在默認情況下返回一個浮點值。





OO 函數

在 PHP V6 中對 OO 函數進行了一些改進。添加了關鍵字 static:: 用於延遲靜態綁定,這意味著將執行運行時靜態數字計算。

支持名稱空間

PHP V5 不支持名稱空間,而是在一個全局名稱空間中定義所有函數和變數。PHP V6 通過關鍵字 namespace 添加對名稱空間的支持。為了定義一個已經定義的類名或函數名,必須使用名稱空間將新的類或函數與已經存在的類或函數區分開來。XMLReader 是一個已經存在的類,但是假設您仍然想定義另一個 XMLReader。您應該這樣定義 XMLReader 類:

___FCKpd___20

為了在 XmlNamespace 中調用 XMLReader 類,需要使用前綴 XmlNamespace\。名稱空間中可以包含類和函數,但不能包含變數。

支持類型提示返回值

PHP V5 僅支持類型提示(其中定義了類型)參數。PHP V6 支持類型提示返回值。

靜態和動態方法調用

在 PHP V5 中,可以對方法進行靜態或動態調用,而不管它是否標記為 static。例如,在下面的清單中,進行了靜態和動態方法的調用:

___FCKpd___21

在 PHP V6 中,使用靜態調用語法調用動態函數將拋出一個 E_FATAL 錯誤,反之亦然。





PHP 的添加內容

opcode 緩存改善了性能。另一個 PHP cache(APC)擴展曾經使用過一段時間,它也將添加到核心 PHP 發布版。默認情況下將不啟用 APC 擴展。提供其他安全性的 Hardened PHP 補丁的一些特性已經合併到 PHP。

現在,許多 PHP 擴展甚至對可修復錯誤使用 E_ERROR。E_ERROR 終止腳本的運行。因此,在 PHP V6 中,擴展中僅對不可修復的錯誤使用 E_ERROR。E_STRICT 錯誤表明這是語言級別的警告或錯誤,目前還沒有包含在 E_ALL 中。在 PHP V6 中,已經將 E_STRICT 添加到 E_ALL。在 PHP V6 中,將為 PHP 添加 MySQL 原生驅動器。並且添加對大於 2 GB 的文件的支持。

在 PHP V6 中,將刪除 ASP 樣式的標記 (<% %>)。但會保留 PHP 短標記 (<? ?>)。





結束語

本文介紹了 PHP V6 中的新特性和已更改的特性。其中最主要的特性就是對 Unicode 的支持。刪除了一些配置選項,比如 register_globals、magic_quotes、safe_mode 和 register_long_arrays。改進了擴展支持和 OO 函數。PHP V5.3 支持 PHP V6 的 50% 的特性。(責任編輯:A6)

GET['var'] ?: 3;

如果 $_GET['var'] 沒有設置,將拋出 E_NOTICE。PHP V6 將規定對多維數組使用 foreach 語法。

___FCKpd___19

在 PHP V5 中,{} 和 [] 都可用於訪問字元串和數組元素中的字元。在 PHP V6 中,將刪除 {},並且繼續使用 [],而 [] 操作符將支持 substr()/array_slice() 函數。在 PHP V6 中,microtime() 在默認情況下返回一個浮點值。





OO 函數

在 PHP V6 中對 OO 函數進行了一些改進。添加了關鍵字 static:: 用於延遲靜態綁定,這意味著將執行運行時靜態數字計算。

支持名稱空間

PHP V5 不支持名稱空間,而是在一個全局名稱空間中定義所有函數和變數。PHP V6 通過關鍵字 namespace 添加對名稱空間的支持。為了定義一個已經定義的類名或函數名,必須使用名稱空間將新的類或函數與已經存在的類或函數區分開來。XMLReader 是一個已經存在的類,但是假設您仍然想定義另一個 XMLReader。您應該這樣定義 XMLReader 類:

___FCKpd___20

為了在 XmlNamespace 中調用 XMLReader 類,需要使用前綴 XmlNamespace\。名稱空間中可以包含類和函數,但不能包含變數。

支持類型提示返回值

PHP V5 僅支持類型提示(其中定義了類型)參數。PHP V6 支持類型提示返回值。

靜態和動態方法調用

在 PHP V5 中,可以對方法進行靜態或動態調用,而不管它是否標記為 static。例如,在下面的清單中,進行了靜態和動態方法的調用:

___FCKpd___21

在 PHP V6 中,使用靜態調用語法調用動態函數將拋出一個 E_FATAL 錯誤,反之亦然。





PHP 的添加內容

opcode 緩存改善了性能。另一個 PHP cache(APC)擴展曾經使用過一段時間,它也將添加到核心 PHP 發布版。默認情況下將不啟用 APC 擴展。提供其他安全性的 Hardened PHP 補丁的一些特性已經合併到 PHP。

現在,許多 PHP 擴展甚至對可修復錯誤使用 E_ERROR。E_ERROR 終止腳本的運行。因此,在 PHP V6 中,擴展中僅對不可修復的錯誤使用 E_ERROR。E_STRICT 錯誤表明這是語言級別的警告或錯誤,目前還沒有包含在 E_ALL 中。在 PHP V6 中,已經將 E_STRICT 添加到 E_ALL。在 PHP V6 中,將為 PHP 添加 MySQL 原生驅動器。並且添加對大於 2 GB 的文件的支持。

在 PHP V6 中,將刪除 ASP 樣式的標記 (<% %>)。但會保留 PHP 短標記 (<? ?>)。





結束語

本文介紹了 PHP V6 中的新特性和已更改的特性。其中最主要的特性就是對 Unicode 的支持。刪除了一些配置選項,比如 register_globals、magic_quotes、safe_mode 和 register_long_arrays。改進了擴展支持和 OO 函數。PHP V5.3 支持 PHP V6 的 50% 的特性。(責任編輯:A6)

SESSION['username'])) { echo "Welcome {
本文詳細闡述 PHP V6 中的新特性。了解為什麼它更加容易使用、更加安全和更加適合國際化。新的特性包括增強對 Unicode 的支持、刪除了幾個函數、改進擴展、引擎添加內容、OO 函數的改變和 PHP 擴展。

簡介

“PHP 的特性” 簡單介紹了 PHP V6 中的新特性。在本文中,了解這些讓 PHP V6 更加容易使用、更加安全和更加適合國際化的新特性。本文探索改進的 Unicode 支持,刪除了幾個函數、改進的擴展、引擎添加內容、改進的面向對象函數和 PHP V6 中的一些擴展。





增強對 Unicode 的支持

PHP V6 中的主要特性是增強對 Unicode 的支持。目前,PHP 實際上是一個二進位處理器。PHP V5 沒有提供原生的 Unicode 支持;它假定所有字元的長度都為 1 位元組,這在處理非拉丁字元時會出現問題。您可以轉換到 Unicode,但需要使用 mbstring 擴展,而默認的 PHP V5 或外部工具(比如 iconv)都不支持該擴展。

PHP V5 有時不能正確顯示文本,這取決於字元編碼。Unicode 是由 Unicode Consortium 開發的行業標準,它能表示所有語言、程序和平台上的每一個字元。各個行業和標準都廣泛支持 Unicode,這使得實現國際化多語言應用程序成為可能。Unicode 可以使用多種字元編碼表示,最常見的是 UTF-8、UTF-16 和 UTF-32。

PHP V6 原生地支持 Unicode (UTF-8),因此它的引擎、擴展和 API 都支持 Unicode。儘管已經添加將所有二進位字元串作為不同類型處理的支持,PHP V6 仍然能夠將字元串作為 Unicode 處理。在 PHP V6 中,字元串的字面量為 Unicode,允許使用 Unicode 標識符,並且它的函數能夠理解 Unicode 文本。PHP V6 能夠在需要時支持 Unicode 字元串和其他編碼之間的轉換,並支持對 UTF-8 文件進行讀寫。下面給出一個從 UTF-8 文件讀取內容的例子:

$input = fopen('inputfile.txt', 'rt');  $str = fread($input, 100); // returns 100 Unicode characters

向 UTF-8 文本文件寫一個 Unicode 字元串 $uni:

$output = fopen('outputfile.txt', 'wt');  fwrite($fp, $uni); // writes out data in UTF-8 encoding

Unicode 模式

在 PHP V5 中,可以根據需求將 Unicode 模式設置為打開或關閉。這表明非 Unicode 和 Unicode 變體類、方法和函數名必須存儲在符號表中,這導致更多的開銷。PHP V6 在 php.ini 中提供一個伺服器通用的配置設置,以啟用或禁用 Unicode 模式。

Opcode 緩存用於緩存已編譯的 PHP 代碼。
伺服器通用的配置使引擎的某個部分的實現更加容易,引起的 opcode 緩存問題更少,並且提高運行速度,因為不需要在運行時轉換符號名。

PHP V6 保留了禁用 Unicode 模式的選項,因為一些字元串函數的 Unicode 實現變慢了 300%,這使整個應用程序的速度變慢 25%。PHP V6 在 php.ini 中提供一個運行時配置選項,用於啟用或禁用 Unicode 語義。默認設置為 on。

unicode.semantics = on           

將 unicode.semantics 設置為 off 並不意味著不使用 Unicode。當設置為 off 時,您仍然可用訪問 Unicode 特性。當 Unicode 語義設置為 off,字元串的字面量是 8 位的字元串;1 個字元等於 1 個位元組。

unicode.semantics = off  $str = "Hello, world!";// ASCII encoding  echo strlen($str);//result is 13

如果設置為 unicode.semantics=on,那麼字元串字面量使用 Unicode 類型。當 Unicode 語義設置為 on 時,一個字元可能 > 1 個位元組。

unicode.semantics = on  $str = "Hello, world!";// Unicode string  echo strlen($str);// result is 13  

PHP V6 中的 unicode.runtime_encoding 配置選項指定在運行時執行 Unicode 和二進位字元串之間的轉換時使用哪種編碼。例如,將運行時編碼設置為 iso-8859-1。

unicode.runtime_encoding = iso-8859-1  

當與尚未支持 Unicode 的函數連接時,仍然需要使用運行時編碼。PHP 腳本可以採用各種編碼方式。PHP V6 提供 unicode.script_encoding 配置選項來指定腳本的編碼。不管腳本的編碼是什麼,生成的字元串字面量都為 Unicode 類型。

 unicode.script_encoding = iso-8859-1  $uni = ""; // Unicode string  unicode.script_encoding = utf-8  $uni = "Atildel"; // also Unicode string  

您還可以將 declare() 語句作為 PHP 腳本的第一個語句,這樣也可以設置腳本的編碼。declare() 構造器覆蓋 php.ini 設置。declare() 設置不會傳播到文件。

 unicode.script_encoding = utf-8  declare(encoding="iso-8859-1");  $uni = "Atildel";// read as ISO-8859-1 string  include "inputfile.php";// file is read as UTF-8  

unicode.output_encoding 配置選項指定標準輸出流所使用的編碼,包括 echo、print 和 var_dump() 函數。輸出流的編碼被即時轉換。unicode.output_encoding 配置選項不影響二進位字元串。

 unicode.output_encoding = utf-8   unicode.script_encoding = iso-8859-1  $unicode = "Atildel"; // Unicode string (from ISO-8859-1)  echo $unicode; // converts $unicode to UTF-8 encoding  echo b"Atildel"; // no conversion, raw contents  

如果啟用了 Unicode 語義,HTTP 輸入必須轉換為 Unicode。GET 請求沒有編碼,並且也很少指定 POST 請求的編碼。PHP V6 提供 unicode.http_input_encoding 配置選項來指定將 HTTP 輸入轉換為哪種 Unicode 編碼。例如,將 HTTP 輸入轉換為 UTF-8:

unicode.http_input_encoding = utf-8 

PHP 將嘗試根據 unicode.http_input_encoding 設置進行解碼。如果解碼失敗,PHP 將使用原始的二進位數據填充請求數組。unicode.filename_encoding 配置選項指定文件系統上文件和目錄名的編碼。

unicode.filename_encoding = utf-8               

當輸入和輸出文件名時,與文件系統相關的函數執行所需的轉換。PHP V6 提供 unicode.fallback_encoding 配置選項來指定 fallback 編碼。

unicode.fallback_encoding = iso-8859-1  

當沒有給其他編碼分配值時,將使用 fallback 編碼。fallback 編碼的默認值是 UTF-8。在 PHP V6 中,您可以使用不同的字元編碼;當啟用 unicode.semantics 選項時,PHP V6 將所有字元串字面量轉換為 Unicode 字元串。您可以無縫地對輸入和輸出使用不同的字元。PHP V6 根據 php.ini 中指定的配置選項對 HTTP 輸入和輸出進行編碼。資料庫和用戶代理程序能夠收到所需的字元編碼,而不需使用任何轉換函數。

您不一定要使用 Unicode 開發腳本來處理和輸出 Unicode,但我們推薦這麼做。如前所述,通過 unicode.script_encoding 配置選項指定腳本編碼。為了在數據中(比如 MySQL)存儲 Unicode 數據,資料庫不需要配置為 UTF-8 編碼,但這樣做比較好。MySQL 資料庫被配置為運行不同的字符集,PHP V6 將以 Unicode 編碼發送查詢,而 MySQL 將嘗試轉換它。

兩種字元串類型

PHP V5 的字元串類型實現有很多字元串類型(二進位、字元串和 Unicode),並且有很多內部引擎函數和幫助函數的實現。PHP V6 只有兩種字元串類型:二進位和 Unicode。unicode.semantics 轉換(switch)決定字元串字面量的默認類型。如果啟用了 unicode.semantics,默認的字元串字面量就為 Unicode。如果禁用該語義轉換,默認字元串字面量的類型就為二進位。您可以顯式地在 Unicode 和二進位字元串類型之間轉換,也可以隱式地進行轉換。使用 unicode.runtime_encoding 配置選項進行隱式轉換。表 1 顯示了如何進行顯式轉換。


表 1. 轉換字元串類型
類型轉換 描述
(binary) 轉換到二進位字元串類型
(unicode) 轉換到 Unicode 字元串類型
(string) 如果 unicode.semantics 設置為 on,就轉換到 Unicode 字元串類型,否則轉換到二進位字元串類型

PHP V6 在內部使用 IS_STRING 表示二進位字元串數據,以及使用 IS_UNICODE 表示 Unicode 字元串數據。

在擴展中支持 Unicode

PHP V6 包含了 Unicode/API,擴展可以藉助它實現 Unicode 支持。需要向擴展模塊結構添加一個標誌,以表明它是否支持 Unicode。如果擴展不支持 Unicode,並且在 PHP 中啟用了 Unicode 語義,那麼在啟動時將不載入它。Unicode 支持被添加到 PHP 數據對象中 (PDO)。

ICU 庫

International Components for Unicode (ICU) 是一組提供 Unicode 和全球化支持的庫。PHP V6 需要使用 ICU,但 ICU 是一個大型的庫,將增加 PHP 的下載體積。PHP 要求使用 ICU V3.4,並且要求發布版提供 ICU 庫。

文件名編碼

不同的文件名可能使用不同的字符集進行編碼。例如,Windows 文件名使用 UTF-16 編碼。filename_encoding 設置指定期望的文件名編碼。當 read 函數(比如 readdir() 和 readfile())遇到其編碼在 filename_encoding 中不存在的文件名時,將返回一個二進位字元串。

緩存校對器

校對器(Collator)用於比較字元串。打開和關閉校對器需要引入開銷。PHP V6 緩存了校對器,但限制存儲在緩存中的對象數量,以防止使用過多的內存。PHP V6 在線程/進程通用緩存中存儲最近打開的 3 個校對器。

基於位置的函數

對於使用系統位置的 PHP 函數,由於位置名在不同的平台中不一致甚至不可用,因此這是一個問題。PHP V6 僅在合適的地方使用基於位置的函數。基於位置的函數包括 strtoupper/strtolower 和 stristr 等。strtoupper 函數將字母表中的字元都轉換為大寫的。“字母表的字元順序” 由當前的位置決定。

字符集轉換錯誤

在字元編碼之間執行轉換可能發生轉換錯誤,因為並不是源字元串中的所有字元都有必要存儲在目標字元串中。PHP V6 為字符集轉換失敗提供一個額外的錯誤模式,它會在失敗時拋出異常。PHP V6 為處理轉換錯誤引入了兩個新的 php.ini 配置選項:unicode.from_error_mode 和 unicode.from_error_subst_char。

unicode.from_error_mode = U_INVALID_SUBSTITUTE  unicode.from_error_subst_char = 3f

unicode.from_error_subst_char 選項為無效的字元串指定了代替字元串的十六進位值;它的默認值是 3f。

unicode.from_error_mode 選項指定錯誤模式,它在遇到無效字元串時採取行動。表 2 顯示了 unicode.from_error_mode 可能使用的值。


表 2. unicode.from_error_mode 值
常量 說明
U_INVALID_STOP 0 遇到第一個無效字元時停止
U_INVALID_SKIP 1 跳過無效字元
U_INVALID_SUBSTITUTE 2 替換無效字元;默認值
U_INVALID_ESCAPE 3 對無效字元進行轉義





刪除了幾個函數

這個小節概述了在 PHP V6 中刪除的幾個函數。

刪除了 register_globals

PHP V5 在 php.ini 中使用 register_globals 配置選項從環境和 HTTP 請求參數定義變數。不過,register_globals 生成不安全的代碼。因此,在 PHP V6 中刪除了 register_globals。

register_globals 生成不安全代碼的方式之一是 authenticate.php,它使用 $auth 變數對用戶進行身份驗證。因為 $auth 沒有被初始化,所以它的值可能通過使用 register_globals 注入變數來定義,比如 GET authenticate.php?auth=1。

<?php  if (authenticated_user()) {      $auth = true;  }  if ($auth) {      include "/data.php";  }  ?>              

register_globals 注入的變數也可能在會話中生成不安全的代碼。看看以下代碼,當設置了 $username 變數時,將在用戶會話中顯示一條歡迎消息。但是,當啟用 register_globals 時,可能會使用 HTTP 請求參數注入 $username 變數。

___FCKpd___14

所有使用 register_globals 的函數都被刪除了,比如 session_register。如果需要導入請求變數,可以使用 import_request_variables。或者使用 $_POST、$_GET、$_COOKIE 和 $_REQUEST 變數。如果設置了 register_globals,PHP V6 將在啟動時拋出 E_CORE_ERROR。

刪除了 magic_quotes

在 PHP V5 中,當啟用了 magic_quotes 配置選項時,它會在輸入數據中自動將所有單引號(')、雙引號(")、反斜杠(\)和 NULL 字元轉義為帶反斜杠的(\)PHP 腳本。Magic Quotes 減少了 SQL 注入(一種能夠篡改 SQL 命令的技術)的風險。Magic Quotes 便於將數據插入到資料庫中。不 使用 Magic Quotes 的理由是考慮到移植性、性能和方便性。

您需要知道是否關閉了 Magic Quotes。如果 Magic Quotes 處於 on,而您認為它處於 off,應用程序就會出現額外的斜杠。如果 Magic Quotes 處於 off,而您認為它處於 on,應用程序就可能遭受 SQL 注入攻擊。Magic Quotes 會損害性能,因為並不是所有轉義數據都被插入到資料庫。一個更好的代替辦法是在運行時使用轉義函數,比如 addslashes。Magic Quotes 可能帶來不便,因為並不是所有數據都需要轉義。可以使用 stripslashes 函數刪除多餘的斜杠。

PHP V6 不再支持 magic_quotes、magic_quotes_sybase 和 magic_quotes_gpc 設置。如果在啟動時發現這些設置,PHP 將發出一個 E_CORE_ERROR。此外,還刪除了 get_magic_quotes_gpc() 函數。

刪除了 safe_mode

在 PHP V5 中,safe_mode 配置選項可用於解決與共享伺服器有關的安全問題。它確保需要打開或包含的文件的用戶必須與執行這些文件的腳本的用戶相同。safe_mode 並不是絕對安全的。

考慮這樣一個場景,一個應用程序使用 Web 伺服器的 ID 並生成緩存文件或映像。如果該應用程序由客戶機用戶載入,PHP 腳本將不能打開緩存文件或映像,因為用戶 ID 不匹配。並且,safe_mode 可以繞過庫。

在 PHP V6 中刪除了 safe_mode 選項。如果檢測到 safe_mode 設置,將拋出 E_CORE_ERROR。open_basedir 配置仍然可用,它限制 PHP 可以在特定目錄樹中打開的文件。

刪除不贊成使用的行為

在 PHP V6 中刪除了一些在早期的 PHP 版本中不贊成使用的行為。allow_call_time_pass_reference 配置指定在運行時通過引用傳遞參數時是否發出警告,它在 PHP V5 中就不推薦使用。在 PHP V6 中刪除了 allow_call_time_pass_reference。

如果要指定哪個參數是通過引用傳遞的,更好的方法是使用聲明函數。在 PHP V6 中,call-time-pass-by-reference 將拋出一個 E_STRICT 錯誤。在 PHP V6 中,“var” 已經成為 “public” 的別名,並且刪除了 E_STRICT 警告。受 "new lt;object-name>" 的影響,也刪除了 return-by-reference。通過引用賦值 “new” 將拋出一個 E_STRICT 錯誤。例如,下面的語句將拋出 E_STRICT 錯誤:

___FCKpd___15

刪除了 zend.ze1_compatibility_mode

zend.ze1_compatibility_mode 配置啟用了與 Zend Engine V1 (PHP V4) 的兼容性,它是在 PHP V5 引入的,方便了從 PHP V4 遷移到 PHP V5。

在 PHP V6 中,已經刪除了 zend.ze1_compatibility_mode 特性,如果檢測到該設置,將拋出 E_CORE_ERROR。

刪除了 Freetype 1 和 GD 1 庫

FreeType 1 和 GD 1 是老版本的字體呈現和圖像處理庫。它們不再受到維護,並且已被更新版本的 FreeType 和 GD 代替。在 PHP V6 中,刪除了對 FreeType 1 和 GD 1 庫的支持。

默認情況下不啟用 dl()

dl (string $library) 函數用於在運行時載入 PHP 擴展。在 PHP V5 中,可以在 php.ini 配置文件中啟用或禁用 dl() 函數:enable_dl = On。

dl() 函數會給從未載入過的模塊帶來問題。dl() 函數不能在多線程伺服器中正常工作,比如 IIS 或 Zeus,因為在這些伺服器中會自動禁用它。不過 dl() 函數在 PHP Command Line Interface (CLI) Server Application Programming Interface (SAPI) 中非常有用。

在 PHP V6 中,dl() 函數在默認情況下是禁用的,但並沒有刪除它。SAPI 層可能會顯式地註冊 dl() 函數。

FastCGI 模式

FastCGI 提供很高的性能,如果禁用,將導致雜亂的代碼。在 PHP V6 中不能禁用 FastCGI。

刪除了 register_long_arrays

當啟用 register_long_arrays 配置選項時,將註冊很長的超級全局變數 — $HTTP_*_VARS 變數。$HTTP_*_VARS 變數是在 PHP V5 中為了向後兼容性而引入的,但不是必要的。使用更短的變數 $_GET、$_POST 和 $_SERVER 代替它會更好。在新的 PHP 版本中,register_long_arrays 設置和 $HTTP_*_VARS 沒有得到好評。

在 PHP V6 中,刪除了 register_long_arrays 設置和 $HTTP_*_VARS 全局變數,如果檢測到 register_long_arrays,將拋出 E_CORE_ERROR。

刪除 break $var

動態的 break 操作數不起作用,如以下示例所示:

___FCKpd___16

在 PHP V6 中,刪除了動態的 break 操作數。取而代之的是,您可以為 $var 分配一個數字,如下所示:

___FCKpd___17





改進擴展

擴展是 PHP 的主要組件。在 PHP V6 中,有幾個組件得到了改進。

包含在核心發布版中的 XML 擴展

XMLReader 擴展提供一個 XML 解析器,用於閱讀 XML 文件,該解析器在內部基於 SAX 解析。XMLWriter 為寫 XML 文件提供一個 API。XMLReader 和 XMLWriter 使 XML 文件的讀寫更加容易。PHP V5 的核心發布版沒有包含 XMLReader 和 XMLWriter。

PHP V6 將在核心發布版中包含 XMLReader 和 XMLWriter 擴展,並且默認啟用這兩個擴展。

正則表達式擴展

PHP V5.x 為正則表達式提供兩個庫:ereg 和 Perl Compatible Regular Expression (PCRE)。ereg 庫支持 Portable Operating System Interface (POSIX) 正則表達式,而 PCRE 擴展支持與 Perl 兼容的語法。打包的 ereg 庫會造成問題,因此被轉換成擴展並從核心發布版移動到 PHP Extension Community Library (PECL)。

PCRE 擴展提供更多的特性,並且比 ereg 擴展快。PCRE 擴展在默認情況下是啟用的,並且不可以禁用它。一些核心的 PHP 函數使用 POSIX 正則表達式。因為刪除了 ereg 庫,所以這些函數將使用 PCRE 表達式重新編寫。PCRE 表達式提供一些與 ereg 庫等效的函數。


表 3. PCRE 擴展中的等效函數
ereg() 函數 等效的 PCRE 函數
ereg() preg_match()
ereg_replace() preg_replace()

MIME 類型檢查擴展

在 PHP V5 中,mime_magic 擴展用於媒體類型(media-type)檢測,但不是很可靠。PECL 為 MIME 類型檢查提供另一個擴展:Fileinfo。mime_magic 擴展將從核心發布版移動到 PECL。Fileinfo 擴展將添加到核心發布版,並默認啟用。

默認啟用 SOAP 擴展

SOAP 擴展(ext/soap)用於開發使用 Web 服務的 PHP 應用程序,包括 SOAP 伺服器和 SOAP 客戶機。在 PHP V5 中,SOAP 擴展不是默認啟用的;開發人員必須配置 SOAP 擴展。在 PHP V6 中,默認啟用 SOAP 擴展。PHP V6 還實現一些安全擴展。





引擎的添加內容

在 PHP V6,將添加 64 位的整數,同時保留 32 位整數。64 位引擎的轉換名為 int64。將使用一個靜態標籤擴展 break 關鍵字。將從 ?: 操作符丟棄中間參數。例如,在下面的表達式中,如果 $_GET['var'] 計算為 true,則 $var 設置為 3。如果 $_GET['var'] 計算為 false 或沒有設置,則 $var 設置為 $_GET['var']。

___FCKpd___18

如果 $_GET['var'] 沒有設置,將拋出 E_NOTICE。PHP V6 將規定對多維數組使用 foreach 語法。

___FCKpd___19

在 PHP V5 中,{} 和 [] 都可用於訪問字元串和數組元素中的字元。在 PHP V6 中,將刪除 {},並且繼續使用 [],而 [] 操作符將支持 substr()/array_slice() 函數。在 PHP V6 中,microtime() 在默認情況下返回一個浮點值。





OO 函數

在 PHP V6 中對 OO 函數進行了一些改進。添加了關鍵字 static:: 用於延遲靜態綁定,這意味著將執行運行時靜態數字計算。

支持名稱空間

PHP V5 不支持名稱空間,而是在一個全局名稱空間中定義所有函數和變數。PHP V6 通過關鍵字 namespace 添加對名稱空間的支持。為了定義一個已經定義的類名或函數名,必須使用名稱空間將新的類或函數與已經存在的類或函數區分開來。XMLReader 是一個已經存在的類,但是假設您仍然想定義另一個 XMLReader。您應該這樣定義 XMLReader 類:

___FCKpd___20

為了在 XmlNamespace 中調用 XMLReader 類,需要使用前綴 XmlNamespace\。名稱空間中可以包含類和函數,但不能包含變數。

支持類型提示返回值

PHP V5 僅支持類型提示(其中定義了類型)參數。PHP V6 支持類型提示返回值。

靜態和動態方法調用

在 PHP V5 中,可以對方法進行靜態或動態調用,而不管它是否標記為 static。例如,在下面的清單中,進行了靜態和動態方法的調用:

___FCKpd___21

在 PHP V6 中,使用靜態調用語法調用動態函數將拋出一個 E_FATAL 錯誤,反之亦然。





PHP 的添加內容

opcode 緩存改善了性能。另一個 PHP cache(APC)擴展曾經使用過一段時間,它也將添加到核心 PHP 發布版。默認情況下將不啟用 APC 擴展。提供其他安全性的 Hardened PHP 補丁的一些特性已經合併到 PHP。

現在,許多 PHP 擴展甚至對可修復錯誤使用 E_ERROR。E_ERROR 終止腳本的運行。因此,在 PHP V6 中,擴展中僅對不可修復的錯誤使用 E_ERROR。E_STRICT 錯誤表明這是語言級別的警告或錯誤,目前還沒有包含在 E_ALL 中。在 PHP V6 中,已經將 E_STRICT 添加到 E_ALL。在 PHP V6 中,將為 PHP 添加 MySQL 原生驅動器。並且添加對大於 2 GB 的文件的支持。

在 PHP V6 中,將刪除 ASP 樣式的標記 (<% %>)。但會保留 PHP 短標記 (<? ?>)。





結束語

本文介紹了 PHP V6 中的新特性和已更改的特性。其中最主要的特性就是對 Unicode 的支持。刪除了一些配置選項,比如 register_globals、magic_quotes、safe_mode 和 register_long_arrays。改進了擴展支持和 OO 函數。PHP V5.3 支持 PHP V6 的 50% 的特性。(責任編輯:A6)

SESSION['username']}"; } else { echo "Welcome Guest"; } ?>

所有使用 register_globals 的函數都被刪除了,比如 session_register。如果需要導入請求變數,可以使用 import_request_variables。或者使用 $_POST、$_GET、$_COOKIE 和 $_REQUEST 變數。如果設置了 register_globals,PHP V6 將在啟動時拋出 E_CORE_ERROR。

刪除了 magic_quotes

在 PHP V5 中,當啟用了 magic_quotes 配置選項時,它會在輸入數據中自動將所有單引號(')、雙引號(")、反斜杠(\)和 NULL 字元轉義為帶反斜杠的(\)PHP 腳本。Magic Quotes 減少了 SQL 注入(一種能夠篡改 SQL 命令的技術)的風險。Magic Quotes 便於將數據插入到資料庫中。不 使用 Magic Quotes 的理由是考慮到移植性、性能和方便性。

您需要知道是否關閉了 Magic Quotes。如果 Magic Quotes 處於 on,而您認為它處於 off,應用程序就會出現額外的斜杠。如果 Magic Quotes 處於 off,而您認為它處於 on,應用程序就可能遭受 SQL 注入攻擊。Magic Quotes 會損害性能,因為並不是所有轉義數據都被插入到資料庫。一個更好的代替辦法是在運行時使用轉義函數,比如 addslashes。Magic Quotes 可能帶來不便,因為並不是所有數據都需要轉義。可以使用 stripslashes 函數刪除多餘的斜杠。

PHP V6 不再支持 magic_quotes、magic_quotes_sybase 和 magic_quotes_gpc 設置。如果在啟動時發現這些設置,PHP 將發出一個 E_CORE_ERROR。此外,還刪除了 get_magic_quotes_gpc() 函數。

刪除了 safe_mode

在 PHP V5 中,safe_mode 配置選項可用於解決與共享伺服器有關的安全問題。它確保需要打開或包含的文件的用戶必須與執行這些文件的腳本的用戶相同。safe_mode 並不是絕對安全的。

考慮這樣一個場景,一個應用程序使用 Web 伺服器的 ID 並生成緩存文件或映像。如果該應用程序由客戶機用戶載入,PHP 腳本將不能打開緩存文件或映像,因為用戶 ID 不匹配。並且,safe_mode 可以繞過庫。

在 PHP V6 中刪除了 safe_mode 選項。如果檢測到 safe_mode 設置,將拋出 E_CORE_ERROR。open_basedir 配置仍然可用,它限制 PHP 可以在特定目錄樹中打開的文件。

刪除不贊成使用的行為

在 PHP V6 中刪除了一些在早期的 PHP 版本中不贊成使用的行為。allow_call_time_pass_reference 配置指定在運行時通過引用傳遞參數時是否發出警告,它在 PHP V5 中就不推薦使用。在 PHP V6 中刪除了 allow_call_time_pass_reference。

如果要指定哪個參數是通過引用傳遞的,更好的方法是使用聲明函數。在 PHP V6 中,call-time-pass-by-reference 將拋出一個 E_STRICT 錯誤。在 PHP V6 中,“var” 已經成為 “public” 的別名,並且刪除了 E_STRICT 警告。受 "new lt;object-name>" 的影響,也刪除了 return-by-reference。通過引用賦值 “new” 將拋出一個 E_STRICT 錯誤。例如,下面的語句將拋出 E_STRICT 錯誤:

___FCKpd___15

刪除了 zend.ze1_compatibility_mode

zend.ze1_compatibility_mode 配置啟用了與 Zend Engine V1 (PHP V4) 的兼容性,它是在 PHP V5 引入的,方便了從 PHP V4 遷移到 PHP V5。

在 PHP V6 中,已經刪除了 zend.ze1_compatibility_mode 特性,如果檢測到該設置,將拋出 E_CORE_ERROR。

刪除了 Freetype 1 和 GD 1 庫

FreeType 1 和 GD 1 是老版本的字體呈現和圖像處理庫。它們不再受到維護,並且已被更新版本的 FreeType 和 GD 代替。在 PHP V6 中,刪除了對 FreeType 1 和 GD 1 庫的支持。

默認情況下不啟用 dl()

dl (string $library) 函數用於在運行時載入 PHP 擴展。在 PHP V5 中,可以在 php.ini 配置文件中啟用或禁用 dl() 函數:enable_dl = On。

dl() 函數會給從未載入過的模塊帶來問題。dl() 函數不能在多線程伺服器中正常工作,比如 IIS 或 Zeus,因為在這些伺服器中會自動禁用它。不過 dl() 函數在 PHP Command Line Interface (CLI) Server Application Programming Interface (SAPI) 中非常有用。

在 PHP V6 中,dl() 函數在默認情況下是禁用的,但並沒有刪除它。SAPI 層可能會顯式地註冊 dl() 函數。

FastCGI 模式

FastCGI 提供很高的性能,如果禁用,將導致雜亂的代碼。在 PHP V6 中不能禁用 FastCGI。

刪除了 register_long_arrays

當啟用 register_long_arrays 配置選項時,將註冊很長的超級全局變數 — $HTTP_*_VARS 變數。$HTTP_*_VARS 變數是在 PHP V5 中為了向後兼容性而引入的,但不是必要的。使用更短的變數 $_GET、$_POST 和 $_SERVER 代替它會更好。在新的 PHP 版本中,register_long_arrays 設置和 $HTTP_*_VARS 沒有得到好評。

在 PHP V6 中,刪除了 register_long_arrays 設置和 $HTTP_*_VARS 全局變數,如果檢測到 register_long_arrays,將拋出 E_CORE_ERROR。

刪除 break $var

動態的 break 操作數不起作用,如以下示例所示:

___FCKpd___16

在 PHP V6 中,刪除了動態的 break 操作數。取而代之的是,您可以為 $var 分配一個數字,如下所示:

___FCKpd___17





改進擴展

擴展是 PHP 的主要組件。在 PHP V6 中,有幾個組件得到了改進。

包含在核心發布版中的 XML 擴展

XMLReader 擴展提供一個 XML 解析器,用於閱讀 XML 文件,該解析器在內部基於 SAX 解析。XMLWriter 為寫 XML 文件提供一個 API。XMLReader 和 XMLWriter 使 XML 文件的讀寫更加容易。PHP V5 的核心發布版沒有包含 XMLReader 和 XMLWriter。

PHP V6 將在核心發布版中包含 XMLReader 和 XMLWriter 擴展,並且默認啟用這兩個擴展。

正則表達式擴展

PHP V5.x 為正則表達式提供兩個庫:ereg 和 Perl Compatible Regular Expression (PCRE)。ereg 庫支持 Portable Operating System Interface (POSIX) 正則表達式,而 PCRE 擴展支持與 Perl 兼容的語法。打包的 ereg 庫會造成問題,因此被轉換成擴展並從核心發布版移動到 PHP Extension Community Library (PECL)。

PCRE 擴展提供更多的特性,並且比 ereg 擴展快。PCRE 擴展在默認情況下是啟用的,並且不可以禁用它。一些核心的 PHP 函數使用 POSIX 正則表達式。因為刪除了 ereg 庫,所以這些函數將使用 PCRE 表達式重新編寫。PCRE 表達式提供一些與 ereg 庫等效的函數。


表 3. PCRE 擴展中的等效函數
ereg() 函數 等效的 PCRE 函數
ereg() preg_match()
ereg_replace() preg_replace()

MIME 類型檢查擴展

在 PHP V5 中,mime_magic 擴展用於媒體類型(media-type)檢測,但不是很可靠。PECL 為 MIME 類型檢查提供另一個擴展:Fileinfo。mime_magic 擴展將從核心發布版移動到 PECL。Fileinfo 擴展將添加到核心發布版,並默認啟用。

默認啟用 SOAP 擴展

SOAP 擴展(ext/soap)用於開發使用 Web 服務的 PHP 應用程序,包括 SOAP 伺服器和 SOAP 客戶機。在 PHP V5 中,SOAP 擴展不是默認啟用的;開發人員必須配置 SOAP 擴展。在 PHP V6 中,默認啟用 SOAP 擴展。PHP V6 還實現一些安全擴展。





引擎的添加內容

在 PHP V6,將添加 64 位的整數,同時保留 32 位整數。64 位引擎的轉換名為 int64。將使用一個靜態標籤擴展 break 關鍵字。將從 ?: 操作符丟棄中間參數。例如,在下面的表達式中,如果 $_GET['var'] 計算為 true,則 $var 設置為 3。如果 $_GET['var'] 計算為 false 或沒有設置,則 $var 設置為 $_GET['var']。

___FCKpd___18

如果 $_GET['var'] 沒有設置,將拋出 E_NOTICE。PHP V6 將規定對多維數組使用 foreach 語法。

___FCKpd___19

在 PHP V5 中,{} 和 [] 都可用於訪問字元串和數組元素中的字元。在 PHP V6 中,將刪除 {},並且繼續使用 [],而 [] 操作符將支持 substr()/array_slice() 函數。在 PHP V6 中,microtime() 在默認情況下返回一個浮點值。





OO 函數

在 PHP V6 中對 OO 函數進行了一些改進。添加了關鍵字 static:: 用於延遲靜態綁定,這意味著將執行運行時靜態數字計算。

支持名稱空間

PHP V5 不支持名稱空間,而是在一個全局名稱空間中定義所有函數和變數。PHP V6 通過關鍵字 namespace 添加對名稱空間的支持。為了定義一個已經定義的類名或函數名,必須使用名稱空間將新的類或函數與已經存在的類或函數區分開來。XMLReader 是一個已經存在的類,但是假設您仍然想定義另一個 XMLReader。您應該這樣定義 XMLReader 類:

___FCKpd___20

為了在 XmlNamespace 中調用 XMLReader 類,需要使用前綴 XmlNamespace\。名稱空間中可以包含類和函數,但不能包含變數。

支持類型提示返回值

PHP V5 僅支持類型提示(其中定義了類型)參數。PHP V6 支持類型提示返回值。

靜態和動態方法調用

在 PHP V5 中,可以對方法進行靜態或動態調用,而不管它是否標記為 static。例如,在下面的清單中,進行了靜態和動態方法的調用:

___FCKpd___21

在 PHP V6 中,使用靜態調用語法調用動態函數將拋出一個 E_FATAL 錯誤,反之亦然。





PHP 的添加內容

opcode 緩存改善了性能。另一個 PHP cache(APC)擴展曾經使用過一段時間,它也將添加到核心 PHP 發布版。默認情況下將不啟用 APC 擴展。提供其他安全性的 Hardened PHP 補丁的一些特性已經合併到 PHP。

現在,許多 PHP 擴展甚至對可修復錯誤使用 E_ERROR。E_ERROR 終止腳本的運行。因此,在 PHP V6 中,擴展中僅對不可修復的錯誤使用 E_ERROR。E_STRICT 錯誤表明這是語言級別的警告或錯誤,目前還沒有包含在 E_ALL 中。在 PHP V6 中,已經將 E_STRICT 添加到 E_ALL。在 PHP V6 中,將為 PHP 添加 MySQL 原生驅動器。並且添加對大於 2 GB 的文件的支持。

在 PHP V6 中,將刪除 ASP 樣式的標記 (<% %>)。但會保留 PHP 短標記 (<? ?>)。





結束語

本文介紹了 PHP V6 中的新特性和已更改的特性。其中最主要的特性就是對 Unicode 的支持。刪除了一些配置選項,比如 register_globals、magic_quotes、safe_mode 和 register_long_arrays。改進了擴展支持和 OO 函數。PHP V5.3 支持 PHP V6 的 50% 的特性。(責任編輯:A6)



[火星人 ] 初步了解 PHP V6 中的新特性已經有446次圍觀

http://coctec.com/docs/linux/show-post-68866.html