php 新特性

PHP 5.6

一、可使用表達式定義常量

https://php.net/manual/zh/migration56.new-features.phpphp

在以前的 PHP 版本中,必須使用靜態值來定義常量,聲明屬性以及指定函數參數默認值。 如今你可使用包括數值、字符串字面量以及其餘常量在內的數值表達式來 定義常量、聲明屬性以及設置函數參數默認值。html

<?php const ONE = 1; const TWO = ONE * 2; //定義常量時容許使用以前定義的常量進行計算 class C { const THREE = TWO + 1; const ONE_THIRD = ONE / self::THREE; const SENTENCE = 'The value of THREE is '.self::THREE; public function f($a = ONE + self::THREE) { //容許常量做爲函數參數默認值 return $a; } } echo (new C)->f()."\n"; echo C::SENTENCE; ?> 

能夠經過 const 關鍵字來定義類型爲 array 的常量。mysql

<?php const ARR = ['a', 'b']; echo ARR[0]; ?> 

二、使用 ... 運算符定義變長參數函數

如今能夠不依賴 func_get_args(), 使用 ... 運算符 來實現 變長參數函數。web

<?php function test(...$args) { print_r($args); } test(1,2,3); //輸出 Array ( [0] => 1 [1] => 2 [2] => 3 ) ?> 

三、使用 ** 進行冪運算

加入右鏈接運算符 ** 來進行冪運算。 同時還支持簡寫的 **= 運算符,表示進行冪運算並賦值。sql

printf(2 ** 3); // 8 $a = 2; $a **= 3; printf($a); // 8 

四、use function 以及 use const

use 運算符能夠在類中導入外部的函數和常量了。 對應的結構爲 use function 和 use const。數據庫

<?php namespace Name\Space { const FOO = 42; function f() { echo __FUNCTION__."\n"; } } namespace { use const Name\Space\FOO; use function Name\Space\f; echo FOO."\n"; f(); } ?> 

五、加入 hash_equals() 函數,以恆定的時間消耗來進行字符串比較,以免時序攻擊

<?php $expected = crypt('12345', '$2a$07$usesomesillystringforsalt$'); $incorrect = crypt('1234', '$2a$07$usesomesillystringforsalt$'); var_dump(hash_equals($expected, $incorrect)); // false ?> 

六、加入 __debugInfo()

當使用 var_dump() 輸出對象的時候,能夠用來控制要輸出的屬性和值。返回值必須是個數組。json

<?php class C { private $prop; public function __construct($val) { $this->prop = $val; } public function __debugInfo() { return array( "prop" => $this->prop ); } } var_dump(new C(42)); ?> 

PHP 5.5

一、新增 Generators

yield關鍵字用於當函數須要返回一個迭代器的時候,逐個返回值。segmentfault

function number10() { for($i = 1; $i <= 10; $i += 1) yield $i; } 

該函數的返回值是一個數組:數組

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

二、新增 finally 關鍵字

Finally處理流程:性能優化

三、foreach 支持 list()

foreach 支持經過 list() 將嵌套數組分離到單獨的變量。

<?php $array = [ [1, 2], [3, 4], ]; foreach ($array as list($a, $b)) { echo $a.$b\n"; } ?> 

四、empty() 支持傳入一個任意表達式,而不只是一個變量

<?php function always_false() { return false; } if (empty(always_false())) { echo 'This will be printed.'; } 

五、直接經過下標獲取訪問數組和字符串字面量的元素或字符

``` echo [1, 2, 3][0]; // 1 echo 'PHP'[0]; // P ``` 

六、新的密碼哈希 API

https://php.net/manual/zh/book.password.php

缺點是缺少互操做性,在須要和其餘語言對接時會比較麻煩。

//加密
echo $hash = password_hash('rasmuslerdorf', PASSWORD_DEFAULT); //輸出結果相似於:$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a //驗證 if(password_verify('rasmuslerdorf','$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a')) { echo "密碼正確"; } else { echo "密碼錯誤"; } 

七、新增 boolval() 函數

PHP已經實現了strval、intval和floatval的函數。爲了達到一致性將添加boolval函數。

八、新增 array_column() 函數

可用來返回數組中指定的一列。

$records = array( array('id' => 2135,'name' => 'John'), array('id' => 3245,'name' => 'Smith'), array('id' => 5342,'name' => 'Peter') ); //從結果集中取出 name 列 $names = array_column($records, 'name'); print_r($names); //從結果集中總取出 name 列,用相應的 id 做爲鍵值 $names = array_column($records, 'name', 'id'); print_r($names); 

PHP 5.4

一、新增 Traits

https://php.net/manual/zh/language.oop5.traits.php

// Traits不能被單獨實例化,只能被類所包含 trait SayWorld { public function sayHello() { echo 'World!'; } } class MyHelloWorld { // 將SayWorld中的成員包含進來 use SayWorld; } $xxoo = new MyHelloWorld(); // sayHello() 函數是來自 SayWorld 構件的 $xxoo->sayHello(); 

二、新增短數組語法

// 原來的數組寫法 $arr = array("key" => "value", "key2" => "value2"); $arr = array(1,2,3,4); // 簡寫形式 $arr = ["key" => "value", "key2" => "value2"]; $arr = [1,2,3,4]; 

三、新增支持對函數返回數組的成員訪問解析

print func()[0]; 

四、不管 php.ini 中是否設置 short_open_tag, 格式老是可用。

這種簡寫形式被稱爲 Short Open Tag, 在 PHP5.3 起被默認開啓,在 PHP5.4 起老是可用。 使用這種簡寫形式在 HTML 中嵌入 PHP 變量將會很是方便。

五、內置用於開發的 CLI 模式的 web server

//啓動Web服務器 php -S localhost:8000 //啓動時指定根目錄 php -S localhost:8000 -t /home/me/public_html/foo //使用路由(Router)腳本 php -S localhost:8000 index.php //全部的請求都會由index.php來處理。 

六、新增在實例化時訪問類成員

(new Foo)->bar(); 

七、新增了動態訪問靜態方法的方式

$func = "funcXXOO"; A::{$func}(); 

八、閉包支持 $this

九、新增二進制直接量

$bin = bindec('110011'); //以前須要這樣寫 $bin = 0b110011; echo $bin; //51 

十、session提供了上傳進度支持

經過 $_SESSION["upload_progress_name"] 就能夠得到當前文件上傳的進度信息,結合 Ajax 就能很容易的實現上傳進度條。

十一、默認使用 mysqlnd

如今mysql, mysqli, pdo_mysql默認使用mysqlnd本地庫,在PHP5.4之前須要:./configure --with-mysqli=mysqlnd
如今:./configure --with-mysqli

十二、讓 json 更懂中文

echo json_encode("中文", JSON_UNESCAPED_UNICODE); //"中文" 

1三、default_charset從ISO-8859-1已經變爲UTF-8

默認發送「Content-Type: text/html; charset=utf-8」

PHP 5.3

一、支持命名空間

https://php.net/manual/zh/language.namespaces.php

<?php namespace my\name; // 定義命名空間 class MyClass {} const MYCONST = 1; $a = new \my\name\MyClass; $class = __NAMESPACE__.'\MyClass'; $b = new $class; $c = \my\name\MYCONST; $d = namespace\MYCONST; var_dump($a,$b,$c,$d); /* object(my\name\MyClass)#1 (0) { } object(my\name\MyClass)#2 (0) { } int(1) int(1) */ ?> 

二、增長後期靜態綁定

https://php.net/manual/zh/language.oop5.late-static-bindings.php

在PHP中,咱們能夠在類中經過self關鍵字或者CLASS來判斷或調用當前類。但有一個問題,若是咱們是在子類中調用,獲得的結果將是父類。由於在繼承父類的時候,靜態成員就已經被綁定了。

class A { static public function callFuncXXOO() { print self::funcXXOO(); } static public function funcXXOO() { return "A::funcXXOO()"; } } class B extends A { static public function funcXXOO() { return "B::funcXXOO"; } } $b = new B; $b->callFuncXXOO(); 

輸出是:

A::funcXXOO()

PHP 5.3.0中增長了一個static關鍵字來引用當前類,即實現了延遲靜態綁定:

class A { static public function callFuncXXOO() { print static::funcXXOO(); } // ... } // ... 

這樣就會像預期同樣輸出了:

B::funcXXOO

三、增長 goto 操做符

https://php.net/manual/zh/control-structures.goto.php

goto 語句有可能會致使程序流程不清晰,可讀性減弱,但在某些狀況下具備其獨特的方便之處,例如中斷深度嵌套的循環和 if 語句。

<?php goto test; echo '1'; test: echo '2'; ?> //以上運行時會輸出 2 

四、添加了原生的閉包(Lambda/匿名函數)支持

https://php.net/manual/zh/functions.anonymous.php

五、新增兩個魔術方法, __callStatic 和 __invoke

https://php.net/manual/zh/language.oop5.magic.php

用靜態方式中調用一個不可訪問方法時,__callStatic() 會被調用。
當嘗試以調用函數的方式調用一個對象時,__invoke() 方法會被自動調用。

class A { public function __invoke($str) { print "A::__invoke(): {$str}"; } } $a = new A; $a("Hello World"); 

輸出是:

A::__invoke(): Hello World 

六、添加 Nowdoc 語法支持

https://php.net/manual/zh/language.types.string.php#language.types.str...

<?php
$str = <<<'EOD' Example of string spanning multiple lines using nowdoc syntax. EOD; 

就象 heredoc 結構相似於雙引號字符串,Nowdoc 結構是相似於單引號字符串的。Nowdoc 結構很象 heredoc 結構,可是 nowdoc 中不進行解析操做。

七、Heredoc 結構中能夠用雙引號來聲明標識符了。

https://php.net/manual/zh/language.types.string.php#language.types.str...

<?php echo <<<"FOOBAR" Hello World! FOOBAR; ?> 

八、const 關鍵字可用來在類定義以外定義常量了

https://php.net/manual/zh/language.constants.syntax.php

<?php define("CONSTANT_A", "Hello world"); const CONSTANT_B = 'Hello World'; 

const 形式僅適用於常量,不適用於運行時才能求值的表達式:

// 正確 const XXOO = 1234; // 錯誤 const XXOO = 2 * 617; 

和使用 define() 來定義常量不一樣的是,使用 const 關鍵字定義常量必須處於最頂端的做用域,由於用此方法是在編譯時定義的。即不能在函數內,循環內以及 if 語句以內用 const 來定義常量。

九、三元運算符能夠簡寫省略中間的部分

表達式 expr1 ?: expr3 ,當 expr1 爲 TRUE 時返回 expr1,不然返回 expr3。

十、異常能夠嵌套了

<?php class MyException extends Exception { } class Test { public function testing() { try { try { throw new MyException('foo!'); } catch (MyException $e) { /* rethrow it */ throw $e; } } catch (Exception $e) { var_dump($e->getMessage()); } } } $foo = new Test; $foo->testing(); ?> 

十一、能夠動態訪問靜態變量了

<?php class C { public static $foo = 123; } $a = "C"; echo $a::$foo; ?> 

上邊運行時輸出:

123

十二、mail()函數支持記錄發送日誌了

在配置文件 php.ini 中可設置日誌路徑。參數名:mail.log

參考資料

一、https://php.net/manual/zh/migration53.new-features.php
二、https://php.net/manual/zh/migration54.new-features.php
三、https://php.net/manual/zh/migration55.new-features.php
四、https://php.net/manual/zh/migration56.new-features.php
五、http://segmentfault.com/a/1190000000403307
六、http://blog.csdn.net/heiyeshuwu/article/details/16884725

 

你可能感興趣的文章


本文采用  署名-相同方式共享 3.0 中國大陸許可協議,分享、演繹需署名且使用相同方式共享。

討論區

 

... 運算符,2 ** 3這是要Python的節奏呀

 蘇生不惑 · 2015年05月26日

 

關於 __debugInfo() 魔術方法,須要返回一個 array,因此示例中應該:

public function __debugInfo() { return array($this->prop); } 

 mengzyou · 2015年05月28日

 

這些新特性都不知道啊! 真是給很大幫助了!

 ChristLand · 2015年05月28日

 
回覆  mengzyou

謝謝你。已經修正。

 wdd2007 · 2015年05月29日

 

 

PHP5各個版本的新功能和新特性總結

做者: 字體:[增長 減少] 類型:轉載 時間:2014-03-16 我要評論

由於 PHP 那「集百家之長」的蛋疼語法,加上社區氛圍很差,不少人對新版本,新特徵並沒有興趣。本文將會介紹自 PHP5.2 起,直至 PHP5.6 中增長的新特徵
 

本文目錄:
PHP5.2 之前:autoload, PDO 和 MySQLi, 類型約束
PHP5.2:JSON 支持
PHP5.3:棄用的功能,匿名函數,新增魔術方法,命名空間,後期靜態綁定,Heredoc 和 Nowdoc, const, 三元運算符,Phar
PHP5.4:Short Open Tag, 數組簡寫形式,Traits, 內置 Web 服務器,細節修改
PHP5.5:yield, list() 用於 foreach, 細節修改
PHP5.6: 常量加強,可變函數參數,命名空間加強

1、PHP5.2之前(2006前)
順便介紹一下 PHP5.2 已經出現但值得介紹的特徵。
autoload
你們可能都知道 __autoload() 函數,若是定義了該函數,那麼當在代碼中使用一個未定義的類的時候,該函數就會被調用,你能夠在該函數中加載相應的類實現文件,如:

複製代碼代碼以下:
function __autoload($classname)
{
    require_once("{$classname}.php")
}

但該函數已經不被建議使用,緣由是一個項目中僅能有一個這樣的 __autoload() 函數,由於 PHP 不容許函數重名。但當你使用一些類庫的時候,不免會出現多個 autoload 函數的須要,因而 spl_autoload_register() 取而代之:
複製代碼代碼以下:
spl_autoload_register(function($classname)
{
    require_once("{$classname}.php")
});

spl_autoload_register() 會將一個函數註冊到 autoload 函數列表中,當出現未定義的類的時候,SPL [注] 會按照註冊的倒序逐個調用被註冊的 autoload 函數,這意味着你可使用 spl_autoload_register() 註冊多個 autoload 函數.
注:SPL: Standard PHP Library, 標準 PHP 庫, 被設計用來解決一些經典問題(如數據結構).

 

PDO 和 MySQLi
即 PHP Data Object, PHP 數據對象,這是 PHP 的新式數據庫訪問接口。
按照傳統的風格,訪問 MySQL 數據庫應該是這樣子:

複製代碼代碼以下:
// 鏈接到服務器,選擇數據庫
$conn = mysql_connect("localhost", "user", "password");
mysql_select_db("database");

 

// 執行 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);


爲了可以讓代碼實現數據庫無關,即一段代碼同時適用於多種數據庫(例如以上代碼僅僅適用於MySQL),PHP 官方設計了 PDO.
除此以外,PDO 還提供了更多功能,好比:

 

1.面向對象風格的接口
2.SQL預編譯(prepare), 佔位符語法
3.更高的執行效率,做爲官方推薦,有特別的性能優化
4.支持大部分SQL數據庫,更換數據庫無需改動代碼

上面的代碼用 PDO 實現將會是這樣:

複製代碼代碼以下:
// 鏈接到數據庫
$conn = new PDO("mysql:host=localhost;dbname=database", "user", "password");

 

// 預編譯SQL, 綁定參數
$query = $conn->prepare("SELECT * FROM `table` WHERE `type` = :type");
$query->bindParam("type", $_POST['type']);

// 執行查詢並打印結果
foreach($query->execute() as $row)
{
    foreach($row as $k => $v)
        print "{$k}: {$v}\n";
}


PDO 是官方推薦的,更爲通用的數據庫訪問方式,若是你沒有特殊需求,那麼你最好學習和使用 PDO.
但若是你須要使用 MySQL 所特有的高級功能,那麼你可能須要嘗試一下 MySQLi, 由於 PDO 爲了可以同時在多種數據庫上使用,不會包含那些 MySQL 獨有的功能。

 

MySQLi 是 MySQL 的加強接口,同時提供面向過程和麪向對象接口,也是目前推薦的 MySQL 驅動,舊的C風格 MySQL 接口將會在從此被默認關閉。
MySQLi 的用法和以上兩段代碼相比,沒有太多新概念,在此再也不給出示例,能夠參見 PHP 官網文檔 [注]。

注:http://www.php.net/manual/en/mysqli.quickstart.php

類型約束
經過類型約束能夠限制參數的類型,不過這一機制並不完善,目前僅適用於類和 callable(可執行類型) 以及 array(數組), 不適用於 string 和 int.

複製代碼代碼以下:
// 限制第一個參數爲 MyClass, 第二個參數爲可執行類型,第三個參數爲數組
function MyFunction(MyClass $a, callable $b, array $c)
{
    // ...
}

 

PHP5.2(2006-2011):JSON 支持

包括 json_encode(), json_decode() 等函數,JSON 算是在 Web 領域很是經常使用的數據交換格式,能夠被 JS 直接支持,JSON 其實是 JS 語法的一部分。
JSON 系列函數,能夠將 PHP 中的數組結構與 JSON 字符串進行轉換:

複製代碼代碼以下:
$array = ["key" => "value", "array" => [1, 2, 3, 4]];
$json = json_encode($array);
echo "{$json}\n";

 

$object = json_decode($json);
print_r($object);


輸出:
複製代碼代碼以下:
{"key":"value","array":[1,2,3,4]}
stdClass Object
(
    [key] => value
    [array] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
        )
)

值得注意的是 json_decode() 默認會返回一個對象而非數組,若是須要返回數組須要將第二個參數設置爲 true.

 

PHP5.3(2009-2012)
PHP5.3 算是一個很是大的更新,新增了大量新特徵,同時也作了一些不向下兼容的修改。
【PHP5.3棄用的功能】:如下幾個功能被棄用,若在配置文件中啓用,則 PHP 會在運行時發出警告。

Register Globals
這是 php.ini 中的一個選項(register_globals), 開啓後會將全部表單變量($_GET和$_POST)註冊爲全局變量.
看下面的例子:

複製代碼代碼以下:
if(isAuth())
    $authorized = true;
if($authorized)
    include("page.php");

這段代碼在經過驗證時,將 $authorized 設置爲 true. 而後根據 $authorized 的值來決定是否顯示頁面.
但因爲並無事先把 $authorized 初始化爲 false, 當 register_globals 打開時,可能訪問 /auth.php?authorized=1 來定義該變量值,繞過身份驗證。
該特徵屬於歷史遺留問題,在 PHP4.2 中被默認關閉,在 PHP5.4 中被移除。

 

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), 常常被用來臨時性地建立一個無名函數,用於回調函數等用途。

複製代碼代碼以下:
$func = function($arg)
{
    print $arg;
};

 

$func("Hello World");


以上代碼定義了一個匿名函數,並賦值給了 $func.
能夠看到定義匿名函數依舊使用 function 關鍵字,只不過省略了函數名,直接是參數列表。
而後咱們又調用了 $func 所儲存的匿名函數。
匿名函數還能夠用 use 關鍵字來捕捉外部變量:
複製代碼代碼以下:
function arrayPlus($array, $num)
{
    array_walk($array, function(&$v) use($num){
        $v += $num;
    });
}

上面的代碼定義了一個 arrayPlus() 函數(這不是匿名函數), 它會將一個數組($array)中的每一項,加上一個指定的數字($num).
在 arrayPlus() 的實現中,咱們使用了 array_walk() 函數,它會爲一個數組的每一項執行一個回調函數,即咱們定義的匿名函數。
在匿名函數的參數列表後,咱們用 use 關鍵字將匿名函數外的 $num 捕捉到了函數內,以便知道到底應該加上多少。

 

魔術方法:__invoke(), __callStatic()
PHP 的面向對象體系中,提供了若干「魔術方法」,用於實現相似其餘語言中的「重載」,如在訪問不存在的屬性、方法時觸發某個魔術方法。
隨着匿名函數的加入,PHP 引入了一個新的魔術方法 __invoke().
該魔術方法會在將一個對象做爲函數調用時被調用:

複製代碼代碼以下:
class A
{
    public function __invoke($str)
    {
        print "A::__invoke(): {$str}";
    }
}

 

$a = new A;
$a("Hello World");


輸出毫無疑問是:
複製代碼代碼以下:
A::__invoke(): Hello World

__callStatic() 則會在調用一個不存在的靜態方法時被調用。

 


命名空間
PHP的命名空間有着前無古人後無來者的無比蛋疼的語法:

複製代碼代碼以下:
<?php
// 命名空間的分隔符是反斜槓,該聲明語句必須在文件第一行。
// 命名空間中能夠包含任意代碼,但只有 **類, 函數, 常量** 受命名空間影響。
namespace XXOO\Test;

 

// 該類的完整限定名是 \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
}


更多有關命名空間的語法介紹請參見官網 [注].
命名空間時常和 autoload 一同使用,用於自動加載類實現文件:

 


spl_autoload_register(
    function ($class) {
        spl_autoload(str_replace("\\", "/", $class));
    }
);
當你實例化一個類 \XXOO\Test\A 的時候,這個類的完整限定名會被傳遞給 autoload 函數,autoload 函數將類名中的命名空間分隔符(反斜槓)替換爲斜槓,幷包含對應文件。
這樣能夠實現類定義文件分級儲存,按需自動加載。
注:http://www.php.net/manual/zh/language.namespaces.php

後期靜態綁定
PHP 的 OPP 機制,具備繼承和相似虛函數的功能,例如以下的代碼:

複製代碼代碼以下:
class A
{
    public function callFuncXXOO()
    {
        print $this->funcXXOO();
    }

 

    public function funcXXOO()
    {
        return "A::funcXXOO()";
    }
}

class B extends A
{
    public function funcXXOO()
    {
        return "B::funcXXOO";
    }
}

$b = new B;
$b->callFuncXXOO();


輸出是:
複製代碼代碼以下:
B::funcXXOO

能夠看到,當在 A 中使用 $this->funcXXOO() 時,體現了「虛函數」的機制,實際調用的是 B::funcXXOO().
然而若是將全部函數都改成靜態函數:
複製代碼代碼以下:
class A
{
    static public function callFuncXXOO()
    {
        print self::funcXXOO();
    }

 

    static public function funcXXOO()
    {
        return "A::funcXXOO()";
    }
}

class B extends A
{
    static public function funcXXOO()
    {
        return "B::funcXXOO";
    }
}

$b = new B;
$b->callFuncXXOO();


狀況就沒這麼樂觀了,輸出是:
複製代碼代碼以下:
A::funcXXOO()

這是由於 self 的語義原本就是「當前類」,因此 PHP5.3 給 static 關鍵字賦予了一個新功能:後期靜態綁定:
複製代碼代碼以下:
class A
{
    static public function callFuncXXOO()
    {
        print static::funcXXOO();
    }

 

    // ...
}

// ...


這樣就會像預期同樣輸出了:
複製代碼代碼以下:
B::funcXXOO

 

Heredoc 和 Nowdoc

PHP5.3 對 Heredoc 以及 Nowdoc 進行了一些改進,它們都用於在 PHP 代碼中嵌入大段字符串。
Heredoc 的行爲相似於一個雙引號字符串:

複製代碼代碼以下:
$name = "MyName";
echo <<< TEXT
My name is "{$name}".
TEXT;

Heredoc 以三個左尖括號開始,後面跟一個標識符(TEXT), 直到一個一樣的頂格的標識符(不能縮進)結束。
就像雙引號字符串同樣,其中能夠嵌入變量。

 

Heredoc 還能夠用於函數參數,以及類成員初始化:

複製代碼代碼以下:
var_dump(<<<EOD
Hello World
EOD
);

 

class A
{
    const xx = <<< EOD
Hello World
EOD;

    public $oo = <<< EOD
Hello World
EOD;
}


Nowdoc 的行爲像一個單引號字符串,不能在其中嵌入變量,和 Heredoc 惟一的區別就是,三個左尖括號後的標識符要以單引號括起來:
複製代碼代碼以下:
$name = "MyName";
echo <<< 'TEXT'
My name is "{$name}".
TEXT;

輸出:
複製代碼代碼以下:
My name is "{$name}".

 

用 const 定義常量

PHP5.3 起同時支持在全局命名空間和類中使用 const 定義常量。
舊式風格:

複製代碼代碼以下:
define("XOOO", "Value");

新式風格:
const XXOO = "Value";
const 形式僅適用於常量,不適用於運行時才能求值的表達式:
複製代碼代碼以下:
// 正確
const XXOO = 1234;
// 錯誤
const XXOO = 2 * 617;

 

三元運算符簡寫形式
舊式風格:

複製代碼代碼以下:
echo $a ? $a : "No Value";

可簡寫成:
複製代碼代碼以下:
echo $a ?: "No Value";

即若是省略三元運算符的第二個部分,會默認用第一個部分代替。

 

Phar

Phar即PHP Archive, 起初只是Pear中的一個庫而已,後來在PHP5.3被從新編寫成C擴展並內置到 PHP 中。
Phar用來將多個 .php 腳本打包(也能夠打包其餘文件)成一個 .phar 的壓縮文件(一般是ZIP格式)。
目的在於模仿 Java 的 .jar, 不對,目的是爲了讓發佈PHP應用程序更加方便。同時還提供了數字簽名驗證等功能。
.phar 文件能夠像 .php 文件同樣,被PHP引擎解釋執行,同時你還能夠寫出這樣的代碼來包含(require) .phar 中的代碼:

複製代碼代碼以下:
require("xxoo.phar");
require("phar://xxoo.phar/xo/ox.php");

更多信息請參見官網 [注].
注:http://www.php.net/manual/zh/phar.using.intro.php

 

PHP5.4(2012-2013)

Short Open Tag
Short Open Tag 自 PHP5.4 起老是可用。
在這裏集中講一下有關 PHP 起止標籤的問題。即:

複製代碼代碼以下:
<?php
// Code...
?>

一般就是上面的形式,除此以外還有一種簡寫形式:
複製代碼代碼以下:
<? /* Code... */ ?>

還能夠把
複製代碼代碼以下:
<?php echo $xxoo;?>

簡寫成:
複製代碼代碼以下:
<?= $xxoo;?>

這種簡寫形式被稱爲 Short Open Tag, 在 PHP5.3 起被默認開啓,在 PHP5.4 起老是可用。
使用這種簡寫形式在 HTML 中嵌入 PHP 變量將會很是方便。

 

對於純 PHP 文件(如類實現文件), PHP 官方建議頂格寫起始標記,同時 省略 結束標記。
這樣能夠確保整個 PHP 文件都是 PHP 代碼,沒有任何輸出,不然當你包含該文件後,設置 Header 和 Cookie 時會遇到一些麻煩 [注].

注:Header 和 Cookie 必須在輸出任何內容以前被髮送。

數組簡寫形式
這是很是方便的一項特徵!

複製代碼代碼以下:
// 原來的數組寫法
$arr = array("key" => "value", "key2" => "value2");
// 簡寫形式
$arr = ["key" => "value", "key2" => "value2"];

 

Traits
所謂Traits就是「構件」,是用來替代繼承的一種機制。PHP中沒法進行多重繼承,但一個類能夠包含多個Traits.

複製代碼代碼以下:
// Traits不能被單獨實例化,只能被類所包含
trait SayWorld
{
    public function sayHello()
    {
        echo 'World!';
    }
}

 

class MyHelloWorld
{
    // 將SayWorld中的成員包含進來
    use SayWorld;
}

$xxoo = new MyHelloWorld();
// sayHello() 函數是來自 SayWorld 構件的
$xxoo->sayHello();


Traits還有不少神奇的功能,好比包含多個Traits, 解決衝突,修改訪問權限,爲函數設置別名等等。
Traits中也一樣能夠包含Traits. 篇幅有限不能逐個舉例,詳情參見官網 [注].
注:http://www.php.net/manual/zh/language.oop5.traits.php

 

內置 Web 服務器
PHP從5.4開始內置一個輕量級的Web服務器,不支持併發,定位是用於開發和調試環境。
在開發環境使用它的確很是方便。

複製代碼代碼以下:
php -S localhost:8000

這樣就在當前目錄創建起了一個Web服務器,你能夠經過 http://localhost:8000/ 來訪問。
其中localhost是監聽的ip,8000是監聽的端口,能夠自行修改。

 

不少應用中,都會進行URL重寫,因此PHP提供了一個設置路由腳本的功能:

複製代碼代碼以下:
php -S localhost:8000 index.php

這樣一來,全部的請求都會由index.php來處理。
你還可使用 XDebug 來進行斷點調試。

 

細節修改
PHP5.4 新增了動態訪問靜態方法的方式:

複製代碼代碼以下:
$func = "funcXXOO";
A::{$func}();

新增在實例化時訪問類成員的特徵:
複製代碼代碼以下:
(new MyClass)->xxoo();

新增支持對函數返回數組的成員訪問解析(這種寫法在以前版本是會報錯的):
複製代碼代碼以下:
print func()[0];

 

PHP5.5(2013起)

yield
yield關鍵字用於當函數須要返回一個迭代器的時候, 逐個返回值。

複製代碼代碼以下:
function number10()
{
    for($i = 1; $i <= 10; $i += 1)
        yield $i;
}

該函數的返回值是一個數組:
複製代碼代碼以下:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list() 用於 foreach
能夠用 list() 在 foreach 中解析嵌套的數組:
複製代碼代碼以下:
$array = [
    [1, 2, 3],
    [4, 5, 6],
];

 

foreach ($array as list($a, $b, $c))
    echo "{$a} {$b} {$c}\n";


結果:
複製代碼代碼以下:
1 2 3
4 5 6

細節修改
不推薦使用 mysql 函數,推薦使用 PDO 或 MySQLi, 參見前文。
再也不支持Windows XP.
可用 MyClass::class 取到一個類的完整限定名(包括命名空間)。
empty() 支持表達式做爲參數。
try-catch 結構新增 finally 塊。

 

PHP5.6

更好的常量
定義常量時容許使用以前定義的常量進行計算:

複製代碼代碼以下:
const A = 2;
const B = A + 1;

 

class C
{
    const STR = "hello";
    const STR2 = self::STR + ", world";
}


容許常量做爲函數參數默認值:
複製代碼代碼以下:
function func($arg = C::STR2)

 

更好的可變函數參數
用於代替 func_get_args()

複製代碼代碼以下:
function add(...$args)
{
    $result = 0;
    foreach($args as $arg)
        $result += $arg;
    return $result;
}

同時能夠在調用函數時,把數組展開爲函數參數:
複製代碼代碼以下:
$arr = [2, 3];
add(1, ...$arr);

// 結果爲 6
命名空間
命名空間支持常量和函數:
複製代碼代碼以下:
namespace Name\Space {
    const FOO = 42;
    function f() { echo __FUNCTION__."\n"; }
}

 

namespace {
    use const Name\Space\FOO;
    use function Name\Space\f;

    echo FOO."\n";    f();}

相關文章
相關標籤/搜索