I want to access a controller, which is located in application/controller/example.php, from a model - located in application/model/users.php
class Users extends CI_Model {
//access the example.php controller
}
Who could i accomplish this ?
You don't want to ever do that, hence why CodeIgniter cannot do it. You should be accessing everything else from your Controller, not the other way around.
A good old resource from CodeIgniter :)
http://codeigniter.com/user_guide/overview/mvc.html
You dont have to access an controller from a model. Models (Views, helpers, libraries ect) should all be accessed from controllers. ( Model are used from manipulating data ( usually in database ) )
The idea behind the MVC is to have a Model, Viewer and Controller.
In other words the Controller handles the request, the Model gets the data and the Viewer displays something to the user.
The Model is used ONLY to manipulate the data - doesn't matter if it's a database connection or other data resource.
Model is where you store your bussines logic. Controller is where you call things and operate with data. Views are for creating output.
Bassically you can do everything from withing controller, but that is wrong, since it does not gain you any clarity. Try to offload as much as possible to models and views and keep controllers small and readable, well commented.
Related
I have searched on SO about this question, but I basically haven't found one concerning this particular scenario; hence, my reason for asking.
I have a basic, abstract understanding of the MVC pattern: Controller calls the right Model based on the action needed; the Model contains the actual business/data logic, and the View displays the result. What I am having trouble understanding is the actual implementation.
Originally, my assumption was this: Controller calls Model; Model processes information, and returns the data back to Controller; Controller call the View, passing this
data to the View, which simply displays it. After reading more articles on MVC, I discovered that the Model doesn't really pass the data back to the Controller; rather, it fires an event, which allows the Controller to call the proper View.
My question centers on this event firing part:
Q.1: Must an event really be fired? Once the Model completes its processing, and returns control to the Controller, can't the Controller simply call the View?
Q.2: In an actual implementation, a Model object is injected into a Controller class. So, Model object basically has no idea what Controller called it. How does it know what Controller to fire an event to? And how do we know what Controller is expecting that notification?
Q.3: The Controller calls the View, injecting it with the current Model object, so the View can use it to obtain the needed data. Is this correct or wrong? If wrong, why is it wrong, and what is the proper way to do it?
I have read my questions on MVC on here and other sites, viewed MVC diagrams, but I haven't been able to really connect the dots the way it's supposed to be connected.
Thanks.
There are many way's on how the different components on MVC are linked together. I think there is no 'Golden Rule'.
I use it the way shown in this picture:
The creation of objects is then like this:
the app object creates a controller, depending on the route. The router is injected into the controller.
The controller creates a model, depending on the route. The model is created by a IoC container.
The controller creates a view, and injects the model into the view.
In my situation I can answer your questions like this:
Q1: No, I do not use events. There is no need. The controller calls the model, and when done the model has state, and can be used by the view.
Q2: I do it just the other way, the controller creates the model. The model has no knowledge about the controller, or view.
Q3: this is the way I implement it.
Let's say I have a Model 'Retrieve.php' where I have a class named 'Retrieve' and it retrieves posts from a database. Then I have Controller in Index.php where I load that model, retrieve posts and pass it to view.
And now, I have one more page where I have to show those posts. Let's say Sidebar.php or something. And now again, I have to retrieve those posts. So, can I load 'Retrieve.php' once more, or I have to create one more model for Sidebar.php which extends 'Retrieve.php'? What is better practise?
And, in general, do I need for every controller create a new model in a good PHP MVC? If yes, probably Controller and Model should be named the same? Any more advices/comments?
Thank you.
In general, the model should represent a business entity and not a process. I.e., it should be a noun and not a verb. In your case, you want a model for a post, and the methods on that model will perform "the things you do with/to a post." The controller then describes what actions occur for a page. In this case, a controller for the /post page would retrieve a post and pass it to the view for rendering.
Only create the models you need. Remember, the whole point of MVC is that the models are decoupled from the views. This means it's perfectly fine to reuse whatever you need to get the job done. If you have multiple views which need access to the same data, just reuse the same model. Just be sure to give the models descriptive names so there's no confusion as to what they're supposed to represent.
You should only have one Model class for each data structure that that model represents. So if you have 5 Controllers that each access the same Model, you should still only ever have one Model class.
No --
Model should be what your application manages -- so instead of Retrieve, your model class should probably be Post (and maybe you have other Model classes for the nouns in your domain-- Thread, Author...)
The controllers should access the model classes they need to do their jobs; one model class could be used by several controllers, and one controller could use several model classes.
I'm trying to get to grips with the MVC structure and trying to decide where my files should go.
I have a php script which reads an image from a non-web accessible location and outputs it.
Does it belong in the Controller or the View?
Likewise, should a script that loads a smarty template (from the view) and sets values and output it be within the Controller or the View?
Thanks for your help!
I Second. Model because controllers get fat so fast.
It should be a model as only Models should be allowed to know where data can be found and how they should be access (filesystem in your case). Also data conversion is best done in a model.
Dare to output compressed JPGs instead 10MB+ BMP-files on the fly? If your server can manage it your $ImageModel->outputAsJPEG() could be called in the controller, skipping viewscripts alltogether or delegated to the viewscripts/smarty functions.
Both your examples sound like Model logic to me, but the second example is a little more fuzzy. A template is a View but setting values is probably Model logic if it's non-trivial.
Your View should invoke a Model to get stuff it needs, and the Controller should be deciding which View to display and instantiating the right Model to hand off to the View.
If you can treat your proxy image script as a Model then just invoke it in the View.
Only Model in this situation.
I'm thinking of re-working my MVC before I get to far along with it. At the moment it uses a sinle controller which takes the user input and determines the model. The model has maby differ methods which I call actions, because one is called automatically. The model loads its view file, which again holds many different methods. The model can set properties which can be used in the view. Then the controller calls th template classwhich parses the output for display.
Is this the bst way to do it?
Or should each different part (news, contact, about) have its own controller, which loads a specific model and view. Essentially, instead of grouping methods into a single file, it uses multipe files.
I'm kind of lost as to how I should do it.
Cheers
Start using a MVC that works and is well-known like in Symfony or Cake. From that you will decide:
what do to in your own, knowing the best practices;
to drop your own if you feel like you can save time by using theses.
If you are thinking of advancing your own MVC model, like #e-satis have said, you will need to experience what is happening in already developed systems. However, as based on my experience in designing MVC model and determining what is there in opensource community, I stick back to my own MVC for two good reasons. One reason is the flexibility of customization and the other is own MVC privacy.
I used the following approach for MVC design pattern.
A Router.php file identifying user-request urls. This router will be able to fetch controllers and include the file and call the controller default method.
The loaded controller is also able to load other controllers if required to function. This is done using a global method, where all controller Class will extend to a MainController Class which is able to call to other controllers.
I do use a global registry to set and get variables from one controller to the other.
The Models are used to get the Data from Table, and most of my Models will represent Database functions which includes CRUD (Create Read Update Delete). So that a controller can easily manipulate database table data using a model.
Naming conventions in all controller, models, and views is also important, if you want to system to be more intelligent to identify the required action knowing the file name.
I use the Views separately for each type of controller. And these views will be sent to a Master Template View file.
Same as models, the controller will be able to set Views to Master View.
There are other customizations which you can do, like applying security methods before calling a class, or after calling a class/controller/model/view etc.
This is done by the MainController, which it will always look into a folder with autoload class which states what files should be loaded before and after of different actions during the process of building the content and delivering the output.
MVC is not a small scale idea, but it is a design idea which can always be developed. There are so many PHP MVC open source frameworks to be found if you know how to search the major search engines like google.com
But I do advice you that, MVC is not a good solution if you are simply developing a small dynamic website, as it will consume more time in developing compared to developing small websites. MVC is ideal, if you have business logic and needs system automation in order to avoid most routine tasks of developing, and like that I would say MVC is most ideal for larger applications.
The model loads its view file
The Controller should act as a Mediator between the Model and the View.
The Model shouldn't be aware of the way the view renders it, and also the View shouldn't be aware of any kind of logic of the Model.
In theory, if your MVC is well structured, you should be able to represent the same Model with different types of Views (HTML, XML, JSON for example).
Build FrontController which parses request uri and decides which controller to load and which method to run. With .htaccess rewrite all request to index.php
//index.php
class FrontController{
function run(){
//parse request uri here /comment/new
//load controller comment
//run controllers method new and pass some request attributes
}
}
// ../controllers/comment.php
class Controller_Comment extends Controller{
function new($request){
//do stuff here
}
}
I am working on a CMS using CakePHP and I want to create a dynamic menu which is the same on all the pages the user can access. So I figured out to create in the layout (since it shared among so many pages and view) but I don't seem to know how to acces the model and get the data from the database to construct the menu. any help is appreciated.
That's because for proper MVC separation* in Cake you're not supposed to access the Model from the View. The only part with access to data should be the Controller (via the Model), which hands it down to the View, which simply displays the data.
As such, using a beforeFilter callback in your global AppController to set() the data is probably the best choice.
In emergencies you can always access anything from anywhere by loading an instance of the needed Class using ClassRegistry::init, but you really shouldn't.
* Actually, in "proper MVC" there's no problem with the View getting data directly from the model. You shouldn't do that in templates necessarily, but View related code can well get data from the model to visualise the model state. It just doesn't really work that way in Cake, because Cake is not proper MVC and default Cake views are only templates.
An alternative could be requestAction, it allows you to call controller actions from views/layouts, and in those actions you can then access the desired model(s).