简体   繁体   中英

How does one use Zend_Db_Table with custom queries?

I need to implement something with joins on top of Zend_Db_Table. It has come to my attention that Zend_Db_Table provides no easy method of doing joins by itself . As a result, I have decided to simply write queries and then fetch the results using Zend_Db_Adapter::fetchAll .

However, I still somehow need to get the results as a Zend_Db_Table_Rowset so that other code expecting a rowset still operates correctly. I therefore need to take the array I get from Zend_Db_Adapter and turn that into a Zend_Db_Table_Rowset manually.

How can I do that?

It's not a documented feature, but you can instantiate a Rowset object with any arbitrary array of arrays of data. This is what Zend_Db_Table does in its find() and fetchall() methods.

<?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";
}

Note that this is not a "live" rowset. You can't change fields and save() them to the base tables in the database. There's no information stored in the rowset or rows about which base tables contain the columns corresponding to the fields of your Row objects. Some columns of your original SQL query may be expressions or aggregations, so there would be no deterministic way to save() them anyway.

So this is basically no improvement over using PDO::FETCH_OBJ to fetch result sets as objects instead of hash arrays.


Re comments:

Yes, you can use setTable() just like with a deserialized Rowset object. But Zend_Db_Table_Row does not have any idea which table each column belongs to. So it will try to generate an UPDATE or INSERT query based on the fields of the Row object. This will fail if the result set from which you make your Row object includes columns from more than one joined tables.

It's up to you to make sure the Row object contains fields only from a single table, and that the primary key column(s) are included, and that the Row is unambiguously mapped from a single row in the table.

Zend_Db_Table as its name suggests abstracts a database table. You can load data, change it and save the results. However, this means you're restricted to the table that your instance is abstracting.

You can update the object's select statement by calling select() on it. You can then join() on additional tables and then fetchall(select) to get data from the joined table. However, as zend_db_table abstracts a single table, it wont allow you to.

You can get around this by doing a setIntegrityCheck(false) on the select, and this will allow you to join. However this means you'll only be able to read data through this object. Writing will be disabled.

Alternatively, you could use a zend_db_select object instead, which doesn't map to a particular table.

I've been stymied by this before, too. I don't think you can return a zend_db_table_rowset unless you write the implementation yourself. Try looking into the rowset abstract to see how the structure works. A zend_db_table_rowset is a collection of zend_db_table_row objects. What you're getting back from zend_db_adapter just isn't compatible*. What you might need to do is somehow convert your results into zend_db_table_rows and then add them to a new zend_db_table_rowset to gain access to all of the members of those classes.

* this describes what can be returned from Zend_Db_Adapter, and I don't see Zend_Db_Table/Rowset/Row as an option: http://framework.zend.com/manual/en/zend.db.adapter.html#zend.db.adapter.select.fetch-mode

  $table = new Zend_Db_Table('tableName');

    $myRowset = $table->fetchAll();

Lastly Zend_Db provices excellent way of joining table through Zend_Db_Select .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM