PHP7新特性


PHP 7除了在性能方面有極大提升外,還添加了很多新的特性,如太空船操作符、標量類型聲明、返回值的類型聲明、全局的throwable接口、抽象語法樹等,下邊分別介紹。

(1)太空船操作符

太空船操作符用於比較兩個表達式。例如,當$a小於、等於或大於$b時,它分別返回-1、0或1。比較的原則沿用PHP的常規比較規則進行。

<?php
//整數
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

//浮點數
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1;   // 1

// 字符串
echo 'a' <=> 'a'; // 0
echo 'a' <=> 'b'; // -1
echo 'b' <=> 'a'; // 1

(2)標量類型聲明和返回值的類型聲明

PHP 7可以對下面幾種類型的參數做聲明:字符串(string)、整型(int)、浮點型(float)以及布爾型(bool)。注意參數類型聲明不受制於默認模式和嚴格模式。默認模式下,當傳入的參數不符合聲明類型時,會首先嘗試轉換類型;而嚴格模式下,則直接報錯。

例如下面的代碼:

<?php
declare(script_types=1); // strict_types=1表示開啟嚴格模式
function sumOfInts(int ...$ints)
{
	return array_sum($ints);
}
var_dump(sumOfInts(2, '3.1', 4.1)); // 運行會報錯

當注釋掉第二行代碼,程序才可以正常運行——PHP會首先嘗試把’3.1’轉為int型的3,然后再執行。(注意:這里的類型轉換僅受制於可轉換的類型,例如不能把’a’轉為int型。)但是當開啟嚴格模式后,代碼會直接報錯。因為函數的參數被聲明為int型,但是傳入的參數中包含一個string型和一個float型。

修改上面代碼,再來看看返回值類型受限制的情況:

<?php
declare(script_types=1); // strict_types=1表示開啟嚴格模式
function sumOfInts(int ...$ints) : int
{
	return array_sum($ints);
}
var_dump(sumOfInts(2, 3, 4);
// 運行結果
// int(9)

這段代碼額外聲明了返回值的類型為int型。如果返回值的類型不是int型,在默認模式下,PHP會首先嘗試轉換返回值的類型為int型,如果不能轉換,則會直接報錯。PHP 7.1對函數返回值的聲明做了擴充,可以定義其返回值為void,無論是否開啟嚴格模式,只要函數中有“return; ”以外的其他return語句都會報錯。注意:參數類型不可以是void。

<?php
declare(strict_types=1);
function sumOfInts(int ...$ints) : void
{
	return;
}
var_dump(sumOfInts(2, 3, 4));
// 運行結果
// NULL

PHP 7.1.0對參數類型和返回值類型還有進一步的支持,其類型可以是可空類型,在參數或返回值類型聲明前邊加上“? ”,表示返回值要么是null,要么是聲明的類型:

<?php
declare(strict_types=1);
function test(? int $a) : ? int
{
	return $a;
}
var_dump(test(null)); // NULL
var_dump(test(1)); // 1
var_dump(test('a')); // ERROR

(3)null合並操作符

在PHP 7之前,人們經常會寫這樣的代碼:

$page = isset($_GET['page']) ? $_GET['page'] : 0;

PHP 7提供了一個新的語法糖“? ? ”,如果變量存在且值不為null,它會返回自身的值,否則返回它的第二個操作數。可以這樣改寫代碼:

$page = $_GET['page'] ? ? 0;

當代碼中有連續的三元運算符的時候還可以像下邊這樣寫:

$page = $_GET['page'] ? ? $_POST['page'] ? ? 0;

(4)常量數組

在PHP 7之前是無法通過define來定義一個數組常量的,PHP 7支持了這個操作:

define('ANIMALS', [
	'dog',
	'cat',
	'bird'
]);

(5)namespace批量導入

在PHP 7之前,如果要導入一個namespace下的多個class,我們需要這樣寫:

use Space\ClassA;
use Space\ClassB;
use Space\ClassC as C;

在PHP 7中支持批量導入:

use Space\{ClassA, ClassB, ClassC as C};

(6)throwable接口

在PHP 7之前,如果代碼中有語法錯誤,或者fatal error時,程序會直接報錯退出,但是在PHP 7中有了改變。PHP 7實現了全局throwable接口,原來的Exception和部分Error實現了該接口。這種Error可以像Exception一樣被第一個匹配的try / catch塊捕獲。如果沒有匹配的catch塊,則調用異常處理函數進行處理。如果尚未注冊異常處理函數,則按照傳統方式處理(fatal error)。Error類並非繼承自Exception類,所以不能用catch (Exception $e) { ... } 來捕獲Error。可以用catch (Error $e) {... },或者通過注冊異常處理函數(set_exception_handler())來捕獲Error:

try {
	undefindfunc();
} catch (Error $e) {
	var_dump($e);
}

// 或者
set_exception_hander(function($e){
	var_dump($e);
});
undefinedfunc();

(7)Closure::call()

在PHP 7之前,我們需要動態地給一個對象添加方法時,可以通過Closure來復制一個閉包對象,並綁定到一個$this對象和類作用域:

class Test {
	private $num = 1;
}

$f = function() {
	return $this->num + 1;
}

$test = $f->bindTo(new Test, 'Test');
echo $test();
// 2

在PHP 7中新添加了Closure::call(),可以通過call來暫時綁定一個閉包對象到$this對象並調用它:

class Test {
	private $num = 1;
}

$f = function() {
	return $this->num + 1;
}

echo $f->call(new Test);
// 2

(8)intdiv函數

PHP 7還增加了一個新的整除函數,在代碼中不需要再手動轉了:

// var_dump(intval(10 / 3));
var_dump(intdiv(10, 3));

(9)list的方括號寫法

我們知道可以通過list來實現解構賦值,如下:

$arr = [1, 2, 3];
list($a, $b, $c) = $arr;

PHP 7.1.0對其做了進一步的優化,可以將其寫成如下方式:

$arr = [1, 2, 3];
[$a, $b, $c] = $arr;

注意:這里的[]並不是數組的意思,只是list的簡略形式。

除了上文這些,PHP7還有很多其他的改變和特性。例如,foreach遍歷數組時不再修改內部指針、移除了ASP和script PHP標簽、移除了$HTTP_RAW_POST_DATA、匿名類、類常量可見性等


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM