Get (Alternatives)
Datamapper ORM includes a number of alternatives to the normal get methods. These can be used to perform more advanced operations based on which one is used.
Also see the Simple Cache Extension for another get variation.
Subsections:
- get_iterated - Streams query results
- When To Use Get Iterated - When get_iterated should be used over get.
- get_paged - Paginated Queries
- get_paged_iterated - Paginated and Streamed Queries
- get_raw - Gets the Raw CodeIgniter result
- get_sql - Gets the raw SQL for the query
$object->get_iterated()
This method can be used to reduce memory overhead and even increase performance if you know you only want to loop over the result set. In fact, it is recommended in almost all cases where you expect more than one result, and don't need direct access to one or more results.
The get_iterated method works by creating a PHP Iterator. The iterator creates each object as it is needed; there is actually only one object that is shared as you loop over the set.
Special thanks to TheJim for coming up with the prototype for this method.
Arguments
- $limit: (Optional) Sets the limit on the query.
- $offset: (Optional) Sets the offset on the query.
Note: The results of this method do not directly modify $object.
Therefore, the database fields are not set on $object, and the $all array will be empty.
However, you can still check the results of the query using exists() and result_count().
Common Usage
$countries = new Country(); $countries->get_iterated(); if(!$countries->exists()) { echo('No countries found'); } else { echo($countries->result_count() . ' countries were found.'); foreach($countries as $country) { // process like normal } }
When To Use Get Iterated (Over Get)
There are several cases where you should always use get, and several cases where get_iterated is preferred.
-
If you are looking up just one object, or expect there to be one or zero results, you always use get.
Otherwise you cannot access the properties directly. -
If you are planning to loop over a relatively small set of objects more than once, you should use get.
Otherwise, you are re-creating each object every time you loop. -
If you are looping over a very large set of objects, you should use get_iterated.
In this case you should also avoid looping over the large set more than once. -
If you need direct access to specific objects in the result set, you should use get.
For example, you need to specifically modify the third item in the results. -
If you are getting a list of objects to delete or save, you must use get.
Then you pass the result as $other_object->all to the appropriate function. (DataMapper must see the array to know to save multiple objects.) - Otherwise, as long as you are using foreach to loop over the results, you should always use get_iterated
$object->get_paged()
Example Application
You can see this feature used in:
» controllers/bugs.php
» views/bugs/paging.php
This method is used to easily get a query that is broken up into pages, as well as handle getting the total number of rows.
You can use this method with any query parameters, and those parameters will automatically be used to determine the total number of rows.
Note: Each call to this method will result in two queries: one for the data set, and one to count the total number of rows.
Arguments
- $page: (Optional) Which page to start on (or which row based on $page_num_by_rows). Defaults to 1.
- $page_size: (Optional) Sets the number of rows on each page. Defaults to 50.
- $page_num_by_rows: (Optional) If TRUE, changes the $page argument to be zero-based, and be based on the row to start on. See below for more information
- $info_object: (Optional) Override the name for the pagination info object. Defaults to 'paged'.
When requesting a page number by row, get_paged converts the row number to the correct page for that row. For example, if you had 10 rows per page, and requested row number 12, the page will be 2, and the starting row will be 10.
This method will automatically prevent the request of a page that is outside the queries' boundaries. If the requested page is less than 1, it reverts to the first page. If the requested page is greater than the total number of pages, it reverts to the last page.
What makes this method so useful, however, is what else it returns. Each call sets the following properties on an object, which is called $paged by default.
If you already have a field called paged, you can easily change the object to a different name with the last argument.
- total_rows: The total number of rows in the unpaged query.
- total_pages: The total number of pages, based on $page_size.
- current_page: The current page (usually passed in).
- current_row: The first row on the current page.
- last_row: The first row on the last page.
- has_previous: If TRUE, there are previous pages in the query.
- previous_page: The previous page or 1, whichever is greater.
- previous_row: The previous page's first row or 0, whichever is greater.
- has_next: If TRUE, there are more pages in the query.
- next_page: The next page or total_pages, whichever is less.
- next_row: The next page's first row or last_row, whichever is less.
- page_size: Number of items per page, might be useful for the view.
- items_on_page: Number of items on the current page, i.e., $object->result_count().
Example
// IN THE CONTROLLER function archive($page = 1) { $posts = new Post(); // show newest first $posts->order_by('created', 'DESC'); // show 10 posts per page $posts->get_paged($page, 10); // send to view $this->load->view('posts/archive', array('posts' => $posts)); } // IN THE VIEW foreach($posts as $post) { // render the post } if($posts->paged->has_previous) { ?> <a href="<?= site_url('posts/archive/1' ?>"><< First</a> <a href="<?= site_url('posts/archive/'.$posts->paged->previous_page) ?>">< Prev</a> <? } if($posts->paged->has_next) { ?> <a href="<?= site_url('posts/archive/'.$posts->paged->next_page ?>">Next ></a> <a href="<?= site_url('posts/archive/'.$posts->paged->total_pages) ?>">Last > ></a> <? }
$object->get_paged_iterated()
A simple combination of get_paged and get_iterated, allowing you to efficiently loop over the results of a paged query.
Use the exact same as get_paged, except the results can only be looped over. Strongly recommended in most cases.
$object->get_raw()
This method runs the query, but returns the raw results from CodeIgniter's database library. It also clears the current query immediately.
Arguments
- $limit: (Optional) Sets the limit on the query.
- $offset: (Optional) Sets the offset on the query.
$foo = new Foo(); $foo->include_related('bar', 'name'); $foo->where_related('bar', 'name', 'baz'); $query = $foo->get_raw(); foreach($query->result() as $row) { echo $row->bar_name; }
$object->get_sql()
This method returns the SQL for the currently built query, as if get() was called. It clears the current query immediately.
Arguments
- $limit: (Optional) Sets the limit on the query.
- $offset: (Optional) Sets the offset on the query.
- $handle_related: (Optional) If TRUE, and this object is referenced from a parent object, the parent object will automatically to the where statement.
$u = new User(); $u->where('name', 'Bob'); echo $u->get_sql(); // outputs the raw SQL
Example with relationship
$group = new Group(1); // load Group #1 echo $group->user->get_sql(); // SELECT `users`.* // FROM `users` echo $group->user->get_sql(NULL, NULL, TRUE); // SELECT `users`.* // FROM `users` // LEFT OUTER JOIN `groups` groups ON `users`.`group_id` = `groups.id` // WHERE `groups`.`id` = 1