The past several years have marked a significant 'framework boom', and almost everyone involved in web application development these days is a part of a new generation of 'framework boomers'. Web development frameworks help jumpstart your application by immediately delivering the core foundation and plumbing needed to quickly turn your ideas scribbled on the whiteboard into a functional and production-ready code. With all of the common features expected from web applications today and available framework options that meet these expectations, there is little reason to code your next web application from scratch. A modern, flexible, and extensible framework is almost as essential a tool as the programming language itself to today's web developer. Moreover, when the two are particularly complementary, the results are an extremely powerful toolkit: Java and Spring, Ruby and Rails, C# and .NET, and PHP and Yii.
Yii is the brainchild of its founder Qiang Xue who started the development of this open source framework on January 1st, 2008. Prior to this, Qiang had previously developed and maintained the PRADO framework for many years. The years of experience and user feedback cultivated from the PRADO project solidified the need for a much easier, more extensible and more efficient PHP5-based framework to meet the ever-growing needs of application developers. The initial alpha version of Yii was officially released to meet these needs in October of 2008. Its extremely impressive performance metrics when compared to other PHP-based frameworks immediately drew very positive attention. On December 3rd, 2008, Yii 1.0 was officially released and as of March 14th, 2010, the latest production-ready version is 1.1.2. It has a growing development team and continues to gain popularity among PHP developers everyday. We feel that with just a little help from the information contained in this book, you will soon understand why.
The name Yii (an acronym for Yes, it is, pronounced as Yee or [ji:]) stands for easy, efficient, and extensible. Yii is a high-performance, component-based, web application framework written in PHP 5. Yii makes it easier to create and maintain large-scale web applications. It also makes them more efficient and extensible. Let's take a quick look at each of these characteristics of Yii in turn.
To run a Yii-powered web application, all you need is the core framework files and a web server supporting PHP 5.1.0 or higher. To develop with Yii, you only need to know PHP and object-oriented programming(OOP). You are not required to learn any new configuration or templating language. Building a Yii application mainly involves writing and maintaining your own custom PHP classes, some of which will extend from the core Yii Framework component classes.
Yii incorporates many of the great ideas and work from other well-known web programming frameworks and applications. So, if you are coming to Yii after using other web development frameworks, it is likely you will find it familiar and easy to navigate.
Yii also embraces a convention over configuration philosophy, which contributes to its ease of use. This means that Yii has sensible defaults for almost all aspects of wiring your application. If you follow the prescribed conventions, you will write less code and spend less time developing your application. If desired, Yii allows you to customize and easily override all of these conventions. We will be covering some of these defaults and conventions later in this chapter and throughout the book.
Yii is a high-performance component-based framework for developing web applications on any scale. It encourages maximum code reuse in web programming, and can significantly accelerate the development process. As mentioned previously, if you stick with Yii's built-in conventions, you can get your application up and running with little to no manual configuration.
Yii is also designed to help you with DRY development. DRY (Don't Repeat Yourself) is a key concept of agile application development. All Yii applications are built using the Model-View-Controller (MVC) architecture. Yii enforces this development pattern by providing a place to keep each piece of your MVC code. This minimizes duplication and helps promote code reuse and ease of maintainability. The less code you need to write, the less time it takes to get your application to market. Similarly, the easier it is to maintain your application, the longer it will stay on the market.
Of course, the framework is not just efficient to use, it is also remarkably fast and performance is optimized. Yii has been developed with performance optimization in mind from the very beginning, and the result is that it is one of the most efficient PHP frameworks around. The Yii development team has performed performance comparison tests with many other PHP frameworks, and Yii outperformed them all. This means that the additional overhead Yii adds to applications written on top of it is negligible.
Yii has been carefully designed to allow nearly every piece of its code to be extended and customized to meet almost any need or requirement. In fact, it is difficult not to take advantage of Yii's ease of extensibility as a primary activity when developing a Yii-driven application, which is extending the core framework classes. If you want to turn your extended code into useful tools for other developers to use, Yii provides easy-to-follow steps and guidelines to help you create such third-party extensions. This allows you to contribute to Yii's ever-growing list of features and actively participate in extending Yii itself.
What is also remarkable about Yii is its ease of use, superior performance, and its depth of extensibility which does not come at the cost of sacrificing features. Yii is packed with features to help you meet those high demands placed on today's web applications. AJAX-enabled widgets, web service integration, enforcement of an MVC architecture, DAO and relational Active Record database layer, sophisticated caching, hierarchical role-based access control, theming, internationalization (I18N), and localization (L10N), are just the tip of the Yii iceberg. As of version 1.1, the core framework is now packaged with an official extension library called Zii. These extensions are developed and maintained by the core framework team members who continue to extend Yii's core feature set. With a deep community of users who are also contributing by writing Yii extensions, the overall feature set available to a Yii powered application is growing daily. For a complete list of all available user contributed extensions, see http://www.yiiframework.com/extensions/.
As mentioned previously, Yii is an MVC framework and it provides an explicit folder structure for each piece of model, view, and controller code. Before we start building our first Yii application, we need to define a few key terms, and look at how Yii implements and enforces this MVC architecture.
Typically in an MVC architecture, the model is responsible for maintaining state. Thus, it should encapsulate the business rules that apply to the data that defines this state. A model in Yii is any instance of the framework class
CModel or its child class. A model class typically comprises data attributes that can have separate labels (something user-friendly for the purpose of display), and can be validated against a set of rules defined in the model. The data that makes up the attributes in the model class could come from a row of a database table or from the fields in a user input form.
Yii implements two kinds of models: The form model (
CFormModel class) and the active record model (
CActiveRecord class). They both extend from the same base class
CFormModel represents a data model that collects inputs in HTML form. It encapsulates all the logic for form field validation and any other business logic that may need to be applied to the form field data. It can then store this data in memory, or with the help of an active record model, store data in a database.
Active Record (AR) is a design pattern used to abstract database access in an object-oriented fashion. Each AR object in Yii is an instance of
CActiveRecord or its child class that wraps a single row in a database table or view, encapsulates all the logic and details around database access, and houses much of the business logic that is required to be applied to that data. The data field values for each column in the table row are represented as properties of the AR object. AR is described in more detail a little later.
Typically, the view is responsible for rendering the user interface, based on the data in the model. A view in Yii is a PHP script that contains user interface related elements, often built using HTML, but can also contain PHP statements. Usually any PHP statements within the view are very simple conditional or looping statements, or refer to other Yii UI-related elements such as HTML helper class methods or prebuilt widgets. More sophisticated logic should be separated from the view and placed appropriately in either the model (if dealing directly with the data), or in the controller for a more general business logic.
The controller is our main director of a routed request and is responsible for taking user input, interacting with the model, and instructing the view to update and display appropriately. A controller in Yii is an instance of
CController or its child. When a controller runs, it performs the requested action, which then interacts with needed models and renders an appropriate view. An action, in its simplest form, is a controller class method whose name starts with the word action.
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:
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:
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
ControllerID would be
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
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
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.
actionShow() method handles requests for specific blog post entries. In this case, it uses the
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.
For the most part, the web applications we build house their data in a relational database. The blog posting application we used in the previous example holds blog post content in database tables. However, web applications need the data that is held in the persistent database storage mapped to in-memory class properties that define the domain objects. Object-relational mapping (ORM) libraries provide this mapping of database tables to domain object classes.
Much of the code that deals with ORM is about describing how fields in the database correspond to fields in our objects, which is tedious and repetitive to write. Luckily, Yii comes to our rescue to save us from this repetition and tedium by providing the ORM layer in the form of the AR pattern.
As was previously mentioned, AR is a design pattern used to abstract database access in an object-oriented fashion. It maps tables to classes, rows to objects and columns to object attributes. In other words, each instance of an active record class represents a single row in a database table. However an AR class is more than just a set of attributes that map to columns in a database table; it also houses the needed business logic behavior to be applied to that data. The end result is a class that defines everything about how it should be written to and read from the database.
By relying on convention and sticking with reasonable defaults, Yii's implementation of AR will save the developer a ton of time normally spent in configuration or in writing tedious and repetitive SQL statements required to create, read, update and delete data. It also allows the developer to access data stored in the database in a much more object-oriented way. To illustrate this, here is some example code that uses AR to operate on a specific blog posting whose internal id, which is also used as the table's Primary Key, is
99. It first retrieves the posting by Primary Key, it then changes the title, and then updates the database to save the changes:
$post=Post::model()->findByPk(99); $post->title='Some new title'; $post->save();
Active Record completely relieves us of the tedium of having to write any SQL or otherwise deal with the underlying database.
Active Record does even more than this. It integrates seamlessly with many other aspects of the Yii Framework. There are myriad active html helper input form fields that tie directly to their respective AR class attributes. This way, Active Record extracts the input form field values directly into the model. It also supports sophisticated, automated data validation, and if the validation fails, the Yii view classes easily display the validation errors to the end user. We will be revisiting AR and providing many concrete examples throughout this book.
The view and the controller are very close cousins. The controller makes the data available for display to the view and the view generates the pages that trigger events, which sends data to the controller.
In Yii, a view file belongs to the controller class that rendered it. This way, inside a view script, we can access the controller instance by simply referring to
$this. This implementation makes the view and controller very intimate. Thankfully, all of these details are handled for us by Yii, so we can focus on coding the specific application.
There is also a lot more to Yii controllers than just calling the model and rendering views. Controllers can manage services to provide sophisticated pre- and post-processing on requests, implement basic access control rules to limit access to certain actions, manage application-wide layout and nested layout file rendering, manage pagination of data, and many other behind-the-scenes services. Again, we have Yii to thank for not needing to get our hands dirty with these messy details.
There is a lot to Yii. The best way to explore all its beauty is to start using it. Now that we have some of the basic ideas and terminology under our belt, we are in a great position to do just that. In the next chapter, we will go through the simple Yii installation process, and then build a working application to better illustrate these ideas.
In this chapter, we were introduced at a very high level to the Yii PHP web application framework. We also covered a number of software design concepts embraced by Yii. Don't worry if the abstract nature of this initial discussion was a tad lost on you. It will all make sense once we dive into specific examples. But, to recap, we specifically covered:
The importance and utility of application development frameworks.
What Yii is and the characteristics of Yii that make it incredibly powerful and useful.
The MVC application architecture and the implementation of this architecture in Yii.
A typical Yii web request lifecycle and URL structures.
Object-relational mapping and Active Record in Yii.