Resultset total count - simple question

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Resultset total count - simple question

Post by alex.barylski »

As the title suggest, this is a simple question: When you implement a model method that queries a large dataset and returns paginated results, how do you return the number of total records, in order to calculate things like, the total number of pages, etc?

Do you:

1. Implement each model to have a getTotalCount() method to complement selectAllRecords() type methods
2. Do you have your selectAllRecords() return an array, with the first element being the count and the second being the records
3. Do you return a resultset object which has mehtods, such as getResults() and/or getCount()

Each has it's pros and cons, I've tried all three in my current setup, each with caveats, so I am just curious, which do you prefer?

Cheers,
Alex
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Resultset total count - simple question

Post by Weirdan »

Another option: return object implementing Countable and Traversable. Then use it like this:

Code: Select all

Page <?=e($_GET['page'])?> of <?=ceil(count($result) / min(intval($_GET['perpage']), 1))?>
<ul>
<? foreach ($result as $row) : ?>
    <li><?=e($row['item'])?></li>
<? endforeach; ?>
</ul>
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Resultset total count - simple question

Post by alex.barylski »

I would personally put that in the same category as a resultset object, although I'm not sure what the Countable would do? I am not interested in counting the number of records to render, but rather the number of total records outside of the paginated result.

The problem I have with returning a resultset object (which is so nice as it allowed me to abstract querying the database inside the model, but return an associative array, or in the rare case a buffered query if the resultset was massive huge), is that now the controller layer is slightly coupled with the DAL, and abstracting the resultset object in the model layer, didn't make sense for me.

Because the resultset object is part of the DAL/DB abstraction layer, if the model were to ever use a third party service, like a CSV file or web service, the resultset object wouldn't be available adn thus force me to refactor the code if I were to ever switch.

Duplicating the resultset object in the model layer just felt, convoluted?!?

All of this is highly subjective and heavily dependent on how you architect your applications, where you need flex points, the amount of abstraction you prefer, etc. I am just curious o hear others views as to how they address the issue.

Cheers,
Alex
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Resultset total count - simple question

Post by VladSun »

The 3th one
There are 10 types of people in this world, those who understand binary and those who don't
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Resultset total count - simple question

Post by alex.barylski »

It's the one I prefer as well, but cannot get over the added coupling between the DAL and controller. :)
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Resultset total count - simple question

Post by VladSun »

I use a Decorator pattern to change the Model query (i.e. to append LIMIT OFFSET) and add an additional query to retrieve the total number of records.

Code: Select all

class User extends Collection_Controller
{
	function __construct()
	{
		parent::__construct();

		$this->setModel(new Pagination(new User_Collection_Model()));
	}
}
Also, I don't pass the Model itself to the View - I use a Response object to collect result data, error/warning messages, etc.
The Response object is passed to the View. Maybe it's not a good practice but it works for me :)
Last edited by VladSun on Thu Jul 10, 2014 3:37 am, edited 1 time in total.
There are 10 types of people in this world, those who understand binary and those who don't
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Resultset total count - simple question

Post by alex.barylski »

Also, I don't pass the Model itself to the View - I use a Response object to collect result data, error/warning messages, etc.
The Response object is passed to the View. Maybe it's not a good practice but it works for me
Seems a little backwards to me, but that doesn't make it wrong I don't think, just different. Personally the response is the last component in the execution pipeline, so the view is rendered and the result assigned to a response->setContent() at which point the framework takes care of sending to stdout.

My only concern with the response being passed to the view, is the coupling of layers (which may or may not be a concern). If the views have a dependency on a response object, could you reuse that view in an environment without a response object?

For example, a cronjob, might use a view to load a template to render an HTML email, in this case the response object, is not an HTTP response, but rather a mailing object, such as SwiftMailer. For that reason, I would personally keep the two decoupled and simply pass the results of the rendered view to whatever object I desire, whether that be a HTTP response object, SMTP object or possibly a File if you were caching, etc.

Of course, this is with a severely limited understanding of your architecture, etc.

Cheers,
Alex
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Resultset total count - simple question

Post by VladSun »

My Response object is a composite object containing Error object, Warning pbject, Result object, etc.

It's not HTML or something like that.

My "views" by default are simple json_encode(Response) - just ExtJS AJAX formated messages :)

So there is no coupling with the Model I think. The response object is just a layer between the Model and the View.
There are 10 types of people in this world, those who understand binary and those who don't
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Resultset total count - simple question

Post by josh »

I have a special model for this, the "finder". So if I have a Widget model, I should have a Widget_Finder

->findAll(1,100) // would give rows 1-100
->findAll() // loads all the rows
->findOne(1) // finds row with primary key = 1
etc...

These methods generally follow the data mapper pattern.
PCSpectra wrote: Personally the response is the last component in the execution pipeline,
For a given sub system, yes. Lots of components have Request/Response objects. Never heard of it for pushing data to the view, but hey.. whatever works. Would be better to term it as a "result" and not a "response" for the reasons you point out. Although a soap server, for example, has a response, you're probably right that it implies an actual response, as opposed to just a "result".
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Resultset total count - simple question

Post by alex.barylski »

truth be told, my framework implements a very basic response object and later inherits from it with an HTTP reponse object, which essentially wraps the HTTP response. It adds methods for things such as redirection, which wouldn't be required when sending emails via cronjob. That being said, I use the same framework VladSun does and everything must be output in JSON format, and the view/rendering is effectively handled client-side. The response object passed to the front controller by the framework is still the generic HTTP one, although one more layer of abstraciton could be added so as to eliminate having to constantly set custom headers in every action.

I supposed one way around introducing yet another reponse object simply for the purpose of eliminating setting headers other than "text/html" would be to have a view object set the reponse for you, and in the process convert a native PHP array into a JSON array. The view in this case is really simple and so the coupling of response and view isn't all that serious, as I would normally consider it anyways. :)

Cheers,
Alex
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Resultset total count - simple question

Post by VladSun »

My Controller hierarchy starts (excluding the base Controller class itself) with a ViewContext_Controller class, which depending on the URL requested (i.e. http://example.com/user/get.html or http://example.com/user/get.json) loads a different View (if it's defined) for it. All Views know about the Response object API and can handle it.

PS: I think that the View is always coupled to the Model - it's a pure example of the Observer pattern. Adding an intermediate layer (the Response object) may introduce some decoupling, but it's still not enough.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Resultset total count - simple question

Post by VladSun »

josh wrote:Would be better to term it as a "result" and not a "response" for the reasons you point out.
I have to agree :)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Resultset total count - simple question

Post by VladSun »

VladSun wrote:So there is no coupling with the Model I think. The response object is just a layer between the Model and
the View.
VladSun wrote:I think that the View is always coupled to the Model - it's a pure example of the Observer pattern. Adding
an intermediate layer (the Response object) may introduce some decoupling, but it's still not enough.
Blah .... :drunk:
There are 10 types of people in this world, those who understand binary and those who don't
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Resultset total count - simple question

Post by alex.barylski »

Hahaha :drunk: indeed :p

Cheers,
Alex
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Resultset total count - simple question

Post by josh »

Yeah almost any literature I've read about MVC, the view observes the model. That way when the model decides to update itself (maybe in a multi-threaded environment, some other process has a reference to our model and updates it) - the view should update too. This is unnecessary in web but I still think the dependencies should be the same.

What framework do you guys use? Also just a friendly request, please try to post less "fluff". ("I agree"), on some forums they have rules against that. It makes the thread impossible to read when you quote a paragraph of text just to add, "indeed", and nothing more.
Post Reply