如何更改模型中的Zend_Db_Table名称以插入多个表

jwh*_*hat 3 php zend-framework zend-db-table models

使用Zend Framework,我创建了一个Model来将记录插入数据库.我的问题是,$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();
  }
}
Run Code Online (Sandbox Code Playgroud)

Gor*_*don 6

Zend_Db_Table是一个表数据网关.它

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

这意味着,每个表有一个类.您Model_DbTable_Foo表示数据库中的Foo表,仅表示此表.它不应该在其他表上插入.这就是你要使用另一个表类的原因.最干净的选择是在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']);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,它是你的应用程序,你可以决定不打扰并简单地在Foo类中创建另一个类的新实例并从那里执行插入,例如

$otherTable = new Model_DbTable_Bar;
$otherTable->insert($data);
Run Code Online (Sandbox Code Playgroud)

另一种选择是将逻辑放入控制器,但我不推荐它,因为这不是控制器的责任,通常控制器应保持薄,模型应该很胖.

在旁注中,当您进行多次插入时,您可能希望使用事务来使两个插入按预期工作,例如

$this->_tables['foo']->getAdapter()->beginTransaction();
Run Code Online (Sandbox Code Playgroud)

然后commit()rollback()取决于查询结果.

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

$fooTable = new Zend_Db_Table('foo');
Run Code Online (Sandbox Code Playgroud)

请参阅ZF参考指南中有关Zend_Db_Table的章节.