PHP 比較少見的語法


分類

建立時間: 2023年11月7日 12:12
更新時間: 2024年8月29日 08:35

說明

有時候在寫 PHP 的時候常常會看到一些比較特別的寫法,有別於 if else, for, switch 這種,本篇將分享這些較為少見的語法給大家。

太空船運算子(組合比較運算子)

$a <=> $b
$a 小於、等於、大於 $b 時分別傳回一個小於、等於、大於0的 int 值。

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

文件說明: https://www.php.net/manual/language.operators.comparison.php


NULL 合併運算子

表達式 (expr1) ?? (expr2) 如果 expr1 為 null 則值為 expr2,否則為 expr1。

範例 #6 設定預設值

<?php
// NULL 合併運算子的例子
$action = $_POST['action'] ?? 'default';

// 以上例子等同於以下 if/else 語句
if (isset($_POST['action'])) {
    $action = $_POST['action'];
} else {
    $action = 'default';
}

Nullsafe 運算子

Nullsafe 運算子的語法是 ?->。它的作用是當鏈中的任何一個對象是 null 時,整個表達式會直接返回 null,而不會繼續執行後續的屬性或方法調用。

$country =  null;

if ($session !== null) {
    $user = $session->user;

    if ($user !== null) {
        $address = $user->getAddress();

        if ($address !== null) {
            $country = $address->country;
        }
    }
}

上述程式碼等同於

$country = $session?->user?->getAddress()?->country;

命名參數

<?php
// 使用順序傳遞參數:
array_fill(0, 100, 50);

// 使用命名參數:
array_fill(start_index: 0, count: 100, value: 50);
?>

文件說明: https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments

可為空(Nullable)類型

參數以及返回值的類型現在可以透過在類型前加上一個問號使之允許為空。

function testReturn(): ?string
{
    return 'elePHPant';
}

var_dump(testReturn());

function testReturn(): ?string
{
    return null;
}

var_dump(testReturn());

function test(?string $name)
{
    var_dump($name);
}

test('elePHPant');
test(null);
test();

輸出

string(10) "elePHPant"
NULL
string(10) "elePHPant"
NULL
Uncaught Error: Too few arguments to function test(), 0 passed in...

文件說明: https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.nullable-types

對稱(Symmetric)陣列解構

短陣列語法 [] 現在作為 list() 語法的一個備選項,可以用於將陣列的值賦給一些變數(包括在 foreach 中)。

<?php
$data = [
    [1, 'Tom'],
    [2, 'Fred'],
];

// list() style
list($id1, $name1) = $data[0];

// [] style
[$id1, $name1] = $data[0];

// list() style
foreach ($data as list($id, $name)) {
    // logic here with $id and $name
}

// [] style
foreach ($data as [$id, $name]) {
    // logic here with $id and $name
}

文件說明: https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.symmetric-array-destructuring

箭頭函式

範例 #1 箭頭函數自動捕捉變數的值

<?php

$y = 1;

$fn1 = fn($x) => $x + $y;
// 相當於透過 value 使用 $y:
$fn2 = function ($x) use ($y) {
    return $x + $y;
};

var_export($fn1(3));
?>

輸出

4

文件說明: https://www.php.net/manual/en/functions.arrow.php

可變參數函式(Variadic functions)

<?php
function f($req, $opt = null, ...$params) {
    // $params 是一個包含了剩餘參數的陣列
    printf('$req: %d; $opt: %d; number of params: %d'."\n",
           $req, $opt, count($params));
}

f(1);
f(1, 2);
f(1, 2, 3);
f(1, 2, 3, 4);
f(1, 2, 3, 4, 5);
?>

輸出

$req: 1; $opt: 0; number of params: 0
$req: 1; $opt: 2; number of params: 0
$req: 1; $opt: 2; number of params: 1
$req: 1; $opt: 2; number of params: 2
$req: 1; $opt: 2; number of params: 3

文件說明: https://www.php.net/manual/en/migration56.new-features.php#migration56.new-features.variadics


match

match 表達式是基於值的一致性進行分支計算。match 表達式和 switch 語句類似,都有一個表達式主體,可以和多個可選項進行比較。與 switch 不同點是,它會像三元表達式一樣求值。 與 switch 另一個不同點,它的比較是嚴格比較(===)而不是鬆散比較(==)。

邏輯 OR

match 表達式分支可以透過逗號分隔,包含多個表達式。

<?php
$result = match ($x) {
    // 匹配分支:
    $a, $b, $c => 5,
    // 等同於以下三個分支:
    $a => 5,
    $b => 5,
    $c => 5,
};
?>

default

default 模式是個特殊的條件。當之前的條件都不匹配時,會匹配到該模式。舉例:

<?php
$expressionResult = match ($condition) {
    1, 2 => foo(),
    3, 4 => bar(),
    default => baz(),
};
?>

範例

範例 #2 match 的基礎用法

<?php
$food = 'cake';

$return_value = match ($food) {
    'apple' => 'This food is an apple',
    'bar' => 'This food is a bar',
    'cake' => 'This food is a cake',
};

var_dump($return_value);
?>

輸出

string(19) "This food is a cake"

文件說明: https://www.php.net/manual/zh/control-structures.match.php

Constructor Promotion

從 PHP 8.0.0 開始,建構器參數也可以提升為相對應物件屬性。將建構器參數指派給建構器中的屬性但不對其進行操作的情況很常見。建構器提升為該用例提供了一種簡寫方式。

<?php
class Point {
    public function __construct(protected int $x, protected int $y = 0) {
    }
}

等同於

<?php
class Point {
    protected int $x;
    protected int $y;

    public function __construct(int $x, int $y = 0) {
        $this->x = $x;
        $this->y = $y;
    }
}

new Class 省略括號

如果沒有參數要傳遞給類別的建構函數,類別名稱後的括號則可以省略掉。

<?php

class Example {
    public function __construct() {
        echo "Constructor called\n";
    }
}

// 使用括號
$obj1 = new Example();
// 輸出:Constructor called

// 省略括號
$obj2 = new Example;
// 輸出:Constructor called
觀看次數: 671
featurephpsyntax
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

一杯咖啡的力量,勝過千言萬語的感謝。

支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!