因為 PHP 那“集百家之長”的蛋疼語法,加上社區(qū)氛圍不好,很多人對新版本,新特征并無興趣。本文將會介紹自 PHP5.2 起,直至 PHP5.6 中增加的新特征
本文目錄:
PHP5.2 以前:autoload, PDO 和 MySQLi,
類型約束
PHP5.2:JSON 支持
PHP5.3:棄用的功能,匿名函數,新增魔術方法,命名空間,后期靜態(tài)綁定,Heredoc 和 Nowdoc,
const, 三元運算符,Phar
PHP5.4:Short Open Tag, 數組簡寫形式,Traits, 內置 Web
服務器,細節(jié)修改
PHP5.5:yield, list() 用于 foreach, 細節(jié)修改
PHP5.6:
常量增強,可變函數參數,命名空間增強
一、PHP5.2以前(2006前)
順便介紹一下 PHP5.2
已經出現但值得介紹的特征。
autoload
大家可能都知道 __autoload()
函數,如果定義了該函數,那么當在代碼中使用一個未定義的類的時候,該函數就會被調用,你可以在該函數中加載相應的類實現文件,如:
PDO 和 MySQLi
即 PHP Data Object, PHP 數據對象,這是 PHP
的新式數據庫訪問接口。
按照傳統的風格,訪問 MySQL 數據庫應該是這樣子:
// 執(zhí)行 SQL 查詢
$type = $_POST['type'];
$sql = "SELECT * FROM `table`
WHERE `type` = {$type}";
$result = mysql_query($sql);
// 打印結果
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
foreach($row as $k => $v)
print "{$k}: {$v}\n";
}
//
釋放結果集,關閉連接
mysql_free_result($result);
mysql_close($conn);
1.面向對象風格的接口
2.SQL預編譯(prepare),
占位符語法
3.更高的執(zhí)行效率,作為官方推薦,有特別的性能優(yōu)化
4.支持大部分SQL數據庫,更換數據庫無需改動代碼
上面的代碼用 PDO 實現將會是這樣:
// 預編譯SQL, 綁定參數
$query = $conn->prepare("SELECT * FROM `table` WHERE
`type` = :type");
$query->bindParam("type", $_POST['type']);
// 執(zhí)行查詢并打印結果
foreach($query->execute() as $row)
{
foreach($row as $k => $v)
print "{$k}:
{$v}\n";
}
MySQLi 是 MySQL 的增強接口,同時提供面向過程和面向對象接口,也是目前推薦的 MySQL 驅動,舊的C風格 MySQL
接口將會在今后被默認關閉。
MySQLi 的用法和以上兩段代碼相比,沒有太多新概念,在此不再給出示例,可以參見 PHP 官網文檔 [注]。
注:http://www.php.net/manual/en/mysqli.quickstart.php
類型約束
通過類型約束可以限制參數的類型,不過這一機制并不完善,目前僅適用于類和 callable(可執(zhí)行類型)
以及 array(數組), 不適用于 string 和 int.
PHP5.2(2006-2011):JSON 支持
包括 json_encode(), json_decode() 等函數,JSON 算是在 Web 領域非常常用的數據交換格式,可以被 JS
直接支持,JSON 實際上是 JS 語法的一部分。
JSON 系列函數,可以將 PHP 中的數組結構與 JSON 字符串進行轉換:
$object = json_decode($json);
print_r($object);
PHP5.3(2009-2012)
PHP5.3
算是一個非常大的更新,新增了大量新特征,同時也做了一些不向下兼容的修改。
【PHP5.3棄用的功能】:以下幾個功能被棄用,若在配置文件中啟用,則 PHP
會在運行時發(fā)出警告。
Register Globals
這是 php.ini 中的一個選項(register_globals),
開啟后會將所有表單變量($_GET和$_POST)注冊為全局變量.
看下面的例子:
Magic Quotes
對應 php.ini 中的選項 magic_quotes_gpc, 這個特征同樣屬于歷史遺留問題,已經在 PHP5.4
中移除。
該特征會將所有用戶輸入進行轉義,這看上去不錯,在第一章我們提到過要對用戶輸入進行轉義。
但是 PHP 并不知道哪些輸入會進入 SQL ,
哪些輸入會進入 Shell, 哪些輸入會被顯示為 HTML, 所以很多時候這種轉義會引起混亂。
Safe Mode
很多虛擬主機提供商使用 Safe Mode 來隔離多個用戶,但 Safe Mode 存在諸多問題,例如某些擴展并不按照 Safe
Mode
來進行權限控制。
PHP官方推薦使用操作系統的機制來進行權限隔離,讓Web服務器以不同的用戶權限來運行PHP解釋器,請參見第一章中的最小權限原則.
【PHP5.3的新增、改進】
匿名函數
也叫閉包(Closures), 經常被用來臨時性地創(chuàng)建一個無名函數,用于回調函數等用途。
$func("Hello World");
魔術方法:__invoke(), __callStatic()
PHP
的面向對象體系中,提供了若干“魔術方法”,用于實現類似其他語言中的“重載”,如在訪問不存在的屬性、方法時觸發(fā)某個魔術方法。
隨著匿名函數的加入,PHP
引入了一個新的魔術方法 __invoke().
該魔術方法會在將一個對象作為函數調用時被調用:
$a = new A;
$a("Hello World");
命名空間
PHP的命名空間有著前無古人后無來者的無比蛋疼的語法:
// 該類的完整限定名是 \XXOO\Test\A , 其中第一個反斜杠表示全局命名空間。
class A{}
// 你還可以在已經文件中定義第二個命名空間,接下來的代碼將都位于 \Other\Test2 .
namespace
Other\Test2;
// 實例化來自其他命名空間的對象:
$a = new \XXOO\Test\A;
class B{}
// 你還可以用花括號定義第三個命名空間
namespace Other {
// 實例化來自子命名空間的對象:
$b
= new Test2\B;
// 導入來自其他命名空間的名稱,并重命名,
// 注意只能導入類,不能用于函數和常量。
use
\XXOO\Test\A as ClassA
}
spl_autoload_register(
function ($class) {
spl_autoload(str_replace("\\", "/", $class));
}
);
當你實例化一個類
\XXOO\Test\A 的時候,這個類的完整限定名會被傳遞給 autoload 函數,autoload
函數將類名中的命名空間分隔符(反斜杠)替換為斜杠,并包含對應文件。
這樣可以實現類定義文件分級儲存,按需自動加載。
注:http://www.php.net/manual/zh/language.namespaces.php
后期靜態(tài)綁定
PHP 的 OPP 機制,具有繼承和類似虛函數的功能,例如如下的代碼:
public function funcXXOO()
{
return
"A::funcXXOO()";
}
}
class B extends A
{
public function funcXXOO()
{
return "B::funcXXOO";
}
}
$b = new B;
$b->callFuncXXOO();
static public function funcXXOO()
{
return
"A::funcXXOO()";
}
}
class B extends A
{
static public function funcXXOO()
{
return "B::funcXXOO";
}
}
$b = new B;
$b->callFuncXXOO();
// ...
}
// ...
B::funcXXOO
Heredoc 和 Nowdoc
PHP5.3 對 Heredoc 以及 Nowdoc 進行了一些改進,它們都用于在 PHP 代碼中嵌入大段字符串。
Heredoc
的行為類似于一個雙引號字符串:
Heredoc 還可以用于函數參數,以及類成員初始化:
class A
{
const xx = <<< EOD
Hello World
EOD;
public $oo = <<< EOD
Hello
World
EOD;
}
My name is "{$name}".
用 const 定義常量
PHP5.3 起同時支持在全局命名空間和類中使用 const 定義常量。
舊式風格:
// 正確
const XXOO = 1234;
// 錯誤
const XXOO = 2 * 617;
三元運算符簡寫形式
舊式風格:
Phar
Phar即PHP Archive, 起初只是Pear中的一個庫而已,后來在PHP5.3被重新編寫成C擴展并內置到 PHP 中。
Phar用來將多個
.php 腳本打包(也可以打包其他文件)成一個 .phar 的壓縮文件(通常是ZIP格式)。
目的在于模仿 Java 的 .jar,
不對,目的是為了讓發(fā)布PHP應用程序更加方便。同時還提供了數字簽名驗證等功能。
.phar 文件可以像 .php
文件一樣,被PHP引擎解釋執(zhí)行,同時你還可以寫出這樣的代碼來包含(require) .phar 中的代碼:
PHP5.4(2012-2013)
Short Open Tag
Short Open Tag 自 PHP5.4
起總是可用。
在這里集中講一下有關 PHP 起止標簽的問題。即:
對于純 PHP 文件(如類實現文件), PHP 官方建議頂格寫起始標記,同時 省略 結束標記。
這樣可以確保整個 PHP 文件都是 PHP
代碼,沒有任何輸出,否則當你包含該文件后,設置 Header 和 Cookie 時會遇到一些麻煩 [注].
注:Header 和 Cookie 必須在輸出任何內容之前被發(fā)送。
數組簡寫形式
這是非常方便的一項特征!
// 原來的數組寫法
$arr = array("key" => "value",
"key2" => "value2");
// 簡寫形式
$arr = ["key" => "value", "key2" => "value2"];
Traits
所謂Traits就是“構件”,是用來替代繼承的一種機制。PHP中無法進行多重繼承,但一個類可以包含多個Traits.
class MyHelloWorld
{
// 將SayWorld中的成員包含進來
use
SayWorld;
}
$xxoo = new MyHelloWorld();
// sayHello() 函數是來自 SayWorld
構件的
$xxoo->sayHello();
內置 Web
服務器
PHP從5.4開始內置一個輕量級的Web服務器,不支持并發(fā),定位是用于開發(fā)和調試環(huán)境。
在開發(fā)環(huán)境使用它的確非常方便。
很多應用中,都會進行URL重寫,所以PHP提供了一個設置路由腳本的功能:
細節(jié)修改
PHP5.4 新增了動態(tài)訪問靜態(tài)方法的方式:
print func()[0];
PHP5.5(2013起)
yield
yield關鍵字用于當函數需要返回一個迭代器的時候, 逐個返回值。
foreach ($array as list($a, $b, $c))
echo "{$a} {$b}
{$c}\n";
PHP5.6
更好的常量
定義常量時允許使用之前定義的常量進行計算:
class C
{
const STR = "hello";
const STR2 = self::STR + ",
world";
}
function func($arg = C::STR2)
更好的可變函數參數
用于代替 func_get_args()
命名空間
命名空間支持常量和函數:
namespace {
use const Name\Space\FOO;
use function
Name\Space\f;
echo FOO."\n";
f();
}
上一篇:php版本發(fā)展的歷史
掃一掃 加微信咨詢