如何使用Zend_Db_Table进行自定义查询?

时间:2011-10-10 15:04:33

标签: php zend-framework zend-db

我需要在Zend_Db_Table之上实现一些带连接的东西。 It has come to my attention that Zend_Db_Table provides no easy method of doing joins by itself。因此,我决定只编写查询,然后使用Zend_Db_Adapter::fetchAll获取结果。

但是,我仍然需要将结果作为Zend_Db_Table_Rowset得到,以便其他代码期望行集仍能正常运行。因此,我需要从Zend_Db_Adapter获取数组,然后手动将其转换为Zend_Db_Table_Rowset

我该怎么做?

4 个答案:

答案 0 :(得分:4)

它不是一个记录的功能,但您可以使用任意数组的数据数组实例化Rowset对象。这就是Zend_Db_Table在其find()fetchall()方法中所做的事情。

<?php

// this can be the result of any Zend_Db_Statement::fetchAll()
$query_result = array(
  array('id'=>123, 'foo'=>'bar'),
  array('id'=>456, 'foo'=>'baz')
);

$rowset = new Zend_Db_Table_Rowset(
  array(
    'readonly' => true,
    'data'     => $query_result
  )
);

foreach ($rowset as $row) {
  print "id  = " . $row->id . "\n";
  print "foo = " . $row->foo . "\n";
}

请注意,这不是“实时”行集。您无法将字段和save()更改为数据库中的基表。行集或行中没有关于哪些基表包含与Row对象的字段对应的列的信息。原始SQL查询的某些列可能是表达式或聚合,因此无论如何都不会确定save()它们的方式。

因此,使用PDO::FETCH_OBJ将结果集作为对象而不是哈希数组获取基本上没有任何改进。


评论:

是的,您可以像使用反序列化的Rowset对象一样使用setTable()。但Zend_Db_Table_Row不知道每列属于哪个表。因此,它将尝试基于Row对象的字段生成UPDATE或INSERT查询。如果从中创建Row对象的结果集包含来自多个连接表的列,则此操作将失败。

您可以确保Row对象仅包含来自单个表的字段,并且包含主键列,并且明确地从表中的单个行映射行。

答案 1 :(得分:0)

Zend_Db_Table顾名思义就是抽象数据库表。您可以加载数据,更改数据并保存结果。但是,这意味着您仅限于您的实例正在抽象的表。

您可以通过调用select()来更新对象的select语句。然后,您可以在其他表上加入(),然后进行fetchall(select)以从连接表中获取数据。但是,由于zend_db_table抽象了一个表,它不会允许你。

你可以通过在select上执行setIntegrityCheck(false)来解决这个问题,这将允许你加入。但是,这意味着您只能通过此对象读取数据。写作将被禁用。

或者,您可以使用zend_db_select对象,而不是映射到特定表。

答案 2 :(得分:0)

我之前也受到了阻碍。除非您自己编写实现,否则我认为您不能返回zend_db_table_rowset。尝试查看行集摘要以查看结构的工作原理。 zend_db_table_rowset是zend_db_table_row对象的集合。您从zend_db_adapter获得的内容不兼容*。您可能需要做的是以某种方式将结果转换为zend_db_table_rows,然后将它们添加到新的zend_db_table_rowset以获取对这些类的所有成员的访问权。

*这描述了可以从Zend_Db_Adapter返回的内容,我没有看到Zend_Db_Table / Rowset / Row作为选项: http://framework.zend.com/manual/en/zend.db.adapter.html#zend.db.adapter.select.fetch-mode

答案 3 :(得分:0)

  $table = new Zend_Db_Table('tableName');

    $myRowset = $table->fetchAll();

最后,Zend_Db提供了通过Zend_Db_Select连接表的绝佳方法。