2009-07-10 4 views
4

私はMVCが初めてです。あなたは警告されています...MVC:ビューはクエリ結果をループできますか?

私はMySQLの結果リソースをコントローラに返すことができるユーザーモデルを持っています。コントローラーはMySQLリソースを表示するビューに渡します。データベース結果取得関数を使用して、クエリ結果をビューに出力することは可能ですか?

<?php while($row = some_fetching_function($database_result_resource): ?> 
<tr> 
    <td><?=$row['Username']?></td> 
    ...etc 
</tr> 
<?php endwhile; ?> 

これは私にとっては正しくありません。密接に結合されていますよね?モデルはある種のデータベースリソースを返さなければならず、ビューは何らかのタイプのデータベースフェッチメソッドを使用してビューをループしなければなりません。結果を2回ループせずにデカップリングすることはできますか?モデルの結果をループして結果の配列を作成し、次にビューを再度作成する必要があると思います。要約すると

:MVCデザインパターンに付着しながら

  1. ビューは、データベースの結果リソースを表示することができますか?
  2. データベースとの緊密な結合を回避しながら、データを2回ループさせないようにすることはできますか?

答えて

6

コードのデータベース部分を抽象化すれば、それは受け入れられると思います。たとえば、反復可能な「行セット」を提供することができます(Iterableインターフェースなどを実装します)。このオブジェクトの背後には、データベース結果が含まれ、フェッチ機能が使用される可能性があります。

基本的な考え方は、データベースや他のソースからのものではなく、カップリングを減らすことを意味する一般的な見た目の行セットを扱うことです。

2

もちろん可能です。しかし、実際にはビュー内の行をフェッチしないでください。モデルデータの割り当てはコントローラで行いますが、ビューには直接は行いません。 Hooray Im助けが指摘したように、データの取得は使用しているモデルによって異なります。しかし、ビューにはDatabase固有のメソッドやモデルロジックを持たないでください。モデルが一般的なIteratorインターフェイスを実装している場合は、ビューに直接渡すことができます。

<?php 
public function someControllerAction($params) 
{ 
    $myModel = Model::getModel('Model Name'); 
    // But you don't do Model::getModel('Model Name')->getResults($params['date']) in your viewa 
    $this->view->rows = $myModel->getResults($params['date']); 
} 
?> 
+1

これは、OPの要件番号2を避けるものではありません。 Iteratorインターフェイスを実装するクラスラッパーを使用して、彼が求めたことを行うことができます。 – Martin

+0

"コントローラでフェッチを行い、配列に入れてこれをビューに渡します。" 私は混乱しています、Daff - コントローラではなく、モデルでフェッチを行うべきではないですか? –

+0

それはそれを表現する最良の方法ではありませんでした。私はそれが本当にアーキテクチャにも依存していると思う。私が意味していたことは、モデルデータのビューへの割り当ては、ビューではなくコントローラで行われることです(少なくとも私が扱ったリクエスト/レスポンスベースのPHPフレームワークのほとんどで)。 – Daff

0

Jani氏によると、MySQLの結果は、標準のPHPライブラリのIterableインターフェイスを実装するクラスにラップする必要があります。このようにして、ビューは使い慣れた一般的なforeach構造体を使用できますが、配列に配置するだけで結果を2回反復する必要はありません。

SPL

 
class rswrap implements Iterator 
{ 
    var $rs; 
    var $current; 

    function __construct($rs) 
    { 
     $this->rs = $rs; 
    } 

    function rewind() 
    { 
     // do nothing 
    } 

    function next() 
    { 
     $this->current = some_fetching_function($this->rs); 
    } 

    function current() 
    { 
     return $this->current; 
    } 

    function valid() 
    { 
     return $this->current !== false; 
    } 

    function key() 
    { 
     return 0; // usually sufficient but you may want to write a real key function. 
    } 
} 

$resultset = new rswrap($database_result_resource); 

foreach($resultset as $row) 
{ 
    // your code here 
} 
0

私は最善の方法は、オブジェクトのリストの中に抽象化へのSQLクエリの結果であるとリストを返すと思います。

私は、行セットを反復すると、使用している特定のデータベース接続からビューが分離されているとは思われません。ビューは、使用されているデータベース接続とは独立している必要があります。 JDBCを使用するか、休止状態にするか、何を変更するかは、ビューに変更を加える必要があります。

関連する問題