Comment joindre les tables à zend3 lors de l'utilisation TableAdapter? La question n'est pas de savoir comment joindre les tables en général, mais comment faire cela dans zend et où placer le code.comment rejoindre les tables en utilisant tablegateway
Disons que je habe une classe de table * par exemple:
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();
}
Je voudrais joindre deux tables, comment puis-je faire, Ist ici le bon endroit pour le faire? J'ai essayé d'implémenter la fonction suivante:
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);
}
Je n'ai pas eu d'erreur, j'ai plutôt mélangé des données. Après cela, j'ai essayé avec des alias ne fonctionnait pas non plus.
Ma question est, comment construire ce TableClass, si je dois joindre deux tables. Les tables seront projet 1 -> n unit (clé projectID). La deuxième question serait de savoir comment utiliser les alias correctement, parce que j'ai des noms de champs dans les deux tables avec des données différentes, par exemple chaque table a un raccourci de colonne.
EDIT: De nouvelles informations Pour voir où proviennent les données, je renomme les variables de mon 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;
}
Maintenant, je reçois une sortie intéressante (j'ai ajouté le contenu de mon tableauDonnees aussi)
J'ai deux colonnes qui portent le même nom, qui sera raccourci et ci-nombre, ces zones de données sont mélangés avec les mêmes de la table TableAdapter.
U1 est pas le raccourci de Galileo est le raccourci de l'appareil. Le raccourci de Galileo devrait être GAL. Il semble que les colonnes nommées de la même manière soient remplies par la seconde table (unité) mais je ne recevrai aucun champ de l'unité de table.
EDIT: pour montrer l'addition, je distinguais des sugestions de jobaer:
ma classe I edited 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();
}
J'ai effectué aussi mon module.php comme suggéré, est ici un extrait
// 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);
}
Mon action du contrôleur n'a pas changé:
return new ViewModel([
'projects' => $this->projectTable->fetchAll(),
]);
À mon avis j'ai essayé de saisir les colonnes des deux tables:
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; ?>
J'ai eu une sortie intéressante, donc quelque chose manque encore. Je m'attendais à avoir toutes les colonnes des deux tables jointes.
EDIT2: montrer prochaine version
ici est ma méthode fetchAll()/classe 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();
Voici mon 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; ?>
}
et voici une nouvelle capture d'écran:
EDIT3: l'ajout d'unité Stuff
class UnitTable
{
private $tableGateway='t_unit';
public function __construct(TableGatewayInterface $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
return $this->tableGateway->select();
}
Unité de classe aussi:
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 Je n'ai SampleData encore, une capture d'écran de mes deux tables unité et projet
EDIT4: Factorypart de 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);
}
],
];
}
Je suis un grand pas en avant, mais cela ne fonctionne pas encore correctement.La sortie montre les colonnes de la table unit_table je peux les saisir al, mais elle n'a pas trouvé les colonnes de la table project_table à côté des deux qui sont nommés les mêmes dans les deux tables. Quels sont raccourci et CI_Number. Alors, comment puis-je obtenir toutes les colonnes? –
Votre 'ProjectTableGateway' est correct mais n'affiche pas votre' UnitTableGateway'. J'ai commenté là où fournir des colonnes pour chaque table. Mais je n'ai pas dit comment utiliser les alias. Ici c'est pour la table d'unité $ sqlSelect-> columns (array ('alias_name' => 'column_name', ...)); C'est pour la table de projet $ sqlSelect-> join ('t_project', 't_unit.ProjectID = t_project.ProjectID', array ('alias_name' => 'nom_colonne', ...)); – unclexo
J'ai essayé ceci, avec une seule colonne, juste pour comprendre. $ sqlSelect-> join ('t_project', 't_unit.ProjectID = t_project.ProjectID', array ('P' => 'Nom du projet')); Je reçois une erreur Remarque: Propriété non définie: Importer \ Model \ Unit :: $ P dans C: \ xampp \ htdocs \ ohb \ module \ Import \ view \ import \ import \ index.phtml sur la ligne 37 et mon vardump ne pas montre la colonne. –