2017-06-13 67 views
0

如何在使用tableadapter時在zend3中加入表格?問題不在於如何在一般情況下連接表,而在於如何在zend中執行此操作,以及在何處放置代碼。如何使用tablegateway加入表格

比方說,我HABE例如*表類:

namespace Import\Model; 
use RuntimeException; 
use Zend\Db\TableGateway\TableGatewayInterface; 

class ProjectTable 
{ 
    private $tableGateway='t_project'; 

    public function __construct(TableGatewayInterface $tableGateway) 
    { 
     $this->tableGateway = $tableGateway; 
    } 

public function fetchAll() 
{ 
    return $this->tableGateway->select(); 
} 

我想加入兩個表,我怎麼能做到這一點,北京時間這裏這樣做的正確的地方?我試圖實現以下功能:

public function Project_Unit(Unit $unit = null){ 

    $select = $this->tableGateway->getSql()->select() 
    ->join('t_unit', 't_project.ProjectID = t_unit.ProjectID',array('UnitID','CI_Number', 'Unitname','Shortcut','Suppliername'));  //, left 
    return $this->tableGateway->selectWith($select); 

} 

我沒有得到一個錯誤,我得到了反而混合了數據。之後,我嘗試別名也沒有工作。

我的問題是,如何構建這個表類,如果我需要連接兩個表。這些表格將是項目1 - > n單元(關鍵項目ID)。第二個問題是如何正確使用別名,因爲我在這兩個表中都有一些字段名與不同的數據,例如每個表都有一個列快捷方式。

編輯:新的信息 要查看的數據從何而來,我重新命名Exchangearray的變量:

public function exchangeArray(array $data) 
{ 
    $this->PProjectID= !empty($data['ProjectID']) ? $data['ProjectID'] : null; 
    $this->PCI_Number= !empty($data['CI_Number']) ? $data['CI_Number'] : null; 
    $this->PDescription= !empty($data['Description']) ? $data['Description'] : null; 
    $this->Projectname= !empty($data['Projectname']) ? $data['Projectname'] : null; 
    $this->PShortcut= !empty($data['Shortcut']) ? $data['Shortcut'] : null; 
    $this->PComponent_Class= !empty($data['Component_Class']) ? $data['Component_Class'] : null; 
} 

現在我得到一個有趣的輸出(我加我DataArray中的內容也)

output in browser

我有兩列被命名爲相同的,那將是快捷和CI-數,這些數據域與來自TableAdapter的表一樣的人混在一起。

U1不是伽利略的快捷方式,它是單位的捷徑。伽利略的捷徑應該是GAL。看起來這些名稱相同的列由第二個表格(單元)填充,但我不會從表格單元獲取任何字段。

編輯:顯示我從jobaer做出來的sugestions的加法:

我編輯ProjectTable類:

class ProjectTable 
{ 
    //private $tableGateway='t_project'; 
    private $projectTableGateway; 
    private $unitTableGateway; 


// public function __construct(TableGatewayInterface $tableGateway) 
// { 
//  $this->tableGateway = $tableGateway; 
// } 

public function __construct(
     TableGatewayInterface $projectTableGateway, 
     TableGatewayInterface $unitTableGateway) 
{ 
    $this->projectTableGateway = $projectTableGateway; 
    $this->unitTableGateway = $unitTableGateway; 
} 


public function fetchAll() 
{ 

    $sqlSelect = $this->unitTableGateway->getSql()->select(); 

    /** 
    * columns for the "project_table" exactly it is unit_table 
    */ 
    $sqlSelect->columns(array('CI_Number', 'ProjectID','Unitname','Shortcut','Suppliername')); 

    /** 
    * this can take two more arguments: 
    * an array of columns for "unit_table" 
    * and a join type, such as "inner" 
    */ 
$sqlSelect->join('t_project', 't_unit.ProjectID = t_project.ProjectID');  


    /** 
    * set condition based on columns 
    */ 
    //$sqlSelect->where(array('unit_table.project_id' => $id)); 

    $resultSet = $this->unitTableGateway->selectWith($sqlSelect); 

    return $resultSet; 



    //return $this->tableGateway->select(); 
} 

我還編輯我Module.php樣的建議,來了一個片段

//      Model\ProjectTable::class => function($container) { 
//       $tableGateway = $container->get(Model\ProjectTableGateway::class); 
//       return new Model\ProjectTable($tableGateway); 
//      }, 
         Model\ProjectTable::class => function($container) { 
          $projectTableGateway = $container->get(Model\ProjectTableGateway::class); 
          $unitTableGateway = $container->get(Model\UnitTableGateway::class); 
          return new Model\ProjectTable($projectTableGateway, $unitTableGateway); 
         }, 

         Model\ProjectTableGateway::class => function ($container) { 
          $dbAdapter = $container->get(AdapterInterface::class); 
          $resultSetPrototype = new ResultSet(); 
          $resultSetPrototype->setArrayObjectPrototype(new Model\Project()); 
          return new TableGateway('t_project', $dbAdapter, null, $resultSetPrototype); 
         } 

我的控制器動作並沒有改變:

return new ViewModel([ 
         'projects' => $this->projectTable->fetchAll(), 
          ]); 

在我看來,我想抓兩個表的列:

foreach ($projects as $project) : 
    // $unit=$units->fetchAllP($project->ProjectID); 
var_dump(get_object_vars($project));?> 
    <tr> 
    <td><?= $this->escapeHtml($project->Unitname) ?></td> 
    <td><?= $this->escapeHtml($project->Projectname) ?></td> 
    <td><?= $this->escapeHtml($project->Shortcut) ?></td> 
    <td><?= $this->escapeHtml($project->CI_Number) ?></td> 
    <td><?= $this->escapeHtml($project->Description) ?></td> 
     <td><?= $this->escapeHtml($project->Component_Class) ?></td> 


     <td> 
      <a href="<?= $this->url('project', ['action' => 'edit', 'id' => $project->ProjectID]) ?>">Edit</a> 
      <a href="<?= $this->url('project', ['action' => 'delete', 'id' => $project->ProjectID]) ?>">Delete</a> 
     </td> 

<?php endforeach; ?> 

我得到了一個有趣的輸出,這樣的東西是人仍下落不明。我希望從兩個連接的表中都有al列。

enter image description here

EDIT2:顯示下一版本

這裏是我的方法使用fetchall()/班ProjectTable

public function fetchAll() 
    { 

     $sqlSelect = $this->unitTableGateway->getSql()->select(); 
     $sqlSelect->columns(array('UnitID','CI_Number', 'ProjectID','Unitname','Shortcut','Suppliername')); 
     $sqlSelect->join('t_project', 't_unit.ProjectID = t_project.ProjectID', array('Project' =>'Projectname','CI' =>'CI_Number','PDescription' =>'Description','PShortcut' =>'Shortcut','PComponent' =>'Component_Class','PProjectID' =>'ProjectID')); 
     //$sqlSelect->where(array('unit_table.project_id' => $id)); 
     $resultSet = $this->unitTableGateway->selectWith($sqlSelect); 

     //return $resultSet; 
     return $resultSet->toArray(); 

     //return $this->tableGateway->select(); 

這裏是我的viewscript:

<?php 
//var_dump(get_object_vars($projects)); 
foreach ($projects as $project) : 
//var_dump(get_object_vars($project)); 

?> 
    <tr> 
    <td><?= $project['Project']?></td> 
    <td><?= $project['CI']?></td> 
    <td><?= $project['Unitname']?></td> 
    <?php  
endforeach; ?> 

}

,在這裏新的截圖: screenshot shows the unit, but no column out of project

EDIT3:加藥裝置的東西

class UnitTable 
{ 
    private $tableGateway='t_unit'; 

    public function __construct(TableGatewayInterface $tableGateway) 
    { 
     $this->tableGateway = $tableGateway; 
    } 

    public function fetchAll() 
    { 
     return $this->tableGateway->select(); 
    } 

類股也:

class Unit implements InputFilterAwareInterface 
{ 
    public $UnitID; 
    public $CI_Number; 
    public $ProjectID; 
    public $Unitname; 
    public $Shortcut; 
    public $Suppliername; 

    private $inputFilter; 

    public function exchangeArray(array $data) 
    { 
     $this->UnitID= !empty($data['UnitID']) ? $data['UnitID'] : null; 
     $this->CI_Number= !empty($data['CI_Number']) ? $data['CI_Number'] : null; 
     $this->ProjectID= !empty($data['ProjectID']) ? $data['ProjectID'] : null; 
     $this->Unitname= !empty($data['Unitname']) ? $data['Unitname'] : null; 
     $this->Shortcut= !empty($data['Shortcut']) ? $data['Shortcut'] : null; 
     $this->Suppliername= !empty($data['Suppliername']) ? $data['Suppliername'] : null; 
    } 

Bcause我只有的sampleData的是,截圖我的兩個表單位和項目

databasestuff

EDIT4:Factorypart module.php

public function getServiceConfig() 
    { 
     return [ 
       'factories' => [ 
         Model\ImportTable::class => function($container) { 
          $tableGateway = $container->get(Model\ImportTableGateway::class); 
          return new Model\ImportTable($tableGateway); 
         }, 
         Model\ImportTableGateway::class => function ($container) { 
          $dbAdapter = $container->get(AdapterInterface::class); 
          $resultSetPrototype = new ResultSet(); 
          $resultSetPrototype->setArrayObjectPrototype(new Model\Import()); 
          return new TableGateway('t_dcl', $dbAdapter, null, $resultSetPrototype); 
         }, 
         Model\DclimportTable::class => function($container) { 
          $tableGateway = $container->get(Model\DclimportTableGateway::class); 
          return new Model\DclimportTable($tableGateway); 
         }, 
         Model\DclimportTableGateway::class => function ($container) { 
          $dbAdapter = $container->get(AdapterInterface::class); 
          $resultSetPrototype = new ResultSet(); 
          $resultSetPrototype->setArrayObjectPrototype(new Model\Dclimport()); 
          return new TableGateway('t_dcl_import', $dbAdapter, null, $resultSetPrototype); 
         }, 
         Model\FollowupTable::class => function($container) { 
          $tableGateway = $container->get(Model\FollowupTableGateway::class); 
          return new Model\FollowupTable($tableGateway); 
         }, 
         Model\FollowupTableGateway::class => function ($container) { 
          $dbAdapter = $container->get(AdapterInterface::class); 
          $resultSetPrototype = new ResultSet(); 
          $resultSetPrototype->setArrayObjectPrototype(new Model\Followup()); 
          return new TableGateway('t_dcl_wv', $dbAdapter, null, $resultSetPrototype); 
         }, 
         Model\UnitTable::class => function($container) { 
          $tableGateway = $container->get(Model\UnitTableGateway::class); 
          return new Model\UnitTable($tableGateway); 
         }, 
         Model\UnitTableGateway::class => function ($container) { 
          $dbAdapter = $container->get(AdapterInterface::class); 
          $resultSetPrototype = new ResultSet(); 
          $resultSetPrototype->setArrayObjectPrototype(new Model\Unit()); 
          return new TableGateway('t_unit', $dbAdapter, null, $resultSetPrototype); 
         }, 
//      Model\ProjectTable::class => function($container) { 
//       $tableGateway = $container->get(Model\ProjectTableGateway::class); 
//       return new Model\ProjectTable($tableGateway); 
//      }, 

         Model\ProjectTableGateway::class => function ($container) { 
          $dbAdapter = $container->get(AdapterInterface::class); 
          $resultSetPrototype = new ResultSet(); 
          $resultSetPrototype->setArrayObjectPrototype(new Model\Project()); 
          return new TableGateway('t_project', $dbAdapter, null, $resultSetPrototype); 
         }, 
         Model\ProjectTable::class => function($container) { 
          $projectTableGateway = $container->get(Model\ProjectTableGateway::class); 
          $unitTableGateway = $container->get(Model\UnitTableGateway::class); 

          return new Model\ProjectTable($projectTableGateway, $unitTableGateway); 
         } 
         ], 
         ]; 
    } 

回答

1

如果您知道如何處理模型中的兩個表格,這非常簡單。假設你有ProjectTable和​​模型和兩個TableGateway服務。那些將分別處理數據庫中的兩個表。所以,如果你想加入他們在您的ProjectTable模型,然後將

ProjectTable.php

class ProjectTable 
{ 
    private $projectTableGateway; 
    private $unitTableGateway; 

    public function __construct(
     TableGatewayInterface $projectTableGateway, 
     TableGatewayInterface $unitTableGateway) 
    { 
     $this->projectTableGateway = $projectTableGateway; 
     $this->unitTableGateway = $unitTableGateway; 
    } 

    public function projectUnit($id) 
    { 

     /** 
     * as you are joing with "project_table" 
     * this will handle "unit_table" 
     */ 
     $sqlSelect = $this->unitTableGateway->getSql()->select(); 

     /** 
     * columns for the "unit_table". 
     * if want to use aliases use as 
     * array('alias_name' => 'column_name') 
     */ 
     $sqlSelect->columns(array('column_one', 'column_two')); 

     /** 
     * this can take two more arguments: 
     * an array of columns for "project_table" 
     * and a join type, such as "inner" 
     */ 
     $sqlSelect->join('project_table', 'unit_table.project_id = project_table.id'); 

     /** 
     * set condition based on columns 
     */ 
     $sqlSelect->where(array('unit_table.project_id' => $id)); 

     $resultSet = $this->unitTableGateway->selectWith($sqlSelect); 

     return $resultSet; 
    } 
} 

現在處理兩個表創建兩個TableGateway服務,並將它們傳遞給ProjectTable的構造函數如下

Model\ProjectTable::class => function($container) { 
    $projectTableGateway = $container->get(Model\ProjectTableGateway::class);   
    $unitTableGateway = $container->get(Model\UnitTableGateway::class); 

    return new Model\ProjectTable($projectTableGateway, $unitTableGateway);   
} 
+0

我是一個更進一步,但它不能正常工作。輸出顯示了我可以抓住它們的unit_table的列,但它沒有找到兩個表中名稱相同的兩個旁邊的project_table的列。哪些是快捷方式和CI_Number。那麼我怎樣才能得到所有的專欄? –

+0

你的'ProjectTableGateway'沒問題,但沒有顯示你的'UnitTableGateway'。我評論說,在哪裏提供每個表的列。但我沒有告訴如何使用別名。這裏是單元表$ sqlSelect-> columns(array('alias_name'=>'column_name',...));這是用於項目表$ sqlSelect-> join('t_project','t_unit.ProjectID = t_project.ProjectID',array('alias_name'=>'column_name',...)); – unclexo

+0

我試過這個,只有一列,只是爲了弄清楚。 $ sqlSelect-> join('t_project','t_unit.ProjectID = t_project.ProjectID',array('P'=>'Projectname'));我得到一個錯誤注意:未定義的屬性:導入\ Model \ Unit :: $ P在第37行的C:\ xampp \ htdocs \ ohb \ module \ Import \ view \ import \ import \ index.phtml和我的vardump do not顯示該列。 –

0

的,我認爲你是缺少點。您不訪問操縱表格網關的表格。你應該做的是使用表網關,這樣你就不必再處理表和SQL了。因此模式的名稱Table Gateway

看看如何ZF manual describes this

完成此操作後,很容易在表格網關的單個方法後面連接兩個表格。該方法返回一個完全從數據庫概念中刪除的模型。

+0

你可以再解釋一下還是舉個加入的例子?因爲我已經閱讀了所有我能找到的東西,而且我沒有理解。當然,我可以在我的控制器中訪問我的適配器,並從這裏運行一個sql,但我真的很想了解這個tablegateway概念。 –

+0

thx給你也jobain得到了解決方案 –