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

作成日: 更新日:

class_implements関数は、指定されたクラスまたはオブジェクトが実装しているすべてのインターフェースの情報を取得する関数です。この関数は、PHPのオブジェクト指向プログラミングにおいて、特定のクラスがどのような機能を契約として持っているかを確認する際に非常に有用です。

この関数には、引数としてクラス名を表す文字列、またはインスタンス化されたオブジェクトのいずれかを渡します。例えば、あるクラスが複数のインターフェースを実装している場合、それらすべてのインターフェース名を一度に取得することができます。また、オプションの第二引数としてautoloadの動作を制御するブール値を指定できます。デフォルトではtrueとなっており、指定されたクラスが存在しない場合にPHPのオートロード機能を使ってクラスを読み込もうとします。

処理が成功した場合、class_implements関数は、実装されているインターフェースの名前をキーと値として持つ連想配列を返します。この配列には、直接実装しているインターフェースだけでなく、親クラスやトレイトを通じて間接的に実装しているインターフェースも含まれます。もし何らかのエラーが発生したり、指定されたクラスが存在しなかったりした場合には、falseが返されます。

この関数を利用することで、実行時にクラスの構造を動的に調べ、そのオブジェクトが特定の振る舞いをサポートしているかを判断できます。これは、ライブラリやフレームワークの開発において、柔軟な型のチェックや機能の拡張性を確保するために活用されることがあります。プログラミングの学習を進める上で、クラスとインターフェースの関係性を理解し、効率的なコード設計を行うために重要な役割を果たす関数の一つです。

基本的な使い方

構文(syntax)

<?php

interface MyInterfaceA
{
    public function methodA();
}

interface MyInterfaceB
{
    public function methodB();
}

class MyClass implements MyInterfaceA, MyInterfaceB
{
    public function methodA() {}
    public function methodB() {}
}

$interfaces = class_implements('MyClass');
print_r($interfaces);

?>

引数(parameters)

object|string $object_or_class, bool $autoload = true

  • object|string $object_or_class: インターフェースを実装しているか確認したいオブジェクトまたはクラス名
  • bool $autoload = true: インターフェースを自動的にロードするかどうかを指定するブール値。デフォルトは true

戻り値(return)

array|false

指定されたクラスが実装しているインターフェース名の配列を返します。実装しているインターフェースがない場合は false を返します。

サンプルコード

PHP class_implements で実装インターフェース取得

<?php

/**
 * プログラミング言語のインターフェースの例。
 * クラスがこのインターフェースを実装することで、特定の機能を提供することを保証します。
 */
interface LoggerInterface
{
    /**
     * メッセージを記録するメソッド。
     *
     * @param string $message 記録するメッセージ
     */
    public function log(string $message): void;
}

/**
 * 別のインターフェースの例。
 */
interface CacheableInterface
{
    /**
     * データをキャッシュに保存するメソッド。
     *
     * @param string $key   キー
     * @param mixed  $value 値
     * @return bool
     */
    public function set(string $key, mixed $value): bool;
}

/**
 * LoggerInterface を実装するクラスの例。
 * このクラスはログ機能を持ちます。
 */
class DatabaseLogger implements LoggerInterface
{
    public function log(string $message): void
    {
        echo "データベースにログを記録: " . $message . PHP_EOL;
    }
}

/**
 * 複数のインターフェースを実装するクラスの例。
 * このクラスはログ機能とキャッシュ機能の両方を持ちます。
 */
class DataManager implements LoggerInterface, CacheableInterface
{
    public function log(string $message): void
    {
        echo "DataManagerがログを記録: " . $message . PHP_EOL;
    }

    public function set(string $key, mixed $value): bool
    {
        echo "DataManagerがデータをキャッシュに保存: キー = '{$key}', 値 = '{$value}'" . PHP_EOL;
        return true;
    }
}

echo "--- DatabaseLogger クラスが実装しているインターフェース ---" . PHP_EOL;
// class_implements を使って、指定したクラスがどのインターフェースを実装しているか取得します。
// クラス名を文字列で渡すことも、`ClassName::class`のようにクラス定数で渡すこともできます。
$interfacesOfDbLogger = class_implements(DatabaseLogger::class);

// 戻り値は配列、または失敗した場合は false です。
if ($interfacesOfDbLogger !== false) {
    // 取得したインターフェースの配列を出力します。
    // キーと値が同じインターフェース名になる連想配列です。
    print_r($interfacesOfDbLogger);
} else {
    echo "DatabaseLogger クラスのインターフェース取得に失敗しました。" . PHP_EOL;
}

echo PHP_EOL;

echo "--- DataManager オブジェクトが実装しているインターフェース ---" . PHP_EOL;
// オブジェクトのインスタンスを class_implements に渡すこともできます。
$dataManager = new DataManager();
$interfacesOfDataManager = class_implements($dataManager);

if ($interfacesOfDataManager !== false) {
    print_r($interfacesOfDataManager);
} else {
    echo "DataManager オブジェクトのインターフェース取得に失敗しました。" . PHP_EOL;
}

echo PHP_EOL;

echo "--- 存在しないクラスを指定した場合 ---" . PHP_EOL;
// 存在しないクラス名を指定すると false が返されます。
$nonExistentClassInterfaces = class_implements('NonExistentClass');

if ($nonExistentClassInterfaces === false) {
    echo "存在しないクラス 'NonExistentClass' のインターフェース取得に失敗しました (期待される結果)。" . PHP_EOL;
} else {
    print_r($nonExistentClassInterfaces);
}

PHPのclass_implements関数は、指定されたクラスまたはオブジェクトがどのインターフェースを実装しているかを確認するために利用されます。インターフェースとは、クラスが特定のメソッド(機能)を持つことを保証するための「設計図」や「契約」のようなもので、例えばLoggerInterfaceはログ機能の、CacheableInterfaceはキャッシュ機能の提供をクラスに義務付けます。

この関数は、第1引数にクラス名(文字列形式、例: DatabaseLogger::class)またはオブジェクトのインスタンス(例: $dataManager)を取ります。サンプルコードでは、DatabaseLoggerクラスがLoggerInterfaceを、DataManagerクラスが複数のインターフェースを実装している例が示されています。

class_implements()を実行すると、そのクラスやオブジェクトが実装しているインターフェースの名前が、キーと値が同じ連想配列として戻り値で得られます。例えば、DatabaseLoggerの場合は['LoggerInterface' => 'LoggerInterface']のような配列が返されます。もし指定されたクラスが存在しないなど、インターフェースの取得に失敗した場合はfalseが返されるため、戻り値の確認は重要です。この関数を使うことで、実行時にクラスの機能性を動的に判断できるようになります。

class_implements関数は、指定したクラスやオブジェクトがどのインターフェースを実装しているかを調べたいときに使用します。引数には、クラス名を文字列で渡すか、ClassName::classのようにクラス定数で指定できます。また、クラスのインスタンスであるオブジェクトを直接渡すことも可能です。関数が成功すると、実装しているインターフェース名がキーと値になる連想配列を返します。クラスが見つからない場合や処理が失敗した場合は、falseが返されるため、戻り値がfalseでないか必ず確認してください。これにより、予期せぬエラーを防ぐことができます。

class_implements で実装インターフェースを取得する

<?php

/**
 * Interface 1: ロギング機能を提供します。
 */
interface LoggerInterface
{
    public function log(string $message): void;
}

/**
 * Interface 2: 実行可能な機能を提供します。
 */
interface RunnableInterface
{
    public function run(): void;
}

/**
 * Interface 3: 設定可能な機能を提供します。
 */
interface ConfigurableInterface
{
    public function configure(array $settings): void;
}

/**
 * 複数のインターフェースを実装するクラスの例です。
 * MyServiceはLoggerInterface, RunnableInterface, ConfigurableInterfaceの全ての契約を満たします。
 */
class MyService implements LoggerInterface, RunnableInterface, ConfigurableInterface
{
    public function log(string $message): void
    {
        echo "[LOG] " . $message . PHP_EOL;
    }

    public function run(): void
    {
        echo "[RUN] サービスが実行されました。" . PHP_EOL;
    }

    public function configure(array $settings): void
    {
        echo "[CONFIG] サービスが以下の設定で構成されました: " . json_encode($settings) . PHP_EOL;
    }
}

// MyServiceクラスのインスタンスを作成します。
$myService = new MyService();

echo "--- クラス名 (文字列) を使用して実装インターフェースを取得 ---" . PHP_EOL;
// class_implements関数を使用して、MyServiceクラスが実装しているインターフェースを調べます。
// MyService::class は 'MyService' という文字列を返します。
$implementedInterfacesByClassName = class_implements(MyService::class);

if ($implementedInterfacesByClassName !== false) {
    echo "クラス '" . MyService::class . "' が実装しているインターフェース:" . PHP_EOL;
    foreach ($implementedInterfacesByClassName as $interfaceName) {
        echo "- " . $interfaceName . PHP_EOL;
    }
} else {
    echo "クラス '" . MyService::class . "' のインターフェース情報を取得できませんでした。" . PHP_EOL;
}
echo PHP_EOL;

echo "--- オブジェクトインスタンスを使用して実装インターフェースを取得 ---" . PHP_EOL;
// オブジェクトインスタンスを渡して、実装しているインターフェースを調べます。
$implementedInterfacesByObject = class_implements($myService);

if ($implementedInterfacesByObject !== false) {
    echo "オブジェクト (クラス '" . get_class($myService) . "') が実装しているインターフェース:" . PHP_EOL;
    foreach ($implementedInterfacesByObject as $interfaceName) {
        echo "- " . $interfaceName . PHP_EOL;
    }
} else {
    echo "オブジェクトのインターフェース情報を取得できませんでした。" . PHP_EOL;
}

echo PHP_EOL;

// 実際にサービス機能を使ってみる例
$myService->log("アプリケーション開始...");
$myService->run();
$myService->configure(['debug_mode' => true, 'port' => 8080]);
$myService->log("アプリケーション終了。");

?>

PHPのclass_implements関数は、指定されたクラスやオブジェクトがどのインターフェースを実装しているかを確認するための関数です。PHPでは、一つのクラスが複数のインターフェースを実装し、それぞれのインターフェースが定める契約(メソッドの定義)を全て満たすことができます。この関数は、引数としてクラス名を表す文字列、またはクラスのオブジェクトインスタンスのいずれかを受け取ります。戻り値は、実装されているインターフェースの完全修飾名がキーと値として含まれる連想配列です。もし、指定されたクラスがインターフェースを実装していない場合や、クラスが存在しない場合はfalseが返されます。

サンプルコードでは、MyServiceクラスがLoggerInterfaceRunnableInterfaceConfigurableInterfaceという3つのインターフェースを実装しています。class_implements関数にMyService::class(クラス名を表す定数)を渡すと、このクラスが実装している全てのインターフェースの名前が配列として取得されます。同様に、MyServiceクラスのインスタンスである$myServiceを渡した場合でも、同じインターフェース情報が得られます。これにより、プログラムの実行中に、あるクラスやオブジェクトが特定の機能群(インターフェース)を提供しているかを動的に判断できるようになります。

class_implements関数は、指定したクラスが実装しているインターフェースの一覧を取得します。引数にはクラス名を表す文字列、またはクラスのオブジェクトインスタンスのどちらも指定可能です。クラス名文字列にはクラス名::classのようにマジック定数を使用すると、タイプミスを防ぎ、より安全に記述できます。関数が正常に情報を取得できなかった場合、戻り値はfalseとなるため、必ずこのfalseチェックを行い、結果を適切に処理してください。インターフェースはクラスが満たすべき機能の「契約」を定義し、この関数はプログラムがその契約を正しく守っているか実行時に確認するのに役立ちます。

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