PHP7——PHP的一次重大變革

一、寫在開頭


PHP7是PHP編程語言全新的一個版本,主要在性能方面獲得了極大的提升。官方的文檔顯示,PHP7可以達到PHP5.x版本兩倍的性能。同時還對PHP的語法做了梳理,提供了很多其他語言流行的語法格式。難能可貴的是,做了如此大的改動,PHP7的兼容性還是非常好的。對於絕大多數的應用來講,可以不用做修改即可遷移到PHP7版本。PHP7你值得擁有

PHP7——PHP的一次重大變革

PHP7你值得擁有

有人有疑問,為什麼沒有PHP6就直接PHP7了呢,實際上PHP6這個項目有過,只是後來取消了,但大量的功能已經在PHP5.x版本中得以實現。所以這一次直接就是PHP7。

二、PHP7的安裝


使用編譯安裝太麻煩了,這裡提供 Linux下的centos的安裝php7的方法:

1)安裝epel: yum -y install epel-release

2)更換rpm源,請根據自己的centos版本選擇相應的rpm源進行安裝:

Centos 5.X:

rpm -Uvhhttp://mirror.webtatic.com/yum/el5/latest.rpmCentOs6.x:

rpm -Uvhhttp://mirror.webtatic.com/yum/el6/latest.rpm

CentOs 7.X:

rpm -Uvhhttps://mirror.webtatic.com/yum/el7/epel-release.rpm

rpm -Uvhhttps://mirror.webtatic.com/yum/el7/webtatic-release.rpm

3)刪除之前的php版本:

yum remove php * php-common

4)安裝php7: yum install php70w

5)安裝成功並檢測: php -v

三、PHP7的新特性


1) 標量類型聲明: PHP 7 中的函數的形參類型聲明可以是標量了,即可以使用 string、int、float和 bool。

PHP7——PHP的一次重大變革

php7性能提升了2倍

2)NULL 合併運算符:

同時使用三元表達式和 isset()的情況,NULL 合併運算符使得變量存在且值不為NULL, 它就會返回自身的值,否則返回它的第二個操作數。

// 如果 $_GET['user'] 不存在返回 'nobody',否則返回 $_GET['user'] 的值

$username = $_GET['user'] ?? 'nobody';

// 類似的三元運算符

$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

?>

4) 太空船操作符(組合比較符)

3)太空船操作符用於比較兩個表達式。當$a大於、等於或小於$b時它分別返回-1、0或1。

// 整型

echo 1 <=> 1; // 0

echo 1 <=> 2; // -1

echo 2 <=> 1; // 1

4)通過 define() 定義常量數組

define('ANIMALS', [

'dog',

'cat',

'bird'

]);

echo ANIMALS[1]; // 輸出 "cat"

?>

四、PHP7的修改


1.【 變量處理機制修改】:

間接變量、屬性和方法引用都按照從左到右的順序進行解釋:

$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz’]

如果想改變解釋的順序,可以使用大括號:${$foo['bar']['baz’]}

global關鍵字現在只能引用簡單變量

global $$foo->bar; // 這種寫法不支持。

global ${$foo->bar}; // 需用大括號來達到效果。

引用賦值時自動創建的數組元素或者對象屬性順序和以前不同了。

$array = [];

$array["a"] =& $array["b"];

$array["b"] = 1;

var_dump($array);

PHP7產生的數組:["a" => 1, "b" => 1]

PHP5產生的數組:["b" => 1, "a" => 1]

2.【list()修改】

list()不再按照相反的順序賦值

list($array[], $array[], $array[]) = [1, 2, 3];

var_dump($array);

上面的代碼會返回一個數組:$array == [1, 2, 3] 而不是之前的 [3, 2, 1]

注意:只是賦值的順序發生變化,賦的值還是和原來一樣的。

空的list()賦值不再允許。

list() = $a;

list()不在支持字符串拆分功能

$string = "xy";

list($x, $y) = $string;

這段代碼最終的結果是:$x == null and $y == null (不會有提示)

PHP5運行的結果是: $x = "x" and $y = "y”.

除此之外,list()現在也適用於數組對象:

list($a, $b) = (object) new ArrayObject([0, 1]);

PHP7結果:$a == 0 and $b == 1.

PHP5結果:$a == null and $b == null.

3.【 foreach 修改】

foreach()循環對數組內部指針不再起作用。

$array = [0, 1, 2];

foreach ($array as &$val)

{

var_dump(current($array));

}

PHP7運行的結果會打印三次int(0),也就是說數組的內部指針並沒有改變。

之前運行的結果會打印int(1), int(2)和bool(false)

按照值進行循環的時候,foreach是對該數組的拷貝操作

foreach按照值進行循環的時候(by-value),foreach是對該數組的一個拷貝進行操作。這樣在循環過程中對數組做的修改是不會影響循環行為的。

$array = [0, 1, 2];

$ref =& $array; // Necessary to trigger the old behavior

foreach ($array as $val) {

var_dump($val);

unset($array[1]);

}

上面的代碼雖然在循環中把數組的第二個元素unset掉,但PHP7還是會把三個元素打印出來:(0 1 2)

之前老版本的PHP會把1跳過,只打印(0 2).

按照引用進行循環的時候,對數組的修改會影響循環。

如果在循環的時候是引用的方式,對數組的修改會影響循環行為。不過PHP7版本優化了很多場景下面位置的維護。比如在循環時往數組中追加元素。

$array = [0];

foreach ($array as &$val) {

var_dump($val);

$array[1] = 1;

}

上面的代碼中追加的元素也會參與循環,這樣PHP7會打印"int(0) int(1)",老版本只會打印"int(0)”。

4.【參數處理機制修改】

重複參數命名不再支持

重複的參數命名不再支持。比如下面的代碼執行的時候會報錯:

public function foo($a, $b, $unused, $unused) {

// ...

}

func_get_arg和func_get_args()調整

func_get_arg()和func_get_args()這兩個方法返回參數當前的值,而不是傳入時的值。當前的值有可能會被修改

function foo($x)

{

$x++;

var_dump(func_get_arg(0));

}

foo(1);

上面的代碼會打印2, 而不是1。如果想打印原始的值,調用的順序調整下即可。

同樣在打印異常回溯信息的時候也是顯示修改後的值。

function foo($x)

{

$x = 42;

throw new Exception;

}

foo("string");

PHP7的運行結果:Stack trace:

#0 file.php(4): foo(42)

#1 {main}

PHP5的運行結果:Stack trace:

#0 file.php(4): foo('string')

#1 {main}

這個調整不會影響代碼的行為,不過在調試的時候需要注意這個變化。

其他和參數有關的函數都是同樣的調整,比如debug_backtrace() .

五、如何升級當前項目代碼來兼容PHP7?


逐步剔除php7不支持的代碼

檢測工具:https://github.com/sstalle/php7cc

PHP7——PHP的一次重大變革

檢測不兼容PHP7的代碼

六、寫在最後


PHP7 2倍性能飆升,你心動了嗎,趕緊下載代碼運行吧~

附錄:

php7官方文檔:http://php.net/manual/zh/migration70.new-features.php

鳥哥的博客:http://www.laruence.com


分享到:


相關文章: