2009-08-28 PHP Benelux BBQ: Advanced Usage Of Zend Paginator

Uploaded on


More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • Hi, that's good, very good
    Are you sure you want to
    Your message goes here
No Downloads


Total Views
On Slideshare
From Embeds
Number of Embeds



Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

    No notes for slide


  • 1. Advanced Usage of Zend_Paginator The Dutch PHP BBQ 2009 Jurriën Stutterheim
  • 2. About Me • ZF user since ZF 0.2 • ZF contributor since 2007 • Author and co-author of Zend_Paginator and Zend_Feed_Reader
  • 3. This Presentation • Short Introduction to Zend_Paginator • Zend_Paginator & Relational Databases • Zend_Paginator & Domain Models • Alternative use-cases
  • 4. Short Introduction “Zend_Paginator is a flexible component for paginating collections of data and presenting that data to users.” - Zend Framework Reference Guide
  • 5. Primary Design Goals • Paginate arbitrary data, not just relational databases • Fetch only the results that need to be displayed • Do not force users to adhere to only one way of displaying data or rendering pagination controls • Loosely couple Zend_Paginator to other Zend Framework components so that users who wish to use it independently of Zend_View, Zend_Db, etc. can do so - Zend Framework Reference Guide
  • 6. Simple Example // Create a Paginator that will paginate an // array with the values 1 to 100 $paginator = new Zend_Paginator( new Zend_Paginator_Adapter_Array(range(1, 100)) ); $paginator->setItemCountPerPage(10); $paginator->setCurrentPageNumber(3); // Echoes numbers 21 to 30 foreach ($paginator as $item) { echo $item; } // This assumes the view helper has been setup echo $paginator
  • 7. Available Adapters Out of the box Zend_Paginator supports: • arrays • Iterators • Zend_Db_Select • Zend_Db_Table_Select
  • 8. Paginator & Database • The total number of items is needed to calculate the number of pages • A count-query is executed to determine the total number of items the original query would retrieve • Paginator only fetches the rows for the current page
  • 9. The Count Query The COUNT query for SELECT * FROM huge_table is SELECT COUNT(1) AS zend_paginator_row_count FROM huge_table In order to fetch the rows for the current page: SELECT * FROM huge_table LIMIT 20, 10
  • 10. Complex Queries In case of more complex queries, subqueries are used instead. Original query: SELECT *, MAX(rating) AS highest_rating FROM publications WHERE publication_year > 2006 GROUP BY category, publication_year, author HAVING highest_rating > 3 Count query: SELECT COUNT(1) AS zend_paginator_row_count FROM ( SELECT *, MAX(rating) AS highest_rating FROM publications WHERE publication_year > 2006 GROUP BY category, publication_year, author HAVING highest_rating > 3 )
  • 11. Custom Queries It’s also possible to use a custom COUNT query: // $select contains the query from the last example $adapter = new Zend_Paginator_Adapter_DbTableSelect($select); $adapter->setRowCount( $db->select()->from('publication_counts', array( Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN => 'highest_rating_count' )) ); $paginator = new Zend_Paginator($adapter);
  • 12. Fixed Page Count You can specify a fixed page count. No COUNT query is executed in this case: // This table has tens of thousands of records $table = new Zend_Db_Table('publications'); $select = $table->select()->order('rating DESC'); $adapter = new Zend_Paginator_Adapter_DbTableSelect($select); $adapter->setRowCount(500); $paginator = new Zend_Paginator($adapter);
  • 13. Paginator & Domain Models • When using a domain model you don’t want to pass database rows to your view, but rather use them to construct domain objects. • You do however wish to keep the Paginator features at your disposal. • Zend_Paginator supports this using filters.
  • 14. Filters • Filter the result from the adapter • Need to implement Zend_Filter_Interface • Can be chained if required • Zend_Filter_Callback allows you to easily reuse existing models to construct domain objects
  • 15. Example class MyObject { // Snip... public static function factory($rows) { $objects = array(); foreach ($rows as $row) { $objects[] = new MyObject($row); } return $objects; } public function getFoo() { return 'foo'; } } // $select is a Zend_Db_Table_Select object $paginator = new Zend_Paginator( new Zend_Paginator_Adapter_DbTableSelect($select) ); $paginator->setFilter(new Zend_Filter_Callback( array('MyObject', 'factory')) ); foreach ($paginator as $item) { echo $item->getFoo(); // echoes foo }
  • 16. Alternative Use-cases • Batch Processing • Zend_Entity
  • 17. Batch Processing • For example, rebuilding a Zend_Search_Lucene search index using a large amount data from a database • Each page contains a relatively large number of items • Main advantage is limited memory usage because not all rows are loaded into memory at once
  • 18. Batch Example public function rebuild() { $paginator = new Zend_Paginator( new Zend_Paginator_Adapter_DbTableSelect($this->getSelect()) ); $paginator->setCacheEnabled(false); // Batch size is 500 records per page/batch $paginator->setItemCountPerPage(500); $searchIndex = $this->getSearchIndex(); for ($i = 1; $i <= $paginator->count(); $i++) { $items = $paginator->getItemsByPage($i); foreach ($items as $item) { $searchIndex->addPublication($item); } } }
  • 19. Zend_Entity • Is a data mapper implementation for ZF • Currently under heavy development • Uses Zend_Paginator_AdapterAggregate • Is used to load subsets of data from the datasource to improve performance and memory consumption
  • 20. Finished! foreach ($questions as $question) { $question->answer(); } $this->bbq(); // o/