淺談PHP7新特性

1. 運算符(NULL 合併運算符)php

把這個放在第一個說是由於我以爲它頗有用。用法:python

$a = $_GET['a'] ?? 1;swift

它至關於:數組

$a = isset($_GET['a']) ? $_GET['a'] : 1;閉包

咱們知道三元運算符是能夠這樣用的:app

$a ?: 1composer

可是這是創建在 $a 已經定義了的前提上。新增的 ?? 運算符能夠簡化判斷。框架

 

2. 函數返回值類型聲明函數

官方文檔提供的例子(注意 … 的邊長參數語法在 PHP 5.6 以上的版本中才有):oop

function arraysSum(array ...$arrays): array 

  return array_map(function(array $array): int { 

    return array_sum($array); 

   }, $arrays); 

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9])); 

以上例程會輸出:

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

從這個例子中能夠看出如今函數(包括匿名函數)均可以指定返回值的類型。

這種聲明的寫法有些相似於 swift:

func sayHello(personName: String) -> String { 

  let greeting = "Hello, " + personName + "!" 

  return greeting 

這個特性能夠幫助咱們避免一些 PHP 的隱式類型轉換帶來的問題。在定義一個函數以前就想好預期的結果能夠避免一些沒必要要的錯誤。

不過這裏也有一個特色須要注意。PHP 7 增長了一個 declare 指令:strict_types,既使用嚴格模式。

使用返回值類型聲明時,若是沒有聲明爲嚴格模式,若是返回值不是預期的類型,PHP 仍是會對其進行強制類型轉換。可是若是是嚴格模式, 則會出發一個 TypeError 的 Fatal error。

強制模式:

function foo($a) : int 

  return $a; 

foo(1.0); 

以上代碼能夠正常執行,foo 函數返回 int 1,沒有任何錯誤。

嚴格模式:

declare(strict_types=1); 

function foo($a) : int 

  return $a; 

foo(1.0); 

# PHP Fatal error:  Uncaught TypeError: Return value of foo() must be of the type integer, float returned in test.php:6 

在聲明以後,就會觸發致命錯誤。

是否是有點相似與 js 的 strict mode?

 

3. 標量類型聲明

PHP 7 中的函數的形參類型聲明能夠是標量了。在 PHP 5 中只能是類名、接口、array 或者 callable (PHP 5.4,便可以是函數,包括匿名函數),如今也可使用 string、int、float和 bool 了。

官方示例:

// Coercive mode 

function sumOfInts(int ...$ints) 

  return array_sum($ints); 

var_dump(sumOfInts(2, '3', 4.1)); 

以上例程會輸出:

int(9)

須要注意的是上文提到的嚴格模式的問題在這裏一樣適用:強制模式(默認,既強制類型轉換)下仍是會對不符合預期的參數進行強制類型轉換,嚴格模式下則觸發 TypeError 的致命錯誤。

 

4. use 批量聲明

PHP 7 中 use 能夠在一句話中聲明多個類或函數或 const 了:

use some/namespace/{ClassA, ClassB, ClassC as C}; 

use function some/namespace/{fn_a, fn_b, fn_c}; 

use const some/namespace/{ConstA, ConstB, ConstC}; 

但仍是要寫出每一個類或函數或 const 的名稱(並無像 python 同樣的 from some import * 的方法)。

須要留意的問題是:若是你使用的是基於 composer 和 PSR-4 的框架,這種寫法是否能成功的加載類文件?實際上是能夠的,composer 註冊的自動加載方法是在類被調用的時候根據類的命名空間去查找位置,這種寫法對其沒有影響。

 

5. 太空艙操做符(組合比較操做符)

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

// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Floats
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// Strings
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1

 

6. 經過 define() 定義常量數組 

Array 類型的常量如今能夠經過 define() 來定義。在 PHP5.6 中僅能經過 const 定義。

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

echo ANIMALS[1]; // outputs "cat"
?>

 

7. 迭代器

經過添加 yield 關鍵字支持了 generators,Generators 提供了一個更簡單的方法實現迭代器,不須要實現 Iterator 接口 

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;
 

以上例程會輸出:

1
2
3

8. 匿名類 

如今支持經過new class 來實例化一個匿名類,這能夠用來替代一些「用後即焚」的完整類定義。

interface Logger {
    public function log(string $msg);
}

class Application {
    private $logger;

    public function getLogger(): Logger {
         return $this->logger;
    }

    public function setLogger(Logger $logger) {
         $this->logger = $logger;
    }
}

$app = new Application;
$app->setLogger(new class implements Logger {
    public function log(string $msg) {
        echo $msg;
    }
});

var_dump($app->getLogger());

以上例程會輸出:

object(class@anonymous)#2 (0) {
}

詳細文檔能夠參考 匿名類.

 

9. 閉包 Closure::call()

Closure::call() 如今有着更好的性能,簡短幹練的暫時綁定一個方法到對象上閉包並調用它。

class A {private $x = 1;}

// Pre PHP 7 code
$getXCB = function() {return $this->x;};
$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure
echo $getX();

// PHP 7+ code
$getX = function() {return $this->x;};
echo $getX->call(new A);
 

以上例程會輸出:

1
1

10. 其餘的特性

其餘的一些特性我就不一一介紹了,有興趣能夠查看官方文檔:

英文文檔:http://php.net/manual/en/migration70.new-features.php

中文文檔:http://php.net/manual/zh/migration70.new-features.php

相關文章
相關標籤/搜索