2009-09-04 19 views
1

"ベストプラクティス"という質問があります。私はPHPでOO MVCフレームワークを開発しています。クラスのほとんどは簡単に相互作用します。それらは文字通りコード内で宣言されて使用されます。たとえば、OOP PHP - オブジェクトと関数の名前を動的に構築/実行する

// In class 'getDetails' 
$db = new mysqli(.....); 
$db->query(.....); 

ただし、クラス名と関数名が動的に作成されることがあります。実際のクラスファイルはすべてフレームワークのどこかに作成され、配置されていますが、すべてが文字通り宣言され使用されるわけではありません。実行時までは、フレームワークが要求を完了するためにどのクラスを必要としているかを知ることはできません。そのため、クラス名と関数名は通常作成され、変数に格納されます。最も単純なケースでは、変数はオブジェクトの作成と関数の実行に使用されます。例:静的関数を実行するために、変数を使用しようとすると

$request = 'blog'; 
$action = 'view'; 
$class = new $request(); // Creates an blog object 
$class->$action(); // Runs the blog function view 

しかし、私はすでに変数はリテラル用法で使用することができませんでした(hereは、スタックオーバーフローの質問と答えです)
事態に遭遇してきました($ request :: $ action()は解析エラーを出します)。私は、クラス、関数、オブジェクトの相互作用/使用のためのPHPマニュアル関数を見てきましたが、これまでに対処する必要はありませんでした。

私の質問は、クラスと関数の名前が実行時に作成されるクラスと関数を処理して実行する最良の方法は何ですか?

+0

KISSの原則(http://en.wikipedia.org/wiki/KISS_principle)を読むことができます。 Zend、CakePHP、CodeIgniter、Symphonyなどを使用してください。 – inakiabt

+0

私はKISSを理解していますが、Zend、CakePHP、CodeIgniterなどもこの同じ問題に直面しています。彼らはちょうど解決し、ユーザーからそれを抽出しました。 –

答えて

4

どちらの方法は、両方の良いですが、持っていますクラスをインスタンス化するための表記法では、各クラス/メソッドが受け入れるパラメータを事前に知っておく必要があります。したがって、任意のパラメータを受け入れるfactory patternをデザインすることはできません。

call_user_func_array()を使用すると、任意のパラメータを使用できます。

$request = 'blog'; 
$action = 'view'; 
$params = array(
    $_GET['category'], 
    $_GET['limit'] 
); 
call_user_func_array(array($request, $action), $params); 

したがって、上記のコードは、リテラルと等価である:基本的に、call_user_func_array()

blog::view($_GET['category'], $_GET['limit']); 

メソッドブログへのパラメータとしての各値を渡し、配列$ paramsはを平坦化::図( )。動的/オブジェクトメソッド呼び出しと同じことを

call_user_func_array(array(new $request, $action), $params); 

しかしながら、これは、任意のクラスのインスタンスを作成し、それをパラメータの任意の数を渡すの問題を解決しません。これを行うには、ReflectionClassを使用します。

例:

$request = 'blog'; 
$action = 'view'; 
$configs = array('something', 'something else'); 
$params = array(
    $_GET['category'], 
    $_GET['limit'] 
); 
$instance = call_user_func_array(
    array(new ReflectionClass($request), 'newInstance'), 
    $configs 
); 
$return = call_user_func_array(array($instance, $action), $params); 

これはに相当します:あなたは、動的に任意のオブジェクトをインスタンス化し、(その__constructorにパラメータの任意の数を渡すことができ、これらのツールを使用

$configs = array('something', 'something else'); 
$params = array(
    $_GET['category'], 
    $_GET['limit'] 
); 
$blog = new blog($configs[0], $configs[1]); 
$blog->view($_GET['category'], $_GET['limit']); 

)ならびに任意の方法。

機能面で最も優れている場合は、call_user_func_array()とReflectionClass()を使用してください。 パフォーマンス面で最高の立場だった場合は、心配しないでください。優れたデザインと機能により、パフォーマンスが向上します。

0

私はあなたの質問を正しく理解していれば、これにはevalを使用します。静的関数に対してもこれを行うことができます。たとえば、私が数年前に構築したサイトのコードを次に示します。

function StaticObjectPrint($mysql,$template, $objecttype, $debug=0) { 
    foreach(eval("return $objecttype::ReturnStaticVariablesForPrinting(\$mysql);") as $key => $value) { 
     global $$key; 
     $$key = $value; 
    } 
    if($debug==1) 
     print_r ($GLOBALS); 

    return ParsePlainTextFile($template,1); 
} 

この場合、いくつかの異なるクラスのオブジェクトがありましたが、それらはすべてReturnStaticVariablesForPrinting関数を持っていました。ユーザーがクリックしたオブジェクトのタイプに応じて、各オブジェクトをインスタンス化する必要なく(そしてメモリを束ねることなく)、そのオブジェクトに関する静的な情報が返されます。これは、オブジェクトのプロパティのリストを作成するのに便利でした。使用

$request = 'blog'; 
$action = 'view'; 
$class = new $request(); // Creates an blog object 
$class->$action(); // Runs the blog function view 

:通常の表記法を使用して

:いくつかの制限を(私はこれは、いくつかのオブジェクト指向の原則に違反して実現するが、スピードのために必要だった)あなたが言及した