PHP

クラスを指定するいろいろな方法(スタブ)

自分用メモです…。不備あると思いますのでもっと調べてからまとめます。

何がしたい?

PHPってホントにインタプリタだなーと思うのが、クラス名や関数名を文字列で指定できたりするところ。たとえばあるインスタンスが取り扱うクラスを「クラス名」で注入することができたりするんですよね。その是非はともかく、他にどんなやりかたができるのか調べてみたものです。

class NewClass 
{
  public $val = "TEST\n";

  public function echo() { echo $this->val; }

  public static function print() { echo "PRINT\n"; }
}

こんなクラスがあるとして

// ふつう
$new = new NewClass;
$new->echo(); // TEST

// スタティック ふつう
NewClass::print(); // PRINT

// スタティック インスタンスから呼び出す
$new->print(); // PRINT インスタンスメソッドに見えるけどスタティック
$new::print(); // PRINT

// スタティック 文字列
(NewClass::class)::print(); // PRINT
'NewClass'::print(); // PRINT
$class = "NewClass";
$class::print(); // PRINT

// new 文字列
$class = "NewClass";
$new = new $class;
$new->echo(); // TEST

// new 文字列
$class = NewClass::class;
$new = new $class;
$new->echo(); // TEST

// new 文字列ダイレクト ....NG 意外と通らない
$new = new "NewClass";  // Syntax Error

// new 文字列ダイレクト ....NG これも通らない(意味ないけど)
$new = new NewClass::class; // Syntax Error
$new = new (NewClass::class); // Syntax Error


// インスタンスからクラス名を取得して new
$class = get_class($new);
$new = new $class;
$new->echo(); // TEST

// 修正を加えたインスタンスを用意して
$new = new NewClass;
$new->val = "MOD\n\n";
$new->echo();  // MOD

// そのインスタンスから新しいインスタンス
$new = new $new;
$new->echo();  // TEST

// 定数
define('NEW_CLASS',NewClass::class);
echo NEW_CLASS; // New Class

NEW_CLASS::print(); // NG Syntax Error
$new = new NEW_CLASS; // NG Syntax Error

インスタンスから新しいインスタンスを作成したり(JavaScriptみたいだ)、文字列やインスタンスからスタティックが呼び出せるか、と思ったのがきっかけで、結論としては、コレでいいや、といった感じ。

$new = new $old;

$new::print();

2つ目のスタティックが $new->print() じゃないのは、インスタンスメソッドに見えることと、$newが文字列"NewClass"だと動かないから。::だと文字列でも動くという…。