I've build my own MVC framework, but I'm still getting my head around a few things.
I have a class to handle session methods such as refreshing sessions, verifying sessions, starting sessions, closing sessions.
My question is where should I declare it in my MVC architecture?
I have an abstract base class, which is extended by the controller.
This base class then declares the model and view.
Should it go in the base class? If so how can I refer to session object methods from the model? Or should I aim to only trigger it from the controller?
I'm new to Object Orientated php as well which makes this more hard. My mind is boggling!!
The request objects are best thought of, or at least written as, being part of the model layer, but because you're writing for the web, Request objects are part of the core of your Framework.
But to clarify:
Effectively, a Session class is a data model, and one could argue that it's part of a bigger subset of request models. Remember, MVC doesn't imply that each request requires a Controller, View and "A Model".
The Model bit, especially, is a layer. It can contain services, data models, an ORM, helpers and what have you...
That said, All things deal with the request should be at the ready in the controller. That's how most FW's work. Check the symfony workflow of a request, and note how far apart the controller and the request are.
This graph, though it deals with the ZendFW cycle, shows the special status of the request object(s) even more clearly:
The server receives the request, the framework kicks in and pours the request into the corresponding objects.
Then, in the code that resolves the request to a given controller, and controller action, I'd pass the required request objects to the controller's constructor.
A basic schematic would be:
Request ===> index.php (startup script)
||
|| some basic checks, create objects
||
|_==> create base controller
||
||
|_==> pass request to constructor, or starter method
Do more specific/targetted checks
||
||
\/
controller has access to request through base controller
and can pass this through to the model layer
So, in resuming, and because I believe repetition works: The request objects are best thought of, or at least written as, being part of the model layer, but because you're writing for the web, Request objects are part of the core of your Framework.
The best way to think of problems involving OO is to consider the following simple questions:
Is your object a representation of something?
Is it actually going to modify other representations?
Is it purely there for display?
Answering "yes" to 1 and "no" to 2 usually (99% of the time) points to the role of a model. "no" to 1 and "yes" to 2 identifies a controller, while "no" to 1, 2, and "yes" to 3 implies a view.
Answering the following highlights inconsistencies or lack of separation:
Yes - yes - no - your model is not clearly separated
Yes - yes - yes - you effectively have an object trying to do everything
Yes - no - yes - your view and models are not separated
In your case, a session is a representation of a state that is held for a client. It therefore can only modify itself, and does not act on anything else. It is a model and is best represented as one.
You should ideally create a session storage controller/object/helper (depending on framework) to insert, recover and update session models, by the way. This is akin to a data provider.
The controller should handle this.
When you will need to set variables, refresh thing inthe session, the controller will do it from the results of your backend functions. That way you do not have to import this session class in every service, backend or utils class and it will always be done in the same way at the same level of coding.
Related
I come from a Java/Grails background and cannot seem to find a definite answer online as to where the service logic for a CakePHP application should be stored. By "Services", I am talking about classes that are usually instantiated through dependency injection to conduct business logic on domain objects. They should be able to query any domain object and make changes in response to a controller action.
Currently, CakePHP's "Component" class seems to be the closest match to this behavior. I can load a component into any controller and execute its methods as needed. However, I have read in several places that components should never access the database and that doing so will result in some steep performance hits.
I have also looked into CakePHP's "Behavior" class and it doesn't seem to fit the ticket at all. It seems well-equipped to organize domain objects into a data structure setting, but that's not the kind of logic that a service would execute. Also, to import any model definition into a Behavior, I would have to edit the model definition itself to allow access, which is very awkward.
So I ask this question: Where should service logic be stored? Certainly not the controller, as it should only contain the minimal logic to process a request and send a response.
Components are the service layer in CakePHP. They are constructed by a dependency injection container (Components Collection) and get passed the controller, request and response that is to be handled.
There are no restrictions in what Components can do other than maintaining separation between layers. It is fine to use database connections, or use models, directly from a component and modify the request.
Components are actually very light-weighted if you only make them act for specific cases. Inspecting the action name, is a common way of limiting the reach of a component. You can also inject setting so it can know when is OK to execute custom service logic.
So I ask this question: Where should service logic be stored?
Certainly not the controller, as it should only contain the minimal
logic to process a request and send a response.
Sounds like the ideal use case for a Dispatcher Filter. It gets called even before a controller is instantiated. If you need to query the database simply load a model via ClassRegistry::init('YourModelName') and pass the request params to the model method and return whatever you need in your request. No controller needed at all. We've implemented oauth + xhttp using Dispatcher Filters without calling ever a controller.
How using a model inside a component should effect the performance... I don't know who got that strange idea, sounds like not the best article you found. It is true that you should not put model layer related logic in them but you can call a model for example through the controller instance and the controllers models.
I have the common MVC situation in my PHP system: the Controller receive a request from the View containing $_POST data. Now I have three ways to handle the data:
a) The Controller only calls the Model and the Model handle the $_POST data.
b) The Controller transforms the $_POST data into variables and pass them to Model.
c) The Controller transforms $_POST data into a Model's domain object and only pass the object to Model.
Currently, I am following option A, but I believe it is wrong, so I am thinking of using option C.
So, according to MVC, what is the right way to handle $_POST data?
EDIT At the moment, I'm not using any MVC framework.
EDIT 2 Generally, the same Controller handles request from a browser, a web service, an offline application, etc, or each one has it own Controller?
The best option is to use #2 approach, with some alterations.
I would write it as something like this:
public function postLogin( $request )
{
$service = $this->serviceFactory->build('Recognition');
$service->authenticate( $request->getParam('username'),
$request->getParam('password') );
}
// Yes, that's the whole method
There is no need to actually create variables, if you have used something like a Request instance to abstract the user's input.
Also, you might want to replace theRequest::getParam()method with something likeRequest::getPost()- although I have come to the conclusion that, in a correctly structured application, theGETandPOSTparameters should not share same name.
The serviceFactory which you see in the code snippet would be an object that you inject in both controller and view instance. It would let you share same service instances between controllers and views.
It is responsible for creation of services (which would contain the application logic, while leaving the domain business logic in the domain objects), which helps you isolate the interaction between domain entities and storage abstractions from the presentation layer.
About the other options:
The Controller only calls the Model and the Model handle the $_POST data.
In the MVC and MVC-inspired design patterns the model should be aware of neither the user interface nor of the presentation layer as whole. The $_POST variable in PHP is a superglobal.
If you use it with model layer, your code becomes bound to the web interface and even the specific request method.
The Controller transforms $_POST data into a Model's object and only pass the object to Model
Not entirely sure what you meant with this. Seems you were talking about instantiation of an abstraction, which would contain the user's request. But in this case controller becomes responsible for instantiation/creation of said structure, which would violate SRP.
Closing notes:
One thing you must understand is that, in context of web based MVC applications, the User of your application is the browser. Not you. Browser sends the request, which is handled by routing mechanism and disseminated by controller. And view produces the response to your browser.
And the other thing is: Model is neither a class nor an object. Model is a layer.
Update
Generally, the same Controller handles request from a browser, a web service, an offline application, etc, or each one has it own Controller?
You should be able to have single controller, that deals with all the forms of application. But that is only on the condition, you are actually using same application for all 3 use-cases.
To do so there are two conditions:
you need to abstract the Request instance, that controller receives
the view should be instantiated outside the controller
This way you can have one application to fulfill all the requirements. Only thing, that each variant has different, is the bootstrap stage, where you create the Request instance and select the proper view.
In the situation, that you described, the changing part would actually be the view, since a REST or SOAP service would be expected to produce a different response than an ordinary web application.
Once upon a time was the three tiered application architecture.
It all depends on your MVC framework. Normally, the Controller does the link between the user and the model layer, which manipulate domain objects.
In the early days of MVC in PHP, the model layer was actually just the domain objects, called models for that purpose.
Some prefered having so called thin models, which only provide an OO representation of the data, (which simplifies persistence). In that case, the controller would regroup the so called actions, containing the bulk of the processing associated with an HTTP request (fat controller).
Others embedded most of said processing in the object model with dedicated methods (fat model).
However, at some point, you have to analyse the content of the query to sanitize and validate it, and this depends on how your view will format the request. Sanitization might be a controller task (this request should only contain these values), while validation is definitely a model task (values should be of these types).
An interesting question is: how do you deal with actions impacting several domain objects? Where do you put the logic for that?
Nowadays, the model layer is composed of services segregating the domain objects from the evil grasp of the controllers, to limit the dependencies between the layers to their respective interfaces only. This is where most of the request processing is done.
Symfony2, for instance, provides a sensible answer to this question: each step of the processing of a request is implemented in a dedicated piece of code, which could be described as the following:
the request is first turned into an object
that object is routed using a routing object
it is handled to a controller
the controller pass the request to the service concerned by the action, which build the response object
The service job is then broken in several steps:
validation (using a dedicated object which rely on rules described in a separate file),
construction/updating of domain objects (using serialization to/from db if necessary),
selection of a template for the response,
population of said template with the relevant data from the domains.
CakePHP is another popular framework which follows similar concepts: simple controllers, and services encapsulating domain objects.
See this question for a better insight on the general concepts.
See this other question for other answers.
Thanks to tereško for his invaluable input on the matter.
i am using Zend and following
the 2nd option .
Example a Registration form
step- 1 the forms sends me the post value to the specified controller
step -2 i will validate the form values for example ( mail and url and empty post values ) through server side validation .
step -3 send the checked post data either in variable or has whole to the model .
step 4- controller calls the model .
step -5 the models inserts the post values and creates a new user .
I think your second option is better regardless of framework or approah you use .
note - same controller can handle everthing depends on your application logic .
but i prefer to keep different controller for differnt user request and user types
it helps in keeping code readable managebale .
Look at some MVC frameworks.
For example, in Yii you can write such code inside action:
$model = new Model();
if(isset($_POST['Model'])) {
$model->attributes = $_POST['Model'];
}
Note, that all attributes of your model must be passed through validation rules. In Yii validation applies during (actually, before) $model->save()
See:
http://www.yiiframework.com/doc/guide/1.1/en/form.model#securing-attribute-assignments
http://www.yiiframework.com/doc/guide/1.1/en/basics.mvc
'C' is best option. You should not let raw $POST data go in model as model is supposed to be generic handling store and load operations mainly.
Example : same model can be used web interface and Web services. On Web $_POST is valid but for web services its not. So model doesnt care how data is received but only how to store and load it.
Yii is definitely a clean implementation of MVC.
So I've been studying the role of the repository pattern as a means of decoupling the persistence layer from my models in an MVC framework. Prior to this, I might have my UserModel calling active record methods directly in order to store/retrieve domain objects.
Here's a sketch of what I'm thinking in regards to the call stack in a request that should create a new User:
Here are my questions:
Is this a correct implementation of the repository pattern?
I understand that the controller should take the user's information from the request and pass it into the model. How does that usually happen? Should the controller create a User object and then pass that into the model? I sure as heck don't wanna just pass in an array of values into the model--nor do I want to pass in 15 arguments to the model method that creates a user.
In order for this pattern to really work, it looks like to me I would need to have a domain object that is just a simple data structure with no behavior and then if I'm using an ORM, I would have an ORM object which will describe how the object is persisted. Initially I resisted this because it feels like duplicate code, but if I'm really separating persistence from the business logic, this would be needed right? For example, what if I went with an in-memory store? I would no longer use the ORM object.
Am I thinking correctly here? Is this acceptable. Please help me connect the dots in my head.
1. Is this a correct implementation of the repository pattern?
I'm not sure where you been doing that research, but you have got it wrong.
Repositories as for separating the domain objects from data mappers.
There no such thing as "models". Model in MVC design pattern is one of the to main layers: presentation layer and model layer.
And the repository pattern is incompatible with active record (anti)pattern, which combines domain and storage logic in single instance, thus causing a major SRP violation.
To use a real world example for, when and how to use a repository here is an example:
You are creating some document management tool, where said documents can come from several sources (for example: local SQL database, SOAP service and cache). In this situation you create a repository, which deals with the "routing" of storage. It is the part of application, that decides which data mapper to use for storing/retrieving each document.
The goal of repository is to separate the domain logic from the interaction with storage. For the system, that was described above, a repository would also let add new data sources, without need to rewrite large amounts of code (if any). You could just add another type of mapper for the document.
2. Should the controller create a User object and then pass that into the model?
To begin with, controller itself should not create anything. Instead your controller should use a factory for acquiring instance of the object that you need. This factory can be provided to the controller through constructor or some other method. This is called: Dependency Injection (to learn more about it, watch this lecture).
Also, as noted above, model is a layer, not any specific class or object. The responsibility of controller is to alter the state of model layer (by passing data to it). You could interact with domain objects and mappers (or repositories) directly in the controller, but it would mean leaking some of the business logic in the controller. It is recommended to instead use services, which then manipulates said domain objects and storage related structures.
As for the issue with 10+ parameter, that you would require for creation of new user account, let's assume you have action with following footprint:
public function postUser( Request $request )
{
....
}
If the action gets called with specific Request instance, you have two options how to deal with large amount of parameters:
Wrap the instance in a decorator, which would let you call a single method for forming the data from request in a specific array. Then you pass this array to the service(s).
Form the array inside the controller's action and pass it, where th data is required.
The former solution is more suited for large scale applications, where such formation of data would be required repeatedly though-out the code. But in a small/medium projects the second option is the common-sense approach.
Thing is, the job of the controller is to take the user's input, and distribute it to the model layer and current view. And formation of such array fits right-in with this mandate.
3. (..) main object that is just a simple data structure with no behavior and then (..)
No. Domain object is not "simple data". It is where most of the domain business logic resides in the application.
And forget about magical ORMs. First step for implementing a repository is to separate the domain and storage logic. Domain object handles the validation and business rules, mapper deals with persistence and data integrity (small example here).
Another thing that you must realize is that repositories for web application do not really interact with in-memory persistence (apart from cache). Instead your repository would be juggling mappers for different data sources.
Should the controller create a User object and then pass that into the model?
I'm not sure what you mean by "pass that into the model" -- the User object is the model. "Controller" and "model" represent different layers in the design, they are not specific objects, and there shouldn't be a separate UserModel object as you mentioned.
The repository interface itself is generally considered part of the model, though the domain objects shouldn't be saving themselves -- this should be done in the controller.
Your controller's job would then be to interpret the request and create a User object, then use the repository to save the user:
$user = new User(...); // based on Request
$repository->save($user);
it looks like to me I would need to have a domain object that is just a simple data structure with no behavior
This is not true, you can and should encapsulate behaviour in your domain objects. As for how persistence is actually implemented, a good ORM should take care of most of the details and you shouldn't have to create additional classes by hand.
I develop most of my web applications using CodeIgniter, and have always took the approach of validating form data inside the controller, using the built in Form Validation class, before sending this data to the Model to be used, e.g insert the data into the database.
However, I keep hearing the "skinny controllers, fat models" line - and I'm wondering if these validation checks should be placed inside the model.
Three things strike me when I think of using this approach.
How can different error messages be shown to the user, without returning seemingly ugly arrays or objects from these model functions? e.g A duplicate email on signing up for an account. Would the method responsible for adding a user in the model have to return an array or object to indicate if the insert was successful, and any error messages?
By doing the validation checks in the model, checking variables supplied to the methods from the controller (not POST data), I will lose the use of the Form Validation class, a class that I find very useful in my projects. Would you suggest that I write a class, or library that can be used like a CI library to mimic the Form Validation class, but for supplied variables, and not limited to the POST data?
Following on from that concern...as the POST data would have to be validated for existence (isset($_POST['myvar'])) before being passed to the model, should the rest of the validation not just be placed in the controller as well?
Any suggestions, advice, opinions will be appreciated!
Your original issue comes from fact that CodeIgniter's interpretation of MVC is quite appalling. This framework pretends that View is just a template, and Model is just an ORM ( which some say, should be classified as anti-pattern ). Which is completely wrong, and forces bot business and presentation logic inside the Controller.
But lets leave View aside.
Model in MVC is not a class or an object. Model is a layer, which contains all the business logic. It is actually comprised of instances from multitude of classes. The two most prevalent groups are Domain Objects [1] [2] (this is, what people people usually call "models") and object responsible for information storage and retrieval - usually DataMappers. The model layer also contains standalone components (both your own and 3rd party) and higher level abstractions - services.
What you have as Validation class, might be considered to be a standalone component, which can either be used by Domain object to perform validation, or expect a Domain object to be passed in for validation .. depends on your implementation.
In your situation i would handle this at the service layer. Which would either provide the instance of View class with a valid domain object, or an object, which represents the error.
Some reading materials yu might be interest in:
GUI Architectures
AnemicDomainModel
Tell, Don't ask
Then again .. what the hell i know of it all ..
I recently read this post which led to a series of other posts that all seem to suggest the same idea: Models do everything, the View should be able to communicate directly with the model and vice versa all while the Controller stays out of the way. However, all of the examples shown are fairly simplistic and none really show an example of how anyone has tried to implement full handling of of a request / response cycle, which got me to wondering "should the model be responsible for handling the request (ie $_GET, $_POST, etc) itself?" and "should the controller only operate as a pass-through to instantiate the necessary model(s) and pass the model(s) to the view?". (In fact I found one example taken the extreme of embedding a Zend_Form object in the model)
From my reading of what Fowler says about MVC and just controller's in general it seems at first glance that the thinner the controller layer the better. But then I took the time to back through and study what he says about both MVC and Front Controller (which just muddies the waters because both patterns define controllers) and now my instincts suggest that Zend_Framework in implementing both of these patterns, has actually created a composite object that performs the functions of a Controller in MVC and those of a Command object in Front Controller (or some such).
So I'm wondering what the general opinions would be of others who have implemented similar patterns in their apps - do you handle the request entirely within the controller layer or do you make the model aware of the request and handle parameters directly within the model?
My first thought is to avoid handling any sort of request in the model. That is the job of the controller. Here is why: suppose you have a model that does handle your requests (GET or POST). That structure will likely work well initially. Now, suppose you want to add some sort of AJAX functionality or put up a service interface to your system. Now that you accept more than simple GET/POST, i.e. JSON or XML, your model will have to distinguish between each request type and know how to parse them. I believe that destroys a lot of simplicity and clarity of the model code. I agree that the controller layer should be thin, but it should also have a role and an expertise. For me a controllers expertise is to:
Handle incoming requests
Delivery data to the model
Request/accept data from the model
Pass the data's model to the view
I vacillate on how much the view should know about the model. Some people recommend the model go straight into the view, but I think that is fragile coupling. It frequently leads to logic in the view. Also, if you are working on a project where the team members working on the view are not as programming savvy as the main developers it puts a large burden on them to keep up with changes. I tend to package the data I hand to my views in a neutral structure instead of handing over the full models.
My interpretation of MVC is mostly pragmatic. The model's job is to model the domain you are working on and should not care where the data comes from. I frequently structure model code with the assumption that it could be used outside of the web application in perhaps a command line application or a desktop application. That sort of union rarely happens, but it leads to clear purpose of each layer. The controllers job is to move data between involved parties, be they client requests, the models, or the view. The controller should have very little domain logic, but that doesn't mean it doesn't have any code. Finally, the view should just look pretty. Hope that helps.
handling the user instructions/input (like HTTP requests) is the job of the controller. model is for working/manipulating/fetching the data and view is for showing the results to user. this means that connection between the view and the model is duty of a controller most of times.