PHP7新特性的介紹

截止到目前爲止,PHP官方已經發布了php7的RC7版本,距離發佈第一個正式版本不會很遠了!如今來講php7的重大特性確定已是定型了,不會再有什麼變更了。後續一些版本的迭代主要也就是修修bug,優化之類的。下面就來講話咱們一直期待的php7會有那些主要的變化了。。。php

關於PHP

  • 20年的發展歷史;mysql

  • 迄今爲止最流行的WEB開發語言;git

  • 超過82%的網站都會使用PHP做爲他們的服務端開發語言;github

新特性介紹

  • PHP NG – Zend Engine 3sql

  • 抽象語法樹api

  • 64位的 INT 支持php7

  • 統一的變量語法curl

  • 新增Closure::call()socket

  • 一致性foreach循環ide

  • 匿名類的支持

  • 新增 <=>**??\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_intis_stringis_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%

抽象語法樹

clipboard.png

假如如今咱們有這樣的需求,要對php源文件就行語法檢測,實現編碼規範。php5以前的話,沒有AST,直接從parser就生成了opcodes!就須要藉助一些外部的php語法解析器來實現;而php7增長了AST,咱們能夠本身去實現這樣一個擴展,利用擴展提供的函數能夠直接獲取文件對應的的AST結構,而這樣的結構正是咱們能夠識別的,因此就能夠在這個基礎上去作一些優化和判斷了。

64位的INT支持

  • 支持存儲大於2GB的字符串

  • 支持上傳大小大於2GB的文件

  • 保證字符串在全部平臺上【64位】都是64bit

統一的語法變量

$$foo['bar']['baz']

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文件移除了#做爲註釋,統一用;去註釋

  • 函數定義同名參數不支持了

  • 類的同名構造函數不推薦(目前沒有移除,後續會去掉)

  • Stringintfloat等這些關鍵字不能被做爲類、接口、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;
    
    (use PDO::ATTR_EMULATE_PREPARES instead)
    PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT;//driver option 
     
    //(use peer_name instead)
    CN_match;//SSL context options 
    SNI_server_name;//SSL context options

差很少了,夜已深、人已困!
更多、更詳細的介紹請猛戳 這裏

相關文章
相關標籤/搜索