【问题标题】:ZF2 TableGateway joinZF2 TableGateway 连接
【发布时间】:2014-10-30 14:31:35
【问题描述】:

我正在尝试通过标准 PHP 学习 OO/Zend 框架。我想尖叫并编写一个 mysql 查询而不是使用 TableGateway 方法。

我一直在关注教程并成功打印出一个表格和一些字段,尽管按照我这样做的方式,我完全不知道如何将它与另一个表格连接并打印出一些字段在那里。

例如。

表格字段 客户 IDx,公司 联系 Idx,名字

这是我的customersController,我假设工作在其中进行

      namespace Customers\Controller;

      use Zend\Mvc\Controller\AbstractActionController;
      use Zend\View\Model\ViewModel;
      use Zend\DB\TableGateway\TableGateway;


class CustomersController extends AbstractActionController
 {

 protected $customersTable;

 public function indexAction()
 {
     return new ViewModel(array('customer' => $this->getCustomersTable()->select()));
     //return new ViewModel(array('customers' => $this->fetchJoin()->select()));
 }

 public function addAction()
 {
 }

 public function editAction()
 {
 }

 public function deleteAction()
 {
 }

 public function getCustomersTable()
 {
        if (!$this->customersTable) {
        $this->customersTable = new TableGateway (
        'customer', //table name
         $this->getServiceLocator()->get('Zend\DB\Adapter\Adapter')
         );
     }
     return $this->customersTable;


    }

   }

我在正确的轨道上吗?

【问题讨论】:

    标签: zend-framework2


    【解决方案1】:

    如果您需要进行连接,请阅读 Zend\Db\Sql 和 Zend\Db\Select 你可以在这里阅读

    http://framework.zend.com/manual/2.0/en/modules/zend.db.sql.html

    一个例子是:

    在您的模型中(扩展 TableGateway 或 AbstractTableGateway)
    在某些功能中,您可以拥有类似的东西(这是来自一个项目):

    $sql = new \Zend\Db\Sql\Sql($this->getAdapter());
    
    $select = $sql->select()
        ->from('event_related_events')
        ->columns(array())
        ->join('event_invitees', 'event_invitees.event_id = 
           event_related_events.related_event_id')
        ->where(array('event_related_events.event_id' => $eventId));
    
    $selectString = $sql->getSqlStringForSqlObject($select); 
    $results      = $this->getAdapter()->query($selectString, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
    

    然后你可以循环遍历结果并做你需要做的事情。

    看看像 Doctrine 或 Propel 这样更强大的 ORM 也可能会有所帮助,但对于小型/业余项目来说可能是矫枉过正。


    编辑:回答 cmets 中的问题

    对于直接使用表达式(if、case 等),您可以使用类似:

     $sql->select()
        ->from('table')
        ->columns(array(
            'sorter' => new Expression('(IF ( table.`something` >= 'otherthing',  1,  0))'),
        'some_count' => new Expression('(count(*))'),
        )
    )
    

    用 SQL 术语解释最后一行,它是: count(*) AS some_count

    【讨论】:

    • 很好的例子。我不同意你关于教义和推进的说法。我倾向于在“小型”项目中使用 ORM,并在应用程序过于复杂而无法单独依赖 ORM 时回退到 Zend 组件。不要误会我的意思,我很喜欢教条。我不喜欢推进器,但我确实在必要时使用它。我不会把开销带到这里。我觉得在经常更改并需要模型具有很大灵活性的应用程序中使用 ORM 通常会导致糟糕的设计选择以使某些东西“工作”。 ORM 旨在与实现而不是接口一起使用。
    • 不过如此。在大多数情况下,学说具有您需要的所有功能。我想说为工作选择合适的工具。
    【解决方案2】:

    这是我的控制器,基本上来自专辑示例,但现在它将显示来自客户表的客户。

    <?php
    
        namespace Customers\Controller;
    
         use Zend\Mvc\Controller\AbstractActionController;
         use Zend\View\Model\ViewModel;
         use Customers\Model\Customers;          
         use Customers\Form\CustomersForm; 
    
         class CustomersController extends AbstractActionController
         {
    
          protected $customersTable;
    
             public function indexAction()
             {
                 return new ViewModel(array(
                     'customer' => $this->getCustomersTable()->fetchAll(),
                 ));
             }
    
            public function addAction()
            {
            }
    
            public function editAction()
             {
             }
    
            public function deleteAction()
            {
            }
    
             public function getCustomersTable()
             {
                 if (!$this->customersTable) {
                     $sm = $this->getServiceLocator();
                     $this->customersTable = $sm->get('Customers\Model\CustomersTable');
                 }
                 return $this->customersTable;
             }
    
    
    
         }
    
    
         ?>
    

    indexAction 调用 getCustomersTable 方法,该方法进入模型 (CustomersTable) 并在那里执行“查询”。

    <?php
    
    namespace Customers\Model;
    
     use Zend\Db\TableGateway\TableGateway;
    
     class CustomersTable
     {
         protected $tableGateway;
    
         public function __construct(TableGateway $tableGateway)
         {
             $this->tableGateway = $tableGateway;
         }
    
         public function fetchAll()
         {
             $resultSet = $this->tableGateway->select();
             return $resultSet;
         }
    
         public function getCustomers($id)
         {
    
         }
    
         public function saveCustomers(customers $customers)
         {
    
         }
    
    
         public function deleteCustomers($id)
         {
         }
     }
    
     ?>
    

    所以从您的示例中,我应该尝试将其实现到模型中的 fetchAll 中? 感谢您的帮助。

    $sql = new \Zend\Db\Sql\Sql($this->getAdapter());
    
            $select = $sql->select()
        ->from('customer')
        ->columns(array())
        ->join('contact', 'contact.Idx = customer.Idx')
        ->where(array('contact.Idx' => $eventId));
    
    $selectString = $sql->getSqlStringForSqlObject($select); 
    $results      = $this->getAdapter()->query($selectString, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
    

    【讨论】:

    • 是的,您可以这样做,但这取决于您,但是当您为客户获取联系人时,使用名为 getContacts() 或类似的函数会更好。
    • 哦,太好了,我搞定了。非常感谢。虽然更进一步,但在我的 sql 查询中,我有一些条件,例如。 select location.* if ( xxxxxxx ) as Name where .... 这可能与tablegateway有关吗?
    • 看看 Zend\Db\Sql\Expression,也许这就是你需要的。
    • 在答案中为您添加示例
    • 这太完美了,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    相关资源
    最近更新 更多