發(fā)布日期:2014/02/20 分類:文檔教程 關(guān)鍵字: php新功能看完本篇,你會明白國內(nèi)的PHP環(huán)境和ThinkPHP為啥要采用PHP5.3甚至更高的版本。 截至目前(2014.2), PHP 的最新穩(wěn)定版本是 PHP5.5, 但有差不多一半的用戶仍在使用已經(jīng)不在維護(hù) [注] 的 PHP5.2, 其余的一半用戶在使用 PHP5.3 [注]. 因為 PHP 那“集百家之長”的蛋疼語法,加上社區(qū)氛圍不好,很多人對新版本,新特征并無興趣。 本文將會介紹自 PHP5.2 起,直至 PHP5.6 中增加的新特征。
注:http:///technologies/details/pl-php/5/all PHP5.2以前(2006前)順便介紹一下 PHP5.2 已經(jīng)出現(xiàn)但值得介紹的特征。 autoload大家可能都知道 __autoload() 函數(shù),如果定義了該函數(shù),那么當(dāng)在代碼中使用一個未定義的類的時候,該函數(shù)就會被調(diào)用,你可以在該函數(shù)中加載相應(yīng)的類實現(xiàn)文件,如:
但該函數(shù)已經(jīng)不被建議使用,原因是一個項目中僅能有一個這樣的 __autoload() 函數(shù),因為 PHP 不允許函數(shù)重名。但當(dāng)你使用一些類庫的時候,難免會出現(xiàn)多個 autoload 函數(shù)的需要,于是 spl_autoload_register() 取而代之:
spl_autoload_register() 會將一個函數(shù)注冊到 autoload 函數(shù)列表中,當(dāng)出現(xiàn)未定義的類的時候,SPL [注] 會按照注冊的倒序逐個調(diào)用被注冊的 autoload 函數(shù),這意味著你可以使用 spl_autoload_register() 注冊多個 autoload 函數(shù).注:SPL: Standard PHP Library, 標(biāo)準(zhǔn) PHP 庫, 被設(shè)計用來解決一些經(jīng)典問題(如數(shù)據(jù)結(jié)構(gòu)). PDO 和 MySQLi即 PHP Data Object, PHP 數(shù)據(jù)對象,這是 PHP 的新式數(shù)據(jù)庫訪問接口。按照傳統(tǒng)的風(fēng)格,訪問 MySQL 數(shù)據(jù)庫應(yīng)該是這樣子:
為了能夠讓代碼實現(xiàn)數(shù)據(jù)庫無關(guān),即一段代碼同時適用于多種數(shù)據(jù)庫(例如以上代碼僅僅適用于MySQL),PHP 官方設(shè)計了 PDO.除此之外,PDO 還提供了更多功能,比如: ·面向?qū)ο箫L(fēng)格的接口 ·SQL預(yù)編譯(prepare), 占位符語法 ·更高的執(zhí)行效率,作為官方推薦,有特別的性能優(yōu)化 ·支持大部分SQL數(shù)據(jù)庫,更換數(shù)據(jù)庫無需改動代碼 上面的代碼用 PDO 實現(xiàn)將會是這樣:
PDO 是官方推薦的,更為通用的數(shù)據(jù)庫訪問方式,如果你沒有特殊需求,那么你最好學(xué)習(xí)和使用 PDO.但如果你需要使用 MySQL 所特有的高級功能,那么你可能需要嘗試一下 MySQLi, 因為 PDO 為了能夠同時在多種數(shù)據(jù)庫上使用,不會包含那些 MySQL 獨有的功能。 MySQLi 是 MySQL 的增強(qiáng)接口,同時提供面向過程和面向?qū)ο蠼涌冢彩悄壳巴扑]的 MySQL 驅(qū)動,舊的C風(fēng)格 MySQL 接口將會在今后被默認(rèn)關(guān)閉。 MySQLi 的用法和以上兩段代碼相比,沒有太多新概念,在此不再給出示例,可以參見 PHP 官網(wǎng)文檔 [注]。 注:http://www./manual/en/mysqli.quickstart.php 類型約束通過類型約束可以限制參數(shù)的類型,不過這一機(jī)制并不完善,目前僅適用于類和 callable(可執(zhí)行類型) 以及 array(數(shù)組), 不適用于 string 和 int.
PHP5.2(2006-2011)JSON 支持包括 json_encode(), json_decode() 等函數(shù),JSON 算是在 Web 領(lǐng)域非常常用的數(shù)據(jù)交換格式,可以被 JS 直接支持,JSON 實際上是 JS 語法的一部分。JSON 系列函數(shù),可以將 PHP 中的數(shù)組結(jié)構(gòu)與 JSON 字符串進(jìn)行轉(zhuǎn)換:
輸出:
值得注意的是 json_decode() 默認(rèn)會返回一個對象而非數(shù)組,如果需要返回數(shù)組需要將第二個參數(shù)設(shè)置為 true.
PHP5.3(2009-2012)PHP5.3 算是一個非常大的更新,新增了大量新特征,同時也做了一些不向下兼容的修改。 棄用的功能 以下幾個功能被棄用,若在配置文件中啟用,則 PHP 會在運行時發(fā)出警告。 Register Globals這是 php.ini 中的一個選項(register_globals), 開啟后會將所有表單變量($_GET和$_POST)注冊為全局變量.看下面的例子:
這段代碼在通過驗證時,將 $authorized 設(shè)置為 true. 然后根據(jù) $authorized 的值來決定是否顯示頁面.但由于并沒有事先把 $authorized 初始化為 false, 當(dāng) register_globals 打開時,可能訪問 /auth.php?authorized=1 來定義該變量值,繞過身份驗證。 該特征屬于歷史遺留問題,在 PHP4.2 中被默認(rèn)關(guān)閉,在 PHP5.4 中被移除。 Magic Quotes對應(yīng) php.ini 中的選項 magic_quotes_gpc, 這個特征同樣屬于歷史遺留問題,已經(jīng)在 PHP5.4 中移除。該特征會將所有用戶輸入進(jìn)行轉(zhuǎn)義,這看上去不錯,在第一章我們提到過要對用戶輸入進(jìn)行轉(zhuǎn)義。 但是 PHP 并不知道哪些輸入會進(jìn)入 SQL , 哪些輸入會進(jìn)入 Shell, 哪些輸入會被顯示為 HTML, 所以很多時候這種轉(zhuǎn)義會引起混亂。 Safe Mode很多虛擬主機(jī)提供商使用 Safe Mode 來隔離多個用戶,但 Safe Mode 存在諸多問題,例如某些擴(kuò)展并不按照 Safe Mode 來進(jìn)行權(quán)限控制。PHP官方推薦使用操作系統(tǒng)的機(jī)制來進(jìn)行權(quán)限隔離,讓W(xué)eb服務(wù)器以不同的用戶權(quán)限來運行PHP解釋器,請參見第一章中的最小權(quán)限原則. 匿名函數(shù)也叫閉包(Closures), 經(jīng)常被用來臨時性地創(chuàng)建一個無名函數(shù),用于回調(diào)函數(shù)等用途。
以上代碼定義了一個匿名函數(shù),并賦值給了 $func.可以看到定義匿名函數(shù)依舊使用 function 關(guān)鍵字,只不過省略了函數(shù)名,直接是參數(shù)列表。 然后我們又調(diào)用了 $func 所儲存的匿名函數(shù)。 匿名函數(shù)還可以用 use 關(guān)鍵字來捕捉外部變量:
上面的代碼定義了一個 arrayPlus() 函數(shù)(這不是匿名函數(shù)), 它會將一個數(shù)組($array)中的每一項,加上一個指定的數(shù)字($num).在 arrayPlus() 的實現(xiàn)中,我們使用了 array_walk() 函數(shù),它會為一個數(shù)組的每一項執(zhí)行一個回調(diào)函數(shù),即我們定義的匿名函數(shù)。 在匿名函數(shù)的參數(shù)列表后,我們用 use 關(guān)鍵字將匿名函數(shù)外的 $num 捕捉到了函數(shù)內(nèi),以便知道到底應(yīng)該加上多少。 魔術(shù)方法:__invoke(), __callStatic()PHP 的面向?qū)ο篌w系中,提供了若干“魔術(shù)方法”,用于實現(xiàn)類似其他語言中的“重載”,如在訪問不存在的屬性、方法時觸發(fā)某個魔術(shù)方法。隨著匿名函數(shù)的加入,PHP 引入了一個新的魔術(shù)方法 __invoke(). 該魔術(shù)方法會在將一個對象作為函數(shù)調(diào)用時被調(diào)用:
輸出毫無疑問是:
__callStatic() 則會在調(diào)用一個不存在的靜態(tài)方法時被調(diào)用。
命名空間PHP的命名空間有著前無古人后無來者的無比蛋疼的語法:
更多有關(guān)命名空間的語法介紹請參見官網(wǎng) [注].命名空間時常和 autoload 一同使用,用于自動加載類實現(xiàn)文件:
當(dāng)你實例化一個類 \XXOO\Test\A 的時候,這個類的完整限定名會被傳遞給 autoload 函數(shù),autoload 函數(shù)將類名中的命名空間分隔符(反斜杠)替換為斜杠,并包含對應(yīng)文件。這樣可以實現(xiàn)類定義文件分級儲存,按需自動加載。 注:http://www./manual/zh/language.namespaces.php 后期靜態(tài)綁定PHP 的 OPP 機(jī)制,具有繼承和類似虛函數(shù)的功能,例如如下的代碼:
輸出是:
可以看到,當(dāng)在 A 中使用 $this->funcXXOO() 時,體現(xiàn)了“虛函數(shù)”的機(jī)制,實際調(diào)用的是 B::funcXXOO().然而如果將所有函數(shù)都改為靜態(tài)函數(shù):
情況就沒這么樂觀了,輸出是:
這是因為 self 的語義本來就是“當(dāng)前類”,所以 PHP5.3 給 static 關(guān)鍵字賦予了一個新功能:后期靜態(tài)綁定:
這樣就會像預(yù)期一樣輸出了:
Heredoc 和 NowdocPHP5.3 對 Heredoc 以及 Nowdoc 進(jìn)行了一些改進(jìn),它們都用于在 PHP 代碼中嵌入大段字符串。Heredoc 的行為類似于一個雙引號字符串:
Heredoc 以三個左尖括號開始,后面跟一個標(biāo)識符(TEXT), 直到一個同樣的頂格的標(biāo)識符(不能縮進(jìn))結(jié)束。就像雙引號字符串一樣,其中可以嵌入變量。 Heredoc 還可以用于函數(shù)參數(shù),以及類成員初始化:
Nowdoc 的行為像一個單引號字符串,不能在其中嵌入變量,和 Heredoc 唯一的區(qū)別就是,三個左尖括號后的標(biāo)識符要以單引號括起來:
輸出:
用 const 定義常量PHP5.3 起同時支持在全局命名空間和類中使用 const 定義常量。舊式風(fēng)格:
新式風(fēng)格:
const 形式僅適用于常量,不適用于運行時才能求值的表達(dá)式:
三元運算符簡寫形式舊式風(fēng)格:
可簡寫成:
即如果省略三元運算符的第二個部分,會默認(rèn)用第一個部分代替。
PharPhar即PHP Archive, 起初只是Pear中的一個庫而已,后來在PHP5.3被重新編寫成C擴(kuò)展并內(nèi)置到 PHP 中。Phar用來將多個 .php 腳本打包(也可以打包其他文件)成一個 .phar 的壓縮文件(通常是ZIP格式)。 目的在于模仿 Java 的 .jar, 不對,目的是為了讓發(fā)布PHP應(yīng)用程序更加方便。同時還提供了數(shù)字簽名驗證等功能。 .phar 文件可以像 .php 文件一樣,被PHP引擎解釋執(zhí)行,同時你還可以寫出這樣的代碼來包含(require) .phar 中的代碼:
更多信息請參見官網(wǎng) [注].注:http://www./manual/zh/phar.using.intro.php PHP5.4(2012-2013)Short Open TagShort Open Tag 自 PHP5.4 起總是可用。在這里集中講一下有關(guān) PHP 起止標(biāo)簽的問題。即:
通常就是上面的形式,除此之外還有一種簡寫形式:
還可以把
簡寫成:
這種簡寫形式被稱為 Short Open Tag, 在 PHP5.3 起被默認(rèn)開啟,在 PHP5.4 起總是可用。使用這種簡寫形式在 HTML 中嵌入 PHP 變量將會非常方便。 對于純 PHP 文件(如類實現(xiàn)文件), PHP 官方建議頂格寫起始標(biāo)記,同時 省略 結(jié)束標(biāo)記。 這樣可以確保整個 PHP 文件都是 PHP 代碼,沒有任何輸出,否則當(dāng)你包含該文件后,設(shè)置 Header 和 Cookie 時會遇到一些麻煩 [注]. 注:Header 和 Cookie 必須在輸出任何內(nèi)容之前被發(fā)送。 數(shù)組簡寫形式這是非常方便的一項特征!
Traits所謂Traits就是“構(gòu)件”,是用來替代繼承的一種機(jī)制。PHP中無法進(jìn)行多重繼承,但一個類可以包含多個Traits.
Traits還有很多神奇的功能,比如包含多個Traits, 解決沖突,修改訪問權(quán)限,為函數(shù)設(shè)置別名等等。Traits中也同樣可以包含Traits. 篇幅有限不能逐個舉例,詳情參見官網(wǎng) [注]. 注:http://www./manual/zh/language.oop5.traits.php 內(nèi)置 Web 服務(wù)器PHP從5.4開始內(nèi)置一個輕量級的Web服務(wù)器,不支持并發(fā),定位是用于開發(fā)和調(diào)試環(huán)境。在開發(fā)環(huán)境使用它的確非常方便。
這樣就在當(dāng)前目錄建立起了一個Web服務(wù)器,你可以通過 http://localhost:8000/ 來訪問。其中l(wèi)ocalhost是監(jiān)聽的ip,8000是監(jiān)聽的端口,可以自行修改。 很多應(yīng)用中,都會進(jìn)行URL重寫,所以PHP提供了一個設(shè)置路由腳本的功能:
這樣一來,所有的請求都會由index.php來處理。你還可以使用 XDebug 來進(jìn)行斷點調(diào)試。 細(xì)節(jié)修改PHP5.4 新增了動態(tài)訪問靜態(tài)方法的方式:
新增在實例化時訪問類成員的特征:
新增支持對函數(shù)返回數(shù)組的成員訪問解析(這種寫法在之前版本是會報錯的):
PHP5.5(2013起)yieldyield關(guān)鍵字用于當(dāng)函數(shù)需要返回一個迭代器的時候, 逐個返回值。
該函數(shù)的返回值是一個數(shù)組:
list() 用于 foreach可以用 list() 在 foreach 中解析嵌套的數(shù)組:
結(jié)果:
細(xì)節(jié)修改不推薦使用 mysql 函數(shù),推薦使用 PDO 或 MySQLi, 參見前文。不再支持Windows XP. 可用 MyClass::class 取到一個類的完整限定名(包括命名空間)。 empty() 支持表達(dá)式作為參數(shù)。 try-catch 結(jié)構(gòu)新增 finally 塊。 PHP5.6更好的常量定義常量時允許使用之前定義的常量進(jìn)行計算:
允許常量作為函數(shù)參數(shù)默認(rèn)值:
更好的可變函數(shù)參數(shù)用于代替 func_get_args()
同時可以在調(diào)用函數(shù)時,把數(shù)組展開為函數(shù)參數(shù):
命名空間命名空間支持常量和函數(shù):
|
|