I’m not even sure how the phrase this question simply. Every search I’ve done (off and on for 6 months or more) regarding Model ‘persistence’ seems to leave me with the vague feeling that what I want is there, but I just can’t see it. (I’m an html/css guy - php is still new even after 4 years or so)
I have a big 'ol fat disgusting ugly controller, lol.
Though I have my business logic pretty much confined to my models, my controllers have grown, in one section in particular, because I can’t figure out how to keep my model active/alive/persisting between views and controllers.
I haven’t been overly worried about efficiency of the app, because it was limited to a few simple tasks. It started as a small tool for my use in my daily work, and as management caught on it expanded more and more. Started as completely procedural, and moved to ZF about a year and a half ago.
It is a job tracking app. that is intranet only. Address Book, and staff and ‘jobs’. In standard use it only deals with one ‘job’ at a time but they want to do a LOT more with it in the coming months.
I’ve just done some major overhauling on my model mappers to change the way they pull data as they want to see a page with all jobs. Since I model job processes, and not just simple data display, I can’t really reduce the amount of info that I pull on a job and have a useful Model/s.
I currently make use of ‘jobs’ array stored in zend session - and pull just the last save time-stamp of the main job table to compare against the stored version. This is reasonably acceptable for viewing a single job but I don’t think I want to rely on this method for what is coming.
I can likely do a lot more optimizing on my sql statements, but it seems odd to me that there isn’t a clear cut way of having ZF not try to pull all the data on every controller/action hit. I’ve read a small amount on view-helpers that seem like they might be the way to go. I’ve also seen reference to the View data being available to all controllers and Actions and being persistent, but haven’t seen a way to make it happen.
So, to try to sum it up. I’d like to instantiate my model/s and have them stay available to a number of actions, and preferably to a number of controllers as well. What is the best way to approach this?
So I don’t have to re-acquire all of the data on each hit. Really just because it was ‘a’ way that I could make work, using what I understood of ZF, to keep it active. Its a hack I use because I just haven’t been able to figure out the right way to do it.
I store them in an array there to use with different request params. My super bloated controller (bloat mainly in a single action) may want to display several different aspects of a job. And a user may need to access several jobs.
Even after almost two years of using the framework and at least having a rudimentary understanding of separation of concerns (from html/css background +reading) - I still don’t understand some, likely, very basic things.
To illustrate why this is - my learning process was like this:
Been doing html/css since 1998 - comfortable with the tech.
have played around with very simple php occasionally.
2006, Boss asks me to track x data - he’s using MS dbs - one for each job
Hey I bet I can do a quick MySql setup to store all jobs in one place.
Set up 3-4 simple forms and a db - my job is easier now.
Boss sees what I’ve done and wants more.
I Buy Kevin’s ‘Build Your Own Database Driven Website’.
Boss wants more and more. His boss wants more.
Way too many changes needed all over the procedural code.
Look into OOP - choose ZF - And do the best I can to make it work.
As I said in my previous post, I see hints at times but no real hard explanation. One thing that I read yesterday said something along the lines of: “Most people use a fresh View for each request” and “Data in the View is available to all actions and Controllers”… I must not be using the correct search terms, because when I try to dig deeper I get articles covering some vaguely connected aspects, but not what I want to know.
Re-reading my posts I see that I may not be clear on what I am currently doing to ‘solve’ the issue.
When I hit the controller for viewing a job, I instantiate the job Model and have it find and construct everything pertaining to the job. On pre-dispatch I save the job in session.
public function preDispatch()
{
parent::preDispatch();
$this->_session = new Zend_Session_Namespace('Jobs');
$request = $this->getRequest();
if ($request->getParam('job')) {
$jobId = $request->getParam('job');
if (!isset($this->_session->$jobId)) {
$this->_session->$jobId = $this->getModel()->find($jobId);
} else {
$jobTable = new Model_DbTable_Jobs();
$test_job = $jobTable->find($jobId)->current();
if ($test_job->last_edited > $this->_session->$jobId->last_edited->timeStamp) {
$this->_session->$jobId = $this->getModel()->find($jobId);
}
}
}
}
I know this is a bad way to do things (for a number of reasons). But it solved the issue, at the time, of reloading the model from scratch on each hit.
OK. That’s what I thought. Sessions are not good for caching, since they serialize and deserialize on each execution. Eg. between each page, php will internally transform the contents of session to a text format and write it down to disk. Then, on the next page load, it will read this file and re-create all the objects that were in session. This is relatively slow.
If you want to optimise your application, you should rather look at reducing the number of records that you pull out of the database.
Maybe i’m reading this wrong, but it sounds like you might be trying to optimise the app prematurely? Is there a big performance hit by creating a fresh copy of the job model for each request?
having links such as app/view/job/1 or app/summary/job/1 where 1 is the jobId seems a much more straightforward approach and allows things such as bookmarking a job, sending job links via email etc without worrying about the current job in the session. If you have other models relating to the job and you dont want to have keep calling the jobid then you may want to look into zend_db_table relationships
The very nature of http is stateless and trying to work against that with storing complex objects in sessions adds overhead without any major gains.
Romance, I think you kind of hit the nail on the head when you mentioned stateless.
As this is my only php project I think I have/had unrealistic expectations on what an object might be capable of. I’ve been under the impression that I ought to be able to reuse an object in different calls to the controller without instantiating it each time, and have had the nagging feeling for quite some time that I just didn’t ‘get it’ when I couldn’t make it work.
Since the landing page of a job is an overview I have the model in a state where all aspects of it are ready to be passed to the view as-is. I’ve been wanting to re-use the model in this state instead or writing methods to pull and view each separate aspect on its own. Sounds like I am going to have to rethink the whole process and separate the steps that get the model to that state and make them as independent as possible.
A quick think about how my models might have to change makes me think that I am/was still thinking procedurally in spite of my attempt to go OOP.
I think I may have to create a jobs_management model as a gatekeeper to separate job and jobs models and/or model each aspect of a job individually.
I do make use of Zend_DbTable relationships, and I think this is part of the difficulty in loading all current jobs at once as they are coded. In trying to separate my models from the data source I have models and model_mappers for pretty much every aspect of a job (like the guestbook in the zend quickstart), and load it all. It really doesn’t make sense in the long run to load all the data into the model when I don’t need it in a particular view.
To clarify: I think I understand now that at the end of script execution all objects are destroyed. As far as php goes; when the page is being displayed my object/model no longer exists, correct?
Yep, even things like sessions are essentially written to disk and re-read on the next request as kyberfabrikken mentioned.
Don’t take this the wrong way but I think you may of taken on a bit too much with trying to implement data mappers etc in your very first php project, let alone taking on ZF.
Although they do have advantages, you only really see these gains once you’ve got a few projects under your belt and see how this approach could help you, rather than trying to implement them into your design because a tutorial says so (personally I think the ZF quickstart is pretty bad for this).
Feel free to PM me if you want someone to look over your code base and give you some pointers (and dont want to share your code on a public forum)
Thanks romance.
No offense taken at all. I agree with you that I likely approached this whole process the wrong way.
My choice of ZF was mainly made after jumping in to Harry Fuecks’ “PHP Anthology”, and starting to rewrite my procedurally coded project (for the 4-5th time) in OPP. I think OOP was the right decision when we realized that this would be a continuing process of extending the project to handle more aspects of a job.
I would have acquired a better foundation by continuing with this prior to jumping into a framework (or by taking some classes :)), but both my boss and I were anxious for results at the time. I am where I am now and there’s no changing it.
The main problem in learning the way I have is that I don’t know what I don’t know, if you know what I mean. The lessons from trial and error, however, are quite valuable, and I’m in a position where it is understood that this is a learning process for me. Changes/re-writes aren’t a problem and are even expected as we continue to modify what the application covers.