日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

PHP7的变化

發布時間:2023/12/15 php 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP7的变化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

PHP7與PHP5版本相比有非常大的變化,尤其是在Zend引擎方面。為了提升性能,PHP7對Zend進行了深度優化,使得PHP的運行速度大大提高,比PHP5.0-5.6快了近5倍,同時還降低了PHP對系統資源的占用。

PHP7比較大的變化有:

抽象語法樹

PHP是一種解釋性語言,通過解析器來執行。

那么首先來看一下編譯器與解釋器的區別:讀入源語言后,解釋器和編譯器都要進行詞法分析、語法分析和語義分析,之后,二者開始有所分別。

  • 解析器與編譯器的區別:

    • 解釋器在語義分析后選擇了直接執行語句;
    • 編譯器在語義分析后選擇將將語義存儲成某一種中間語言,之后通過不同的后端翻譯成不同的機器語言(可執行程序)。其存在一個預編譯的過程。如下圖所示:

  • PHP7之前的版本,代碼解釋過程:

    • PHP代碼在語法解析階段直接生成ZendVM指令,即在zend_language_parser.y中直接生成opline指令,使得編譯器與執行器耦合在一起。
    • 編譯生成的指令再供執行引擎使用,該指令是在語法指令直接生成的,若要更換執行引擎,怎需要修改語法解析規則;若PHP語法變化,但沒有修改執行引擎,仍需要修改語法解析規則。其代碼解析過程如下圖:

  • PHP7的代碼解析過程:

Native TLS

PHP5.x版本擴展中,有TSRM_CC、TSRM_DC宏,用于線程安全。

PHP中有很多變量需要在不同函數間共享,多線程的環境下不能簡單地通過全局變量來實現,為了適應線程的應用環境,PHP提供了一個線程安全資源管理器,將全局資源進行線程隔離,不同的線程之間互不干擾。

使用全局資源需要先獲取本線程的資源池,這個過程比較占用時間,因此,PHP5.x通過參數傳遞的方式將本線程的資源池傳遞給其他函數,避免重復查找。這種方式需要所有函數接受資源池的參數(TSRM_DC宏所加的參數),這些參數傳遞不僅易遺漏參數,還是得代碼不優雅

PHP7使用Native TLS(線程局部存儲)來保存線程的資源池,簡單來說就是通過__thread標識一個全局變量,這樣這個全局變量就是線程獨享的了,不同線程的修改不會相互影響。

指定函數參數、返回值類型

輸入和輸出參數必須是指定的數據類型,示例如下:

1
2
3
function foo(string $name): array {
return [];
}

zval結構的變化

Zval是PHP中最重要的數據結構之一(另一個比較重要的數據結構是hash table),它包含了PHP中的變量值和類型的相關信息。它是一個struct,在PHP5.x中,基本結構為:

1
2
3
4
5
6
7
struct _zval_struct {
zvalue_value value; /* value,變量的具體值 */
zend_uint refcount__gc; /* variable ref count,記錄變量的引用計數(自動回收的基礎) */
zend_uchar type; /* active type ,類型*/
zend_uchar is_ref__gc; /* if it is a ref variable,標識變量是否為引用 */
};
typedef struct _zval_struct zval;

變量的實際值,具體來說是一個zvalue_value的聯合體(union),用來適配不同的變量類型:

1
2
3
4
5
6
7
8
9
10
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct { /* string */
char *val;
int len;
} str;
HashTable *ht; /* hash table value,used for array */
zend_object_value obj; /* object */
} zvalue_value;

參考:PHP內核探索之變量(1)變量的容器-Zval

PHP5.x中引用計數是在zval中,而不是在具體的value中,這樣一來,導致變量復制時需要復制兩個結構,zval,zvalue_value始終是綁定在一起的。

  • 變化1:PHP7中將引用計數轉移到具體的value中,這樣更合理,因為zval只是變量的一個載體,可以簡單地認為是變量名,而value才是真正的值,這個改變使得PHP變量之間的復制、傳遞更加簡潔、易懂
  • 變化2:zval結構的大小由24byte減少到16byte,這PHP7能夠降低系統的資源占用。

異常處理

PHP5.x中很多操作會直接拋出error錯誤,PHP7中將多數錯誤改為了異常拋出,這樣就可以通過try catch捕捉到異常。這種新的異常處理方式使得錯誤處理更加可控。

HashTable的變化

HashTable,即哈希表,也稱為散列表,它是PHP強大的array()類型的內部實現結構,也是內核中使用非常頻繁的一個結構,函數符號表、類符號表、常量符號表等都是通過HashTable實現的。

PHP7中,HashTable結構的大小由72byte減小到56byte,同時,數組元素Bucket結構也由72byte減小到32byte。

執行器

execute_data、opline采用寄存器變量存儲,執行器的調度函數為execute_ex(),這個函數復制執行PHP代碼編譯生成ZendVM指令。在執行期間會頻繁地用到execute_data、opline兩個變量。

PHP5.x中,這兩個變量是由execute_ex()通過參數傳遞給各指令handle的。

PHP7中不再采用傳參的方式,而是將execute_data、opline通過寄存器來存儲,避免傳參導致的頻繁出入棧操作,同時寄存器相比于內存的訪問速度更快。這個優化使得PHP的性能有了5%左右的提升。

新的參數解析

PHP5.x通過zend_parse_parameters()解析函數的參數,PHP7提供另外一種方式,同時保留原來方式,但是新的解析方式速度更快。

參考:秦朋 《PHP7內核剖析》第1.3節

推薦文章——關于PHP內部實現的文章:

  • 給PHP開發者的PHP源碼(1):源碼結構
  • 理解 PHP 內部函數的定義
  • PHP 的變量實現
  • 理解數組在PHP內部的實現
  • 總結

    以上是生活随笔為你收集整理的PHP7的变化的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。