新特性預覽
1234567891011 | ZEND引擎升級到Zend Engine 3,也就是所謂的php NG 增加抽象語法樹,使編譯更加科學 64位的INT支持 統一的變量語法 原聲的TLS - 對擴展開發有意義 一致性foreach循環的改進 新增 <=>、**、?? 、/u{xxxx}操作符 增加了返回類型的聲明 增加了標量類型的聲明 核心錯誤可以通過異常捕獲了 增加了上下文敏感的詞法分析 |
移除的一些特性
1.移除一些舊的擴展,被移遷移到了PECL(例如:MySQL)2.移除SAPIs的支持3.<?和<? language=“php”這樣的標簽被移除了4.16進制的字符串轉換被廢除了
?12345 | //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()獲取的是當前變量的值
?123456789101112 | 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
?1234 | call_user_function(_array) => ZEND_INIT_USER_CALL is_int /string/ array /* => ZEND_TYPE_CHECK strlen => ZEND_STRLEN defined => ZEND+DEFINED |
使用了新的內存分配,管理方式,減少了內存的浪費核心排序zend_sort的優化
?12345 | //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統一的語法變量
?1234567 | $ $foo [ 'bar' ][ 'baz' ] //PHP5 ($ $foo )[‘bar '][' baz'] //PHP7: 遵循從左到右的原則 ${ $foo [‘bar '][' baz']} |
foreach循環的改進
?12345678910111213141516171819202122232425262728293031 | //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) |
新增的幾個操作符
?1234567891011121314151617 | //<=> - 比較兩個數的大小【-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}" ; //新 |
返回類型的聲明
?1234567891011 | function getInt() : int { return “test”; }; getInt(); //PHP5 #PHP Parse error: parse error, expecting '{'... //PHP7 #Fatal error:Uncaught TypeError: Return value of getInt() must be of the type integer, string returned |
標量類型的聲明
?1234567891011 | function getInt(int $num ) : int { return $num ; }; getInt(“test”); //PHP5 #PHP Catchable fatal error: Argument 1 passed to getInt() must be an instance of int, string given… //PHP7 #Fatal error: Uncaught TypeError: Argument 1 passed to getInt() must be of the type integer, string given… |
核心錯誤可以通過異常捕獲了
?12345678 | try { non_exists_func(); } catch (EngineException $e ) { echo “Exception: { $e ->getMessage();}/n”; } //這里用php7試了一下還是沒法捕獲,但是看鳥哥介紹說是可行的。。。 #Exception: Call to undefined function non_exists_func() |
上下問敏感的詞法分析
?12345678910111213 | //PHP5 class Collection { public function foreach ( $arr ) {}} #Parse error: parse error, expecting `"identifier (T_STRING)”'... //PHP7 class Collection { public function foreach ( $arr ) {} public function in( $arr ){} public function where( $condition ){} public function order( $condition ){} } $collection = new Collection(); $collection ->where()->in()-> foreach ()->order(); |
新聞熱點
疑難解答
圖片精選