web-dev-qa-db-ja.com

PHPの変数からクラスをインスタンス化しますか?

私はこの質問がかなり曖昧に聞こえることを知っているので、例を使ってより明確にします:

$var = 'bar';
$bar = new {$var}Class('var for __construct()'); //$bar = new barClass('var for __construct()');

これは私がやりたいことです。どうしますか?もちろん、次のようにeval()を使用できます。

$var = 'bar';
eval('$bar = new '.$var.'Class(\'var for __construct()\');');

しかし、私はむしろeval()を避けたいです。 eval()なしでこれを行う方法はありますか?

131
Pim Jager

最初にクラス名を変数に入れます:

$classname=$var.'Class';

$bar=new $classname("xyz");

これは、多くの場合、Factoryパターンにラップされたようなものです。

詳細については、 名前空間と動的言語機能 を参照してください。

190
Paul Dixon

動的コンストラクターパラメーターも渡す方法

動的コンストラクターパラメーターをクラスに渡す場合は、次のコードを使用できます。

$reflectionClass = new ReflectionClass($className);

$module = $reflectionClass->newInstanceArgs($arrayOfConstructorParameters);

動的クラスとパラメーターの詳細

PHP> = 5.6

PHP 5.6以降、 Argument Unpacking を使用して、これをさらに簡素化できます。

// The "..." is part of the language and indicates an argument array to unpack.
$module = new $className(...$arrayOfConstructorParameters);

それを指摘してくれたDisgruntledGoatに感謝します。

59
flu

名前空間を使用する場合

私自身の調査結果では、クラスの完全な名前空間パスを宣言する必要があることを(私の知る限り)言及するのは良いことだと思います。

MyClass.php

namespace com\company\lib;
class MyClass {
}

index.php

namespace com\company\lib;

//Works fine
$i = new MyClass();

$cname = 'MyClass';

//Errors
//$i = new $cname;

//Works fine
$cname = "com\\company\\lib\\".$cname;
$i = new $cname;
58
csga5000
class Test {
    public function yo() {
        return 'yoes';
    }
}

$var = 'Test';

$obj = new $var();
echo $obj->yo(); //yoes
28
zalew