【PHP8.x】forward_static_call関数の使い方

作成日: 更新日:

forward_static_call関数は、現在のスコープと呼び出し元の静的スコープを維持したまま、指定された静的メソッドまたはクラスメソッドを実行する関数です。この関数は、PHPの「遅延静的束縛(Late Static Bindings)」の仕組みをさらに細かく制御するために利用されます。

通常のstatic::method()のような静的メソッド呼び出しでは、メソッドが実際に実行されるコンテキスト(staticキーワードが指し示すクラス)は、呼び出し元の状況によって必ずしも開発者の意図通りにならない場合があります。forward_static_callは、呼び出し元のstaticバインディング(つまり、staticキーワードがどのクラスを指すべきかという情報)を、呼び出されるメソッドに正確に「転送」します。

これにより、メソッドが実行される際のコンテキスト、特にstaticキーワードがどのクラスを指すかを、呼び出し元が意図する通りに動的に制御することが可能になります。主に、トレイト内で定義されたメソッドから、そのトレイトを利用するクラスで実装されたメソッドを呼び出すといった、複雑なクラス階層やトレイトの利用を伴う高度なオブジェクト指向設計のシナリオで活用されます。

この機能は、継承やトレイトによってstaticキーワードの解決が複雑になる状況において、開発者が期待するメソッドが確実に実行されるようにするための強力なツールです。システムエンジニアを目指す初心者の方には少し高度な概念に感じるかもしれませんが、PHPのクラスやトレイトを深く学び、静的呼び出しの振る舞いをより精密に制御したい場合に非常に役立つ機能です。

基本的な使い方

構文(syntax)

forward_static_call(callable $callback, mixed ...$args): mixed

引数(parameters)

callable $callback, mixed ...$args

  • callable $callback: 呼び出し対象のコールバック関数またはメソッドを指定します。
  • mixed ...$args: コールバック関数に渡す可変個の引数です。

戻り値(return)

mixed

forward_static_call 関数は、静的メソッド呼び出しの結果を返します。これは、call_user_funccall_user_func_array の静的メソッド版として機能します。

サンプルコード

PHP forward_static_call_arrayで静的呼び出しを転送する

<?php

declare(strict_types=1);

/**
 * 親クラス
 */
class ParentClass
{
    /**
     * メッセージと呼び出し元のクラスコンテキストを表示します。
     * `static::who()` は遅延静的束縛により、実行時のクラスの `who()` を呼び出します。
     *
     * @param string $message 表示するメッセージ
     */
    public static function test(string $message): void
    {
        echo "Message: {$message}" . PHP_EOL;
        echo 'Context: ';
        static::who();
    }

    /**
     * 呼び出されたクラスの名前を表示します。
     */
    public static function who(): void
    {
        echo __CLASS__ . PHP_EOL;
    }
}

/**
 * 子クラス
 */
class ChildClass extends ParentClass
{
    /**
     * 親クラスの `who()` メソッドをオーバーライドします。
     */
    public static function who(): void
    {
        echo __CLASS__ . PHP_EOL;
    }

    /**
     * `forward_static_call_array` を使って親のメソッド呼び出しを転送します。
     * この関数は、呼び出し元のクラス(この場合は ChildClass)のコンテキストを
     * 保持したまま、指定された静的メソッドを呼び出します。
     *
     * @param string $message 親メソッドに渡すメッセージ
     */
    public static function forwardTheCall(string $message): void
    {
        // `ParentClass::test` メソッドを、引数を配列で渡して呼び出します。
        // この時、呼び出し元である `ChildClass` のコンテキストが転送されるため、
        // `ParentClass::test` 内の `static::who()` は `ChildClass::who()` を実行します。
        forward_static_call_array([ParentClass::class, 'test'], [$message]);
    }
}

// 子クラスのメソッドを呼び出します。
ChildClass::forwardTheCall('Hello from ChildClass!');

/*
--- 期待される出力 ---
Message: Hello from ChildClass!
Context: ChildClass
*/

このサンプルコードは、forward_static_call_array 関数を使い、呼び出し元のクラスの情報を維持したまま別の静的メソッドを呼び出す例です。この関数は、第一引数に callable 型で指定された静的メソッドなどを、第二引数に指定された配列の要素を引数として渡して実行します。

この関数の最大の特徴は、呼び出し元の「静的コンテキスト」を転送する点にあります。サンプルでは ChildClass のメソッド内から ParentClass::test を呼び出しています。この時、forward_static_call_arrayChildClass のコンテキストを ParentClass::test メソッドに引き継ぎます。

ParentClass::test の内部では static::who() が呼び出されます。これは「遅延静的束縛」という仕組みで、実行時のクラスで定義されたメソッドを呼び出します。今回は ChildClass のコンテキストが引き継がれているため、ChildClass でオーバーライドされた who メソッドが実行されます。その結果、出力は ParentClass ではなく ChildClass と表示されます。

このように、継承関係において、子クラスの振る舞いを保ちつつ親クラスのメソッドを再利用したい場合などに有効です。関数の戻り値は、第一引数で呼び出されたメソッドの戻り値そのものとなります。

forward_static_call_arrayは、呼び出し元のクラス情報を引き継いで静的メソッドを呼び出す関数です。このため、呼び出されたメソッド内でstatic::キーワードが使われている場合、それは呼び出し元のクラスを指します。サンプルコードではChildClassから呼び出しているため、ParentClassのメソッド内でもstatic::who()ChildClass::who()として実行されます。もしcall_user_func_arrayを使うとこの情報は引き継がれず、ParentClass::who()が呼ばれてしまう点に注意してください。この関数はクラスの継承と「遅延静的束縛」を理解した上で使うことが重要で、静的メソッドの呼び出しにのみ使用できます。

【PHP8.x】forward_static_call関数の使い方 | いっしー@Webエンジニア