Php 如何将模型中的Zend_Db_表名更改为插入多个表中

Php 如何将模型中的Zend_Db_表名更改为插入多个表中,php,zend-framework,models,zend-db-table,Php,Zend Framework,Models,Zend Db Table,使用Zend Framework,我创建了一个模型来将记录插入数据库。我的问题是,在$this->insert($data)之后,如何切换活动表,以便将记录插入到另一个表中 以下是我目前的代码: class Model_DbTable_Foo extends Zend_Db_Table_Abstract { protected $_name = 'foo'; public function addFoo($params) { $data = array( 'fo

使用Zend Framework,我创建了一个模型来将记录插入数据库。我的问题是,在
$this->insert($data)
之后,如何切换活动表,以便将记录插入到另一个表中

以下是我目前的代码:

class Model_DbTable_Foo extends Zend_Db_Table_Abstract
{
  protected $_name = 'foo';

  public function addFoo($params)
  {
    $data = array(
      'foo' => $params['foo'],
    );
    $this->insert($data);
    $foo_id = $this->getAdapter()->lastInsertId();

    $data2 = array(
      'bar' => $params['bar']
    );
    // I need to change the Db Table name here.
    $this->insert($data2);
    $bar_id = $this->getAdapter()->lastInsertId();
  }
}

我想你应该有另一个
模型表
模型表
并称之为

内部

class Model_DbTable_Foo ... {
  public function addFooAndBar() {
    ...
    $bar = new Model_DbTable_Bar();
    $bar->insert($data2);
  }
}
class ModelX ... {
  public function addFoos() {
    $foo = new Model_DbTable_Foo();
    $foo->insert($data);
    $bar = new Model_DbTable_Bar();
    $bar->insert($data2);
  }
}
或外部:

class Model_DbTable_Foo ... {
  public function addFooAndBar() {
    ...
    $bar = new Model_DbTable_Bar();
    $bar->insert($data2);
  }
}
class ModelX ... {
  public function addFoos() {
    $foo = new Model_DbTable_Foo();
    $foo->insert($data);
    $bar = new Model_DbTable_Bar();
    $bar->insert($data2);
  }
}

Zend_Db_表
。它

充当数据库表的网关。一个实例处理表中的所有行

这意味着,每个表有一个类。您的
Model\u DbTable\u Foo
表示数据库中的Foo表,并且仅表示此表。它不应该在其他表上进行插入。这就是使用另一个table类的目的。最干净的选择是在TDG上添加另一层,它知道如何处理多个表的插入,例如

class Model_Gateway_FooBar
{
    protected $_tables;

    public function __construct(Zend_Db_Table_Abstract $foo, 
                                Zend_Db_Table_Abstract $bar)
    {
        $this->_tables['foo'] = $foo;
        $this->_tables['bar'] = $bar;
    }

    public function addFoo($data)
    {
        $this->_tables['foo']->insert($data['foo']);
        // yaddayaddayadda
        $this->_tables['bar']->insert($data['bar']);
    }
}
但是,这是你的应用程序,你可以决定不去打扰,只需在Foo类中创建另一个类的新实例,然后从那里进行插入,例如

$otherTable = new Model_DbTable_Bar;
$otherTable->insert($data);
另一种选择是将逻辑放入控制器中,但我不推荐这样做,因为这不是控制器的责任,一般来说也是如此

另一方面,当您执行多个插入时,您可能希望使用事务使两个插入都按预期工作,例如

$this->_tables['foo']->getAdapter()->beginTransaction();
然后根据查询结果执行
commit()
rollback()

另外请注意,从ZF1.9开始,您还可以创建Zend_Db_表的实例,而无需首先定义具体的子类,例如

$fooTable = new Zend_Db_Table('foo');

请参阅上的章节。

您也可以使用该类。 大概是这样的:

 $fooTbl = new Zend_Db_Table('foo');
 $lastFooID = $fooTbl->insert($data2)
                     ->getAdapter()
                     ->lastInsertId();

非常好的建议!我忘记了所有的交易,我一定要使用它们。谢谢戈登,你能解释一下为什么我想在构造函数中键入cast$foo和$bar作为Zend_Db_Table_Abstract而不是我的自定义模型_DbTable_foo和模型_DbTable_bar吗?这只是对MySQL事务感兴趣的其他人的一个提示:我必须将我的Db类型从MyISAM更改为InnoDB以获得事务支持。@jwhat这不是类型转换,而是打字提示。请看-您可以在这里使用自定义模型类,但这会将您的具体模型类耦合到网关。当使用抽象类作为提示时,请确保传递的实例(仅)是表实例。它们不一定是您的自定义类,但本例中的要点是,确保实例具有Zend_Db_Table_Abstract的方法。如果需要将自定义类与其他类交换,它也更灵活。@简言之,依赖抽象类型(接口、抽象基类)总比依赖具体类型好。这允许您更改方法的实现,而不会影响其任何调用方。唯一表的唯一类很有意义,而且感觉更干净。谢谢