5

次のようなクラスの新しいインスタンスを作成しようとしています:

$obj = new $class;

私は、関数の共通セットが多くのクラスに対してこれを行う方法でこれを行っていますが、今はいくつかの引数を実装しています。ハンドラー関数は次のようになりますが、

function newInst($argA = null, $argB = null, $argC = null)

これには、事前にすべての引数を含める必要があり、上限があります。だから、私はこのようなことをしようとしています:

function newInst() {
    $obj = new $class(func_get_args());
    ...
}

しかし、最初の引数だけが適用されるのではなく、配列を引数のセットとして適用したいと思います。私が試してみました

function newInst() {
    $obj = new $class;
    call_user_func_array(array($obj, '__construct'), func_get_args());
    ...
}

しかし、それは__construct関数を2回呼び出します。__constructでは、呼び出された関数の引数を使用して、インスタンス化中にorclassname関数を通過する新しいインスタンスを作成する方法はありますか?

4

1 に答える 1

6

リフレクションの使用に反対しない場合: ReflectionClass::newInstanceArgs

function createInstance($class, array $arguments) {
    $reflection = new ReflectionClass($class);
    return $reflection->newInstanceArgs($arguments);
}

リフレクションには多くの機能があり、「遅い」という一般的な主張にもかかわらず、リフレクションがアプリケーションの真のボトルネックになることはほとんどありません。いずれにせよ、キャッシングによってあらゆる可能性を軽減できます。


議論に基づいて、count()チェックと単純なキャッシュを使用して仮想的なソリューションを修正しているだけです。それでも(間違いなく)プロファイリングが必要です。

function createInstance($class, array $arguments) {
    static $cache = [];
    switch (count($arguments)) {
        case 0: return new $class();
        case 1: return new $class($arguments[0]);
        case 2: return new $class($arguments[0], $arguments[1]);
        case 3: return new $class($arguments[0], $arguments[1], $arguments[2]);
    }
    if (!isset($cache[$class])) {
        $cache[$class] = new ReflectionClass($class);
    }
    return $cache[$class]->newInstanceArgs($arguments);
}    
于 2013-06-25T12:44:24.923 に答える