動的クラス(つまり変数から)を使用して広告インスタンスを作成するコードがあります。
$instance = new $myClass();
コンストラクターの引数数は値によって異なるため、$myClass
引数の変数リストを新しいステートメントに渡すにはどうすればよいですか?出来ますか?
class Horse {
public function __construct( $a, $b, $c ) {
echo $a;
echo $b;
echo $c;
}
}
$myClass = "Horse";
$refl = new ReflectionClass($myClass);
$instance = $refl->newInstanceArgs( array(
"first", "second", "third"
));
//"firstsecondthird" is echoed
上記のコードでコンストラクターを検査することもできます。
$constructorRefl = $refl->getMethod( "__construct");
print_r( $constructorRefl->getParameters() );
/*
Array
(
[0] => ReflectionParameter Object
(
[name] => a
)
[1] => ReflectionParameter Object
(
[name] => b
)
[2] => ReflectionParameter Object
(
[name] => c
)
)
*/
最も簡単なルートは、配列を使用することです。
public function __construct($args = array())
{
foreach($array as $k => $v)
{
if(property_exists('myClass', $k)) // where myClass is your class name.
{
$this->{$k} = $v;
}
}
}
理由はわかりませんが、コードでnew演算子を使用するのは好きではありません。
これは、静的に呼び出されるクラスのインスタンスを作成するための静的関数です。
class ClassName {
public static function init(){
return (new ReflectionClass(get_called_class()))->newInstanceArgs(func_get_args());
}
public static function initArray($array=[]){
return (new ReflectionClass(get_called_class()))->newInstanceArgs($array);
}
public function __construct($arg1, $arg2, $arg3){
///construction code
}
}
名前空間内で使用している場合は、次のようにReflectionClassをエスケープする必要があります。new\ ReflectionClass ...
これで、可変数の引数を使用してinit()メソッドを呼び出すことができ、コンストラクターに渡されてオブジェクトが返されます。
新しいを使用する通常の方法
$obj = new ClassName('arg1', 'arg2', 'arg3');
echo $obj->method1()->method2();
新しいを使用したインライン方法
echo (new ClassName('arg1', 'arg2', 'arg3'))->method1()->method2();
newの代わりにinitを使用した静的呼び出し
echo ClassName::init('arg1', 'arg2', 'arg3')->method1()->method2();
newの代わりにinitArrayを使用した静的呼び出し
echo ClassName::initArray(['arg1', 'arg2', 'arg3'])->method1()->method2();
静的メソッドの良いところは、コンストラクター引数の検証など、initメソッドでいくつかの構築前の操作を実行できることです。