截止到目前爲止,PHP官方已經發布了php7的RC5版本,預計在11月份左右會發布第一個正式版本!現在來說php7的重大特性肯定已經是定型了,不會再有什麼變動了。後續一些版本的迭代主要也就是修修bug,優化之類的。下面就來說話我們一直期待的php7會有那些主要的變化了。。。
新特性預覽
1
2
3
4
5
6
7
8
9
10
11
|
ZEND引擎升級到Zend Engine 3,也就是所謂的PHP NG
增加抽象語法樹,使編譯更加科學
64位的INT支持
統一的變量語法
原聲的TLS - 對擴展開發有意義
一致性foreach循環的改進
新增 <=>、**、?? 、\u{xxxx}操作符
增加了返回類型的聲明
增加了標量類型的聲明
核心錯誤可以通過異常捕獲了
增加了上下文敏感的詞法分析
|
移除的一些特性
1.移除一些舊的擴展,被移遷移到了PECL(例如:mysql)
2.移除SAPIs的支持
3.<?和<? language=「php」這樣的標籤被移除了
4.16進制的字符串轉換被廢除了
1
2
3
4
5
|
//PHP5
"0x10"
==
"16"
//PHP7
"0x10"
!=
"16"
|
5.HTTP_RAW_POST_DATA移除了(可以使用php://input替代)
6.靜態函數裏面不再支持通過一個不兼容的$this調用一個非靜態的函數了
$o = & new className{},不再支持這樣的寫法
7.php.ini文件移除了#作爲註釋,統一用;去註釋
一些行爲的改變
不在支持函數定義同名參數
類型的同名構造函數不推薦使用了(目前沒有移除,後續會移除)
String、int、float等這些關鍵字不能被作爲類名使用了
func_get_args()獲取的是當前變量的值
1
2
3
4
5
6
7
8
9
10
11
12
|
function
test (
$num
) {
$num
++;
var_dump(func_get_args()[0]);
};
test(1)
//PHP5
int(1)
//PHP7
int(2)
|
下面就挑選了一些主要的、核心的、對我們PHPer來說比較重要的特性介紹一下
PHP NG
新的php引擎優化了很多地方,也正式因爲如此,才使得php7相對於php5性能有了接近兩倍的提升!
ZVAL結構的重構
左邊是PHP5的zval(24字節),右邊是PHP7的zval(16字節);
可以看出來php7的zval要比php5還要複雜,但是卻能從24個字節下降到16個字節,爲什呢?
在C語言中struct的每一個成員變量要各自佔據一塊獨立的內存空間,而union裏的成員變量是共用一塊內存空間(php7中大量使用union替換了struct)。因此,雖然成員變量看起來多了不少,但是實際佔據的內存空間有很多都是公用的卻下降了。
使用新的Zend Array替換之前的HashTale結構
我們php程序中使用最多、最有用、最方便、最靈活的就是數組了,而php5它的底層就是HashTable實現的,php7使用了新的Zend Array類型,性能和訪問速度上都有了大幅度提升!
一些非常常用,開銷不大的的函數直接變成了引擎支持的opcode
1
2
3
4
|
call_user_function(_array) => ZEND_INIT_USER_CALL
is_int
/string/
array
/* => ZEND_TYPE_CHECK
strlen
=> ZEND_STRLEN
defined => ZEND+DEFINED
|
使用了新的內存分配,管理方式,減少了內存的浪費
核心排序zend_sort的優化
1
2
3
4
5
|
//PHP5 - 快速排序(非穩定排序)
array
(1 => 0, 0 => 0)
//PHP7 - 快速排序+選擇排序(穩定排序)
array
(0 => 0, 1 => 0)
|
小於16個元素的使用選擇排序,大於16個按照16個爲單位去分割,分別使用選擇排序,然後再全部合起來使用快速排序。排序較之前相比,內部元素由非穩定排序變成穩定排序,減少元素的交換次數,減少對內存的操作次數,性能提升40%
抽象語法樹
假如現在我們有這樣的需求,要對php源文件就行語法檢測,實現編碼規範。php5之前的話,沒有AST,直接從parser就生成了opcodes!就需要藉助一些外部的php語法解析器來實現;而php7增加了AST,我們可以自己去實現這樣一個擴展,利用擴展提供的函數可以直接獲取文件對應的的AST結構,而這樣的結構正是我們可以識別的,所以就可以在這個基礎上去做一些優化和判斷了。
64位的INT支持
支持存儲大於2GB的字符串
支持上傳大小大於2GB的文件
保證字符串在所有平臺上【64位】都是64bit
統一的語法變量
1
2
3
4
5
6
7
|
$
$foo
[
'bar'
][
'baz'
]
//PHP5
($
$foo
)[‘bar
']['
baz']
//PHP7: 遵循從左到右的原則
${
$foo
[‘bar
']['
baz']}
|
foreach循環的改進
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
//PHP5
$a
=
array
(1, 2, 3);
foreach
(
$a
as
$v
){var_dump(current(
$a
));}
int(2)
int(2)
int(2)
$a
=
array
(1, 2, 3);
$b
=&
$a
;
foreach
(
$a
as
$v
){var_dump(current(
$a
));}
int(2)
int(3)
bool(false)
$a
=
array
(1, 2, 3);
$b
=
$a
;
foreach
(
$a
as
$v
){var_dump(current(
$a
));}
int(1)
int(1)
int(1)
//PHP7:不再操作數據的內部指針了
$a
=
array
(1, 2, 3);
foreach
(
$a
as
$v
){var_dump(current(
$a
))}
int(1)
int(1)
int(1)
$a
=
array
(1, 2, 3);
$b
=&
$a
;
foreach
(
$a
as
$v
){var_dump(current(
$a
))
int(1)
int(1)
int(1)
$a
=
array
(1, 2, 3);
$b
=
$a
;
foreach
(
$a
as
$v
){var_dump(current(
$a
))}
int(1)
int(1)
int(1)
|
新增的幾個操作符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//<=> - 比較兩個數的大小【-1:前者小於後者,0:前者等於後者,1:前者大於後者】
echo
1 <=> 2;
//-1
echo
1 <=> 1;
//0
echo
1 <=> 0;
//1
// ** - 【a的b次方】
echo
2 ** 3;
//8
//?? - 三元運算符的改進
//php5
$_GET
[
'name'
] ?
$_GET
[
'name'
] :
''
;
//Notice: Undefined index: …
//php7
$_GET
[
'name'
] ??
''
->
''
;
//\u{xxxx} - Unicode字符的解析
echo
"\u{4f60}"
;
//你
echo
"\u{65b0}"
;
//新
|
返回類型的聲明
1
2
3
4
5
6
7
8
9
10
11
|
function getInt() :
int
{
return
「test」;
};
|
function getInt() :
int
{
return
「test」;
};
getInt();
|