PHP 構文のスニペット集

このページは、PHPの構文のスニペットなどをまとめる予定のページです。

目次

数値

数値リテラルのセパレータ

数値リテラルのセパレータ (PHP 7.4~)
$x = 1_000_000; // 1000000

文字列

Unicode コードポイントエスケープ構文

Unicode コードポイントエスケープ構文 (PHP 7.4~)
echo "\u{3042}"; // あ

演算子

分割代入

分割代入
list($a, $b, $c) = [1, 2, 3];
分割代入の短縮記法 (PHP 7.1~)
[$a, $b, $c] = [1, 2, 3];

null合体演算子

null合体演算子 (PHP 7.0~)
$data = ['user' => ['name' => 'taro']];
$userName = $data['user']['name'] ?? ''; // taro

$data = null;
$userName = $data['user']['name'] ?? ''; // ''

宇宙船演算子

宇宙船演算子 (PHP 7.0~)
function cmp($a, $b){ return $a <=> $b; }

$arr = [1, 5, 4, 3, 2];
usort($arr, 'cmp'); // $arr == [1, 2, 3, 4, 5]
//usort($arr, fn($a, $b) => $a <=> $b); // アロー関数と併用する場合

nullsafe演算子

nullsafe演算子 (PHP 8.0~)
$data = (object)['user' => (object)['name' => 'taro']];
$userName = $data?->user?->name; // taro

$data2 = null;
$userName = $data2?->user?->name; // null

match式

match式 (PHP 8.0~)
$ext = 'jpg';
$mimeType = match ($ext) {
    'png' => 'image/png',
    'jpe' => 'image/jpeg',
    'jpeg' => 'image/jpeg',
    'gif' => 'image/gif',
    default => 'application/octet-stream'
};

$ext = 'jpg';
$mimeType = match (true) {
    $ext === 'png' => 'image/png',
    preg_match('#\Ajpe?g\z#', $ext) !== false => 'image/jpeg',
    $ext === 'gif' => 'image/gif',
    default => 'application/octet-stream'
};

配列

短縮記法

配列初期化の短縮記法 (PHP 5.4~)
$arr = [1, 2, 3];
連想配列初期化の短縮記法 (PHP 5.4~)
$assoc = ['a' => 1, 'b' => 2, 'c' => 3];

アンパック

アンパック (スプレッド演算子) (PHP 7.4~)
$arr = [1, 2, 3];
$arr2 = [4, 5, 6, ...$arr];

ジェネレータ

ジェネレータ

ジェネレータ (PHP 5.5~)
function g() {
    yield 1;
    yield 2;
    yield 3;
}
foreach (g() as $k => $v) {
    echo "{$k}:{$v}", PHP_EOL; // 0:1 1:2 2:3
}

ジェネレータの移譲

ジェネレータの移譲 (PHP 7.0~)
function g() {
    yield 1;
    yield 2;
    yield 3;
}
function g2() {
    yield from g();
    yield 4;
    yield 5;
}

foreach (g2() as $k => $v) {
    echo "{$k}:{$v}", PHP_EOL; // 0:1 1:2 2:3 0:4 1:5
}

関数

デフォルト引数

デフォルト引数
function f($a, $b = 1) {
    return $a * $b;
}
$x = f(100, 2); // 200;
$x2 = f(100); // 100;

名前付き引数

名前付き引数
$x = htmlspecialchars('<a>', encoding: 'UTF-8');

アロー関数

アロー関数 (PHP 7.4~)
$b = 100;
$fn = fn($a) => $a * $b;
$x = $fn(10); // 1000

無名関数

無名関数 (PHP 5.3~)
$b = 100;
$fn = function($a) use($b) { return $a * $b; };
$x = $fn(10); // 1000

型宣言

型宣言
function sum(int $a, int $b, int $c) {
    return $a + $b + $c;
}
$x = sum(1, 2, 3);

第一級callable

第一級callable (PHP 8.1~)
$h = htmlspecialchars(...);
$x = $h('<a>');

クラス

無名クラス

無名クラス (PHP 7.0~)
class Event {
    public $type;
    public function __construct($type) {
        $this->type = $type;
    }
}
interface EventTarget {
    public function addEventListener($type, EventListener $listener);
    public function dispatchEvent(Event $e);
}
interface EventListener {
    public function handleEvent(Event $e);
}
class Element implements EventTarget {
    private $listeners = [];
    public function addEventListener($type, EventListener $listener) {
        $this->listeners[$type][] = $listener;
    }
    public function dispatchEvent(Event $e) {
        if (!isset($this->listeners[$e->type])) return;
        foreach ($this->listeners[$e->type] as $listener) {
            $listener->handleEvent($e);
        }
    }
};

$el = new Element();
// 無名クラスの使用 (クラスやインタフェースが要求されている箇所に、使い捨てのクラスを作ることで対応できる)
$el->addEventListener('click', new class() implements EventListener {
    public function handleEvent(Event $e) {
        echo 'click!';
    }
});
$el->dispatchEvent(new Event('click')); // click! が出力される

プロパティの型宣言

プロパティの型宣言 (PHP 7.4~)
class Point {
    public int $x = 0;
    public int $y = 0;
}

__call, __callStatic

__call, __callStatic (PHP 5.3~)
class ArrayEx {
    private $array;

    // 存在しないインスタンスメソッドが呼ばれた時の処理
    public function __call($name, $arguments)
    {
        $class = get_class();
        if (!method_exists($class, "_{$name}")) trigger_error("Call to undefined method {$class}::{$name}()", E_USER_ERROR);
        return call_user_func_array([$class, "_{$name}"], [$this->array, ...$arguments]);
    }

    // 存在しない静的メソッドが呼ばれた時の処理
    public static function __callStatic($name, $arguments)
    {
        $class = get_class();
        if (!method_exists($class, "_{$name}")) trigger_error("Call to undefined method {$class}::{$name}()", E_USER_ERROR);
        return call_user_func_array([$class, "_{$name}"], $arguments);
    }

    public function __construct($array) {
        $this->array = $array;
    }

    // 静的メソッドとしてもインスタンスメソッドとしても呼び出せるメソッドの定義
    protected function _first($array, $default = null) {
        return count($array) > 0 ? $array[0] : $default;
    }
}

$array = [1, 2, 3];
$first = ArrayEx::first($array); // 1
$first = (new ArrayEx([4, 5, 6]))->first(); // 4

コンストラクタのプロモーション (コンストラクタ引数をプロパティに昇格)

コンストラクタのプロモーション (PHP 8.0~)
class Point {
    public function __construct(public int $x = 0, public int $y = 0) {
    }
}
$p = new Point(10, 20);
echo $p->x; // 10

トレイト

トレイト (PHP 5.4~) / Singleton パターン
// トレイトの定義
trait SingletonTrait {
    public static function getInstance() {
        static $instance = [];
        return $instance[static::class] ?? $instance[static::class] = new static();
    }
    protected function __construct() {}
}

class Test {
    // トレイトの使用
    use SingletonTrait;
}
$o = Test::getInstance();
トレイト (PHP 5.4~) / Observer パターン
// インターフェースの定義
interface Observer {
    public function execute();
}
// トレイトの定義
trait Observable {
    protected array $observers = [];
    public function addObserver(Observer $observer) {
        $this->observers[] = $observer;
    }
    public function notifyObservers(...$args) {
        foreach ($this->observers as $observer) {
            $observer->execute(...$args);
        }
    }
}
// 実装するクラスの定義
class Operation {
    // トレイトの使用
    use Observable;

    public function execute() {
        $this->notifyObservers(1);
    }
}

$o = new Operation();
$o->addObserver(new class() implements Observer {
    public function execute(...$args) {
        var_dump($args);
    }
});
$o->execute();

アトリビュート

アトリビュート (PHP 8.0~)
// アトリビュートの定義
#[Attribute]
class JsonPropertyName {
    // #[JsonPropertyName('名前')] のように使用できるようにする
    public function __construct(public ?string $name = null) {}
}

// アトリビュートを使用するトレイトの定義 (通常のメソッド定義でも可)
trait JsonTrait {
    public function toJson() {
        // リフレクションを使用してアトリビュートの情報を取得して処理を行う
        $ref = new ReflectionClass($this);
        $props = $ref->getProperties(ReflectionProperty::IS_PUBLIC);

        $data = [];
        foreach ($props as $prop) {
            // プロパティに付与されたアトリビュートを取得
            $attrs = $prop->getAttributes(JsonPropertyName::class);
            if (count($attrs) > 0) {
                $name = $attrs[0]->newInstance()->name;
            }
            else {
                $name = $prop->getName();
            }
            $data[$name] = $prop->getValue($this);
        }
        return json_encode($data);
    }
}

class User {
    use JsonTrait;

    public function __construct(
        public ?int $id = null,
        // アトリビュートの使用
        #[JsonPropertyName('screenName')]
        public ?string $name = null
    ) {}
}

$u = new User(1, 'taro');
echo $u->toJson(); // {"id":1,"screenName":"taro"}