【PHP】PSR-4を崩さずその場で class object を作れる無名クラス

  • 2020年11月16日
  • PHP

 時折、再利用する気もないその場限りのクラスオブジェクトが欲しくなる時があります。例えば、インタフェースを満たしたクラスオブジェクトが引数として要求されているが既存のそのインタフェースを満たしたクラスを使いたくない時です。そういった時ファイルを分けてクラスを新たに記述するのも手ですが、コード量がさほどでもなく、再利用する気もなく、拡張する予定もない時は使いどころのファイル内に記述したくなります。この時、1 ファイル内に 2 クラス書くこともできますが、これは PSR-4 に反しており一見外部から呼べそうながらも呼べない時があるクラスができることになり、事故の元となります。

/** app/TmpA.php */
// クラス定義ファイル。 TmpB が呼べない時のあるクラスです
namespace App;

class TmpA {

}

class TmpB {

}

/** script_fail.php */
// composer のオートローダ(PSR-4)でクラスを探します
require __DIR__.'/vendor/autoload.php';

new \App\TmpB(); // Uncaught Error: Class 'App\TmpB' not found でエラーになります。

/** script_success.php */
// composer のオートローダ(PSR-4)でクラスを探します
require __DIR__.'/vendor/autoload.php';

new \App\TmpA();
new \App\TmpB(); // TmpA でロードされたファイル中に \App\TmpB が定義されているのでエラーになりません。

 1 ファイル中に複数クラスを書きながらも PSR-4 に反しない仕組みとして無名クラスがあります。
PHP: 無名クラス – Manual
 無名クラスは例えば次の様に使えます。

<?php

class Hoge
{
}

/**
 * インタフェースを満たせ、継承もできます
 * コンストラクタに引数を渡すこともできます。
 */
$instance = new class(['a', 'b', 'c']) extends Hoge implements JsonSerializable {
    /** @var array プロパティを持てます */
    protected $arr;

    /**
     * コンストラクタを持てます
     * @param array $arr
     */
    public function __construct(array $arr)
    {
        $this->arr = $arr;
    }

    /**
     * JsonSerializable を満たすためのメソッドです
     * @return array
     */
    public function jsonSerialize()
    {
        return $this->arr;
    }
};

echo json_encode($instance);// ["a","b","c"]

 滅多に使わない機能ですが、その場で書き捨てるスクリプトやごく短く限られた範囲におけるDTO(DataTransferObject)などとして使うと案外便利です。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG