In most MVC implementations, a web request typically has the following lifecycle:
The browser sends the request to the server hosting the MVC application.
A controller is invoked to handle the request.
The controller interacts with the model.
The controller invokes the view.
The view renders the data (often as HTML) and returns it to the browser for display.
Yii's MVC implementation is no exception. In a Yii application, incoming requests from the browser are first received by a router. The router analyzes the request to decide where in the application it should be sent for further processing. In most cases, the router identifies a specific action method within a controller class to which the request is passed. This action method will look at the incoming request data, possibly interact with the model, and perform other needed business logic. Eventually, this action class will prepare the response data and send it to the view class. The view will then massage this data to conform to the desired layout and design, and return it for the browser to display.
To help all of this make more sense, let's look at a fictitious example. Pretend we have used Yii to build ourselves a new blog site, yourblog.com. This site is similar to most typical blog sites out there. The home page displays a list of recently posted blog posts. The names of each of these blog postings are hyperlinks that take the user to the page that displays the full article. The next diagram illustrates how Yii handles an incoming request sent from clicking on one of these hypothetical blog post links.
The figure traces the request made from a user clicking on the following link: http://yourblog.com/post/show/id/99
First, the request is sent to the router. The router parses the request to decide where to send it. The structure of the URL is key to the decision the router will make. By default, Yii recognizes URLs with the following format: http://hostname/index.php?r=ControllerID/ActionID
The r
querystring
variable refers to the route that is analyzed by the Yii router. It will parse this route to determine the appropriate controller and action method to further handle the request. Now, you may have immediately noticed that the URL mentioned in the previous example does not follow this default format. It is a simple matter to configure the application to recognize the more search engine friendly format: http://hostname/ControllerID/ActionID
We will continue to use this simplified format for the purposes of this example. The ControllerID
in the URL refers to the name of the controller. By default this is the first part of the controller class name, up to the word Controller
. For example, if your controller class name is TestController
, the ControllerID
would be Test
. Similarly, ActionID
refers to the name of the action that is defined by the controller. If the action is a simple method defined within the controller, this will be whatever follows the word Action
in the method name. For example, if your action method is named actionCreate()
,
the
ActionID
is Create
.
Note
If the ActionID
is omitted, the controller will take the default action, which is a method in the controller called actionIndex()
. If the ControllerID
is also omitted, the application will use the default controller. The Yii default controller is called SiteController
.
Turning back to the example, the router will analyze the following URL, http://yourblog.com/post/show/id/99
, and will take the first part of the URL path, post
to be the ControllerID
and the second part, show
to be the ActionID
. This will translate to routing the request to the actionShow()
method within the PostController
class. The last part of the URL (id/99
) is a name/value querystring
parameter that will be available to the method during processing. In this example, 99
represents the unique internal id
for the selected blog post.
The actionShow()
method handles requests for specific blog post entries. In this case, it uses the querystring
variable,
id
to determine which specific post is being requested. It asks the model to retrieve information about blog post entry number 99
. The model AR class interacts with the database to retrieve the requested data. After retrieving the data from the model, the controller class further prepares it for display by making it available to the view. The view then renders the needed HTML in a response back to the user's browser.
This MVC architecture allows us to separate the presentation from the model, and the controller from the view. This makes it easy for developers to change aspects of the application without affecting the User Interface (UI) and for UI designers to freely make changes without affecting the model or business logic. This separation also makes it very easy to provide multiple presentations of the same model code. For example, you could use the same model code that drives the HTML layout of yourblog.com to drive a Flash/Flex RIA presentation or a mobile application or web services, or a command-line interface. In the end, following this set conventions and separating the functionality will result in an application that is much easier to extend and maintain.
Yii does a lot more to help you enforce this separation than simply providing some naming conventions and suggestions for where your code should be placed in a folder structure. It helps to take care of all the lower-level glue code needed to stitch all the pieces together. This allows you to reap the benefits of a strict MVC designed application without having to spend all the time coding the details yourself. Let's take a look at some of these lower-level details.