新特性介紹
PHP NG – Zend Engine 3
抽象語法樹
64位的 INT 支持
統一的變量語法
新增Closure::call()
一致性foreach循環
匿名類的支持
新增 <=>、**、?? 、\u{xxxx}操作符
增加了返回類型的聲明
增加了標量類型的聲明
核心錯誤可以通過異常捕獲
增加了上下文敏感的詞法分析
PHP NG
ZVAL
大小從24字節減少到16字節
Zend Array(HashTable)
HashTable大小從72字節減少到56字節
HashTable bucket大小從72字節減少到32字節
- 函數調用的優化
- 使用了新的內存分配,管理方式,減少了內存的浪費
Immutable array optimization
$arr = [];
for($i=0; $i<100000; $i++) {
$arr[] = ['php'];
}
p(memory_get_usage(true));
PHP5: 45M
PHP7: 10M
一些非常常用,開銷不大的的函數直接變成了引擎支持的opcode
call_user_function(_array) => ZEND_INIT_USER_CALL
is_int、is_string、is_array、... => ZEND_TYPE_CHECK
strlen => ZEND_STRLEN
defined => ZEND+DEFINED
核心排序的優化
PHP5(zend_qsort)
快速排序(非穩定排序)
array(1 => 0, 0 => 0)
PHP7(zend_sort)
快速排序+選擇排序(穩定排序)
array(0 => 0, 1 => 0)
小於16個元素的使用選擇排序,大於16個按照16個為單位去分割,分別使用選擇排序,然後再全部合起來使用快速排序。排序較之前相比,內部元素由非穩定排序變成穩定排序,減少元素的交換次數,減少對內存的操作次數,性能提升40%
抽象語法樹
假如現在我們有這樣的需求,要對php源文件就行語法檢測,實現編碼規範。 php5之前的話,沒有AST,直接從parser就生成了opcodes!就需要藉助一些外部的php語法解析器來實現;而php7增加了AST,我們可以自己去實現這樣一個擴展,利用擴展提供的函數可以直接獲取文件對應的的AST結構,而這樣的結構正是我們可以識別的,所以就可以在這個基礎上去做一些優化和判斷了。
64位的INT支持
支持存儲大於2GB的字符串
支持上傳大小大於2GB的文件
保證字符串在所有平台上【64位】都是64bit
統一的語法變量
PHP5: ${$foo[‘bar’]['baz']}
PHP7: ($$foo)['bar']['baz']【從左至右法則】
(function() {})();
$foo()();
[$obj, 'method']();
class A {
public static function a1() {}
}
[new A, 'a1']();
新增Closure::call()
$f = function() {
p($this->name);
};
class F {
private $name = 'F';
}
$f->call(new F);
匿名類的支持
function getAnonymousClass($config) {
return new class(config) {};
}
p(getAnonymousClass(array()));
一致性的foreach循環
//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)
新增的幾個操作符
<=>
//PHP5
function compare($a, $b) {
return ($a < $b) ? -1 : (($a >$b) ? 1 : 0);
}
//PHP7
function compare($a, $b) {
return $a <=> $b;
}
**
2 ** 2; // 2 * 2 = 4
2 ** -1; // 1 / 2 = 0.5
3 ** -2; // 1 / 9 = 0.111111111
??
$a = null;
$b = 1;
$c = 2;
echo $a ?? $b , ‘,’ , $c ?? $b; // 1,2
echo $a ?? $b ?? $c , ',' , $a ?? $d ?? $c; // 1,2
\u{xxxx}
echo "\u{4f60}";//你
echo "\u{65b0}";//新
// 從右至左強制
echo"\u{202E}iabgnay\u{1F602}";;
😂 yangbai
返回類型的聲明
function getInt() : int {
return 'test';
};
getInt();
//返回值為DateTime的函數
function getDateTime() : DateTime {
return new DateTime();
};
標量類型的聲明
function getAmount(int $num) : int {
return $num;
};
getAmount('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…
getAmount('123');
#PHP7新增的嚴格模式選項開啟下也會報錯【declare(strict_types=1),注意要放到代碼的第一行】
- 核心錯誤可以通過異常捕獲了
try {
non_exists_func();
} catch(EngineException $e) {
echo "Exception: {$e->getMessage();}\n";
} finally {
echo "undefined function…";
}
//這裡用php7試了一下沒有捕獲成功【但是確實拋出了異常】。 。 。#Exception: Call to undefined function non_exists_func()
上下問敏感的詞法分析
//PHP5
class Collection {public function foreach($arr) {}}
#Parse error: parse error, expecting `"identifier (T_STRING)”'...
//PHP7
class Collection {
public function foreach($arr) {
return $this;
}
public function in($arr){
return $this;
}
public function sort($condition){
return $this;
}
public function echo($condition){
return 'ok';
}
}
$collection = new Collection();
$collection->in()->foreach()->sort()->echo();
打破的一些東西
mysql、ereg
mysql 移到了ext/pecl 中去了,ereg 移到了ext/pcre
isapi、tux etc SAPIs
<?和<? language=“php”這樣的標籤被移除了
HTTP_RAW_POST_DATA移除了(可以使用php://input替代)
$o = & new className(),不再支持這樣的寫法
mktime()、gmmktime() 函數的$is_dst 參數被移除了
setlocale()函數的$category參數不支持字符串了,必須是LC開頭的常量
php.ini文件移除了#作為註釋,統一用;去註釋
函數定義同名參數不支持了
類的同名構造函數不推薦(目前沒有移除,後續會去掉)
String,int,float等這些關鍵字不能被作為類、接口、trait的名稱使用了
func_get_arg/func_get_args獲取的是當前變量的值
無效的八進制數字會產生編譯錯誤
preg_replace()不再支持匹配模式/e
16進制的字符串數字轉換被移除了
不再支持靜態調用一個不兼容的$this上下文的非靜態調用
Unsafe curl file uploads (use CurlFile instead)
//PHP5
curl_setopt(ch, CURLOPT_POSTFIELDS, array(
'file' => '@'.realpath('image.png'),
));
//PHP7
curl_setopt(ch, CURLOPT_POSTFIELDS, [
'file' => new CURLFile(realpath('image.png')),
]);
一些移除的函數和選項
set_magic_quotes_runtime();
magic_quotes_runtime();
//(use stream_set_blocking() instead)
set_socket_blocking();
//(use mcrypt_generic_deinit() instead)
mcrypt_generic_end();
//(use mcrypt_encrypt() and mcrypt_decrypt() instead)
mcrypt_ecb();
mcrypt_cbc();
mcrypt_cfb();
mcrypt_ofb();
//(use datefmt_set_timezone() or IntlDateFormatter::setTimeZone() instead)
datefmt_set_timezone_id();
IntlDateFormatter::setTimeZoneID();
//(use XsltProcessor::setSecurityPrefs() instead)
xsl.security_prefs;//php.ini
//(use php.input_encoding、php.internal_encoding and php.output_encoding instead)
iconv.input_encoding;
iconv.output_encoding;
iconv.internal_encoding;
mbstring.http_input;
mbstring.http_output;
mbstring.internal_encoding;
沒有留言:
張貼留言