Yii
Yii
www.techalone.com
1/28/2010
Yii Seminar Report
CHAPTER 1 : INTRODUCTION
The Yii framework is free software. It is released under the terms of the following BSD
License.
This page summarizes the main new features introduced in each Yii release.
• Version 1.0.7
• Version 1.0.6
• Added support for using named scope with update and delete methods:
– Named Scopes
• Added support for using named scope in the with option of relational rules
• Version 1.0.5
Requirements
To run an Yii-powered Web application, you need a Web server supporting PHP 5.1.0
or higher.
For developers who want to use Yii, understanding ob ject-oriented programming
(OOP)is very helpful, because Yii is a pure OOP framework.
1.4 Installation
Installation of Yii mainly involves the following two steps:
• Download Yii Framework from yiiframework.com.
• Unpack the Yii release file to a Web-accessible directory.
Requirements
After installing Yii, you may want to verify that your server satisfies all the
requirementsof using Yii. You can do so by accessing the requirement checker script at the
followingURL in a Web browser:
http://hostname/path/to/yii/requirements/index.php
The minimum requirement by Yii is that your Web server supports PHP 5.1.0 or above.
Yii has been tested with Apache HTTP server on Windows and Linux operating systems.
It may also run on other Web servers and platforms provided PHP 5 is supported.
CHAPTER 2: FUNDAMENTALS
A Typical Workflow
The following diagram shows a typical workflow of an Yii application when it is
handling a user request:
Entry script is the bootstrap PHP script that handles user requests initially. It is the only
PHP script that end users can directly request to execute.In most cases, entry script of an Yii
application contains the code that is as simple as follows,
Yii::createWebApplication($configFile)->run();
The script first includes the Yii framework bootstrap file yii.php. It then creates a Web
application instance with the specified configuration and runs it.
2.3 Application
Application represents the execution context of request processing. Its main task is to
resolve the user request and dispatch it to an appropriate controller for further processing.
It also serves as the central place for keeping application-level configurations. For this
reason, application is also called front-controller.Application is created as a singleton by the
entry script. The application singleton can beaccessed at any place via Yii::app().
array(
’name’=>’Yii Framework’,
’defaultController’=>’site’,
$app=Yii::createWebApplication($configFile);
array(
......
’components’=>array(
......
’cache’=>array(
’class’=>’CMemCache’,
’servers’=>array(
array(’host’=>’server1’, ’port’=>11211, ’weight’=>60),
array(’host’=>’server2’, ’port’=>11211, ’weight’=>40),
),
),
),
)
In the above, we add the cache element to the components array. The cache element
statesthat the class of the component is CMemCache and its servers property should be
initialized as such. To access an application component, use Yii::app()->ComponentID,
where ComponentID refers to the ID of the component (e.g. Yii::app()->cache).
An application component may be disabled by setting enabled to be false in its configu-
ration. Null is returned when we access a disabled component.
2.4 Controller
A controller is an instance of CController or its child class. It is created by application
when the user requests for it. When a controller runs, it performs the requested action which
usually brings in the needed models and renders an appropriate view. An action, at its
simplest form, is just a controller class method whose name starts with action. A controller
has a default action. When the user request does not specify which action to execute, the
default action will be executed. By default, the default action is named as index. It can be
changed by setting CController::defaultAction.
Below is the minimal code needed by a controller class. Since this controller does not
define any action, requesting for it would throw an exception.
2.4.1 Route
Controllers and actions are identified by IDs. Controller ID is in the format of path/
to/xyz which corresponds to the controller class file protected/controllers/path/to/
XyzController.php, where the token xyz should be replaced by actual names (e.g. post cor-
responds to protected/controllers/PostController.php). Action ID is the action method name
without the action prefix. For example, if a controller class contains a method named
actionEdit, the ID of the corresponding action would be edit.
Users request for a particular controller and action in terms of route. A route is formed
by concatenating a controller ID and an action ID separated by a slash. For example, the route
post/edit refers to PostController and its edit action. And by default, the URL
Since version 1.0.3, an application can contain modules. The route for a controller
action inside a module is in the format of moduleID/controllerID/actionID. For more details,
see the section about modules.
used to put the application under maintenance mode and display a static notice
page.
• If the ID is found in CWebApplication::controllerMap, the corresponding controller
configuration will be used to create the controller instance.
• If the ID is in the format of ’path/to/xyz’, the controller class name is assumed to
be XyzController and the corresponding class file is protected/controllers/path/
to/XyzController.php. For example, a controller ID admin/user would be resolved as
the controller class UserController and the class file protected/controllers/admin/
UserController.php. If the class file does not exist, a 404 CHttpException will be
raised.
In case when modules are used (available since version 1.0.3), the above process is
slightly different. In particular, the application will check if the ID refers to a controller
inside
a module, and if so, the module instance will be created first followed by the controller
instance.
2.4.3 Action
As aforementioned, an action can be defined as a method whose name starts with the
word action. A more advanced way is to define an action class and ask the controller to
instantiate it when requested. This allows actions to be reused and thus introduces more
reusability.
of
our controller class:
class PostController extends CController
{
public function actions()
{
return array(
’edit’=>’application.controllers.post.UpdateAction’,
);
}
}
In the above, we use the path alias application.controllers.post.UpdateAction to specify
that the action class file is protected/controllers/post/UpdateAction.php. Writing class-based
actions, we can organize an application in a modular fashion. For example, the following
directory structure may be used to organize the code for controllers:
protected/
controllers/
PostController.php
UserController.php
post/
CreateAction.php
ReadAction.php
UpdateAction.php
user/
CreateAction.php
ListAction.php
ProfileAction.php
UpdateAction.php
2.4.4 Filter
Filter is a piece of code that is configured to be executed before and/or after a controller
action executes. For example, an access control filter may be executed to ensure that the user
is authenticated before executing the requested action; a performance filter may be used to
measure the time spent in the action execution.
An action can have multiple filters. The filters are executed in the order that they appear
in the filter list. A filter can prevent the execution of the action and the rest of the unexecuted
filters.
A filter can be defined as a controller class method. The method name must begin with
filter. For example, the existence of the filterAccessControl method defines a filter named
accessControl. The filter method must be of the signature:
array(
’application.filters.PerformanceFilter - edit, create’,
’unit’=>’second’,
),
);
}
}
The above code specifies two filters: postOnly and PerformanceFilter. The postOnly fil-
ter is method-based (the corresponding filter method is defined in CController already); while
the PerformanceFilter filter is ob ject-based. The path alias application.filters.
PerformanceFilter specifies that the filter class file is protected/filters/PerformanceFilter.
We use an array to configure PerformanceFilter so that it may be used to initialize the
property values of the filter ob ject. Here the unit property of PerformanceFilter will be
initialized as ’second’.
Using the plus and the minus operators, we can specify which actions the filter should
and should not be applied to. In the above, the postOnly should be applied to the edit and
create actions, while PerformanceFilter should be applied to all actions EXCEPT edit and
create. If neither plus nor minus appears in the filter configuration, the filter will be applied to
all actions.
Model
A model is an instance of CModel or its child class. Models are used to keep data and
their relevant business rules. A model represents a single data ob ject. It could be a row in a
database table or a form of user inputs. Each field of the data ob ject is represented as an
attribute of the model.
The attribute has a label and can be validated against a set of rules. Yii implements two
kinds of models: form model and active record. They both extend from the same base class
CModel.
A form model is an instance of CFormModel. Form model is used to keep data
collected from user inputs. Such data are often collected, used and then discarded. For
example, on a login page, we can use a form model to represent the username and password
information that are provided by an end user. For more details, please refer to Working with
Form Active Record (AR) is a design pattern used to abstract database access in an ob ject-
oriented fashion. Each AR ob ject is an instance of CActiveRecord or its child class,
representing a single row in a database table. The fields in the row are represented as
properties of the AR ob ject. Details about AR can be found in Active Record.
View
A view is a PHP script consisting of mainly elements of user interface. It can contain
PHP statements, but it is recommended that these statements should not alter data models and
should remain relatively simple. For the spirit of separation of logic and presentation, large
chunk of logic should be placed in controller or model instead of view.
A view has a name which is used to identify the view script file when rendering. The
name of a view is the same as the name of its view script file. For example, view edit refers to
a view script file named as edit.php. To render a view, call CController::render() with the
name of the view. The method will look for the corresponding view file under the directory
protected/views/ControllerID.
Inside the view script, we can access the controller instance using $this. We can thus
pull in any property of the controller by evaluating $this->propertyName in the view. We can
also use the following push approach to pass data to the view:
$this->render(’edit’, array(
’var1’=>$value1,
’var2’=>$value2,
));
In the above, the render() method will extract the second array parameter into variables.
As a result, in the view script we can access local variables $var1 and $var2.
Layout
Layout is a special view that is used to decorate views. It usually contains portions of
user interface that are common among several views. For example, a layout may contain
header and footer portions and embed the content view in between,
......header here......
<?php echo $content; ?>
......footer here......
Layout is implicitly applied when calling render(). By default, the view script protected/
views/layouts/main.php is used as the layout. This can be customized by changing either
CWebApplication::layout or CController::layout. To render a view without applying any
layout, call renderPartial() instead.
Widget
A widget is an instance of CWidget or its child class. It is a component mainly for
presentational purpose. Widgets are usually embedded in a view script to generate some
complex yet self-contained user interface. For example, a calendar widget can be used to
render a complex calendar user interface. Widgets enable better reusability in user interface.
The latter is used when the widget does not need any body content.
Widgets can be configured to customize its behaviors. This is done by settings their
initial property values when calling CBaseController::beginWidget or
CBaseController::widget. For example, when using CMaskedTextField widget, we would
like to specify the mask being used. We can do so by passing an array of those property
initial values as follows, where the array keys are property names and array values the initial
values of the corresponding widget properties:
<?php
$this->widget(’CMaskedTextField’,array(
’mask’=>’99/99/9999’
));
?>
To define a new widget, extend CWidget and override its init() and run() methods:
class MyWidget extends CWidget
{
public function init()
{
//this method is called by CController::beginWidget()
}
Like a controller, a widget can also have its own view. By default, widget view files are
located under the views subdirectory of the directory containing the widget class file. These
views can be rendered by calling CWidget::render(), similar to that in controller. The only
difference is that no layout will be applied to a widget view.
System View
System views refer to the views used by Yii to display error and logging information.
For example, when a user requests for a non-existing controller or action, Yii will throw an
exception explaining the error. Yii displays the exception using a specific system view.
The naming of system views follows some rules. Names like errorXXX refer to views for
displaying CHttpException with error code XXX. For example, if CHttpException is raised
with error code 404, the error404 view will be displayed.
Yii provides a set of default system views located under framework/views. They can be
customized by creating the same-named view files under protected/views/system.
Component
Yii applications are built upon components which are ob jects written to a specification.
A component is an instance of CComponent or its derived class. Using a component mainly
involves accessing its properties and raising/handling its events. The base class CComponent
specifies how to define properties and events.
Component Property
A component property is like an ob ject’s public member variable. We can read its
value or assign a value to it. For example,
To define a component property, we can simply declare a public member variable in the
component class. A more flexible way, however, is by defining getter and setter methods
like the following:
$this-> textWidth=$value;
}
The above code defines a writable property named textWidth (the name is case-
insensitive). When reading the property, getTextWidth() is invoked and its returned value
becomes the property value; Similarly, when writing the property, setTextWidth() is invoked.
If the setter method is not defined, the property would be read-only and writing it would
throw an exception. Using getter and setter methods to define a property has the benefit that
additional logic (e.g. performing validation, raising events) can be executed when reading
and writing the property.
Component Event
Component events are special properties that take methods (called event handlers) as
their values. Attaching (assigning) a method to an event will cause the method to be invoked
automatically at the places where the event is raised. Therefore, the behavior of a component
can be modified in a way that may not be foreseen during the development of the component.
A component event is defined by defining a method whose name starts with on. Like
property names defined via getter/setter methods, event names are case-insensitive. The
following code defines an onClicked event:
where $event is an instance of CEvent or its child class representing the event parameter.
We can attach a method to this event as follows:
$component->onClicked=$callback;
where $callback refers to a valid PHP callback. It can be a global function or a class
method. If the latter, the callback must be given as an array: array($object,’methodName’).
where $event is the parameter describing the event (it originates from the raiseEvent()
call). The $event parameter is an instance of CEvent or its derived class. At the minimum,
it contains the information about who raises the event.
If we call onClicked() now, the onClicked event will be raised (inside onClicked()), and
the attached event handler will be invoked automatically. An event can be attached with
multiple handlers. When the event is raised, the handlers will be invoked in the order that
they are attached to the event. If a handler decides to prevent the rest handlers from being
invoked, it can set $event-¿handled to be true.
Component Behavior
Starting from version 1.0.2, a component has added support for mixin and can be
attached with one or several behaviors. A behavior is an ob ject whose methods can be
’inherited’ by its attached component through the means of collecting functionality instead of
specialization (i.e., normal class inheritance). A component can be attached with several
behaviors and thus achieve ’multiple inheritance’.
Behavior classes must implement the IBehavior interface. Most behaviors can extend
from the CBehavior base class. If a behavior needs to be attached to a model, it may also
extend from CModelBehavior or CActiveRecordBehavior which implements additional
features specifc for models.
To use a behavior, it must be attached to a component first by calling the behavior’s
attach() method. Then we can call a behavior method via the component:
$behavior->attach($name,$component);
//test() is a method of $behavior
$component->test();
An attached behavior can be accessed like a normal property of the component. For
example, if a behavior named tree is attached to a component, we can obtain the reference
to this behavior ob ject using:
$behavior=$component->tree;
//equivalent to the following:
//$behavior=$component->asa(’tree’);
A behavior can be temporarily disabled so that its methods are not available via the
component. For example,
$component->disableBehavior($name);
//the following statement will throw an exception
$component->test();
$component->enableBehavior($name);
//it works now
$component->test();
It is possible that two behaviors attached to the same component have methods of the
same name. In this case, the method of the first attached behavior will take precedence.
When used together with , behaviors are even more powerful. A behavior, when being
attached to a component, can attach some of its methods to some events of the component.
By doing so, the behavior gets a chance to observe or change the normal execution flow
of the component.
To get an initial experience with Yii, we describe in this section how to create our first
Yii application. We will use the powerful yiic tool which can be used to automate code
creation for certain tasks. For convenience, we assume that YiiRoot is the directory where
Yii is installed, and WebRoot is the document root of our Web server.
Note: When running yiic on Mac OS, Linux or Unix, you may need to change the
permission of the yiic file so that it is executable. Alternatively, you may run the
tool as follows,
% cd WebRoot/testdrive
% php YiiRoot/framework/yiic.php webapp WebRoot/testdrive
This will create a skeleton Yii application under the directory WebRoot/testdrive. The
application has a directory structure that is is needed by most Yii applications. Without
writing a single line of code, we can test drive our first Yii application by accessing the
following URL in a Web browser:
http://hostname/testdrive/index.php
As we can see, the application has three pages: the homepage, the contact page and
the login page. The homepage shows some information about the application as well as
the user login status, the contact page displays a contact form that users can fill in to submit
their inquiries, and the login page allows users to be authenticated before accessing
privileged contents.
• testdrive/
Connecting to Database
Most Web applications are backed by databases. Our test-drive application is not an
exception. To use a database, we first need to tell the application how to connect to it. This is
done by changing the application configuration file WebRoot/testdrive/protected/
config/main.php
Note: To use Yii’s database feature, we need to enable PHP PDO extension and
the driver-specific PDO extension. For the test-drive application, we would need
the php pdo and php pdo sqlite extensions to be turned on.
To this end, we need to prepare a SQLite database so that the above configuration can
be effective. Using some SQLite admin tool, we can create a database with the following
schema:
Note: If you are using MySQL database, you should replace AUTOINCREMENT with
AUTO INCREMENT in the above SQL.
For simplicity, we only create a single User table in our database. The SQLite database
file is saved as WebRoot/testdrive/protected/data/source.db. Note that both the file and
the containing directory must be made writable by the Web server process, as required by
SQLite.
Now is the fun part. We would like to implement the CRUD (create, read, update and
delete) operations for the User table we just created. This is also commonly needed in
practical applications.
Instead of taking trouble to write actual code, we would use the powerful yiic tool again
to automatically generate the code for us. This process is also known as scaffolding. Open
a command line window, and execute the commands listed as follows,
% cd WebRoot/testdrive
% protected/yiic shell
Yii Interactive Tool v1.0
Please type ’help’ for help. Type ’exit’ to quit.
>> model User
generate User.php
The ’User’ class has been successfully created in the following file:
D:\wwwroot\testdrive\protected\models\User.php
If you have a ’db’ database connection, you can test it now with:
$model=User::model()->find();
print_r($model);
>> crud User
generate UserController.php
generate create.php
mkdir D:/wwwroot/testdrive/protected/views/user
generate update.php
generate list.php
generate show.php
Crud ’user’ has been successfully created. You may access it via:
http://hostname/path/to/index.php?r=user
In the above, we use the yiic shell command to interact with our skeleton application.
At the prompt, we execute two sub-commands: model User and crud User. The former
generates a model class for the User table, while the latter reads the User model and
generates the code implementing the CRUD operations.
CONCLUSION
REFERENCES
[1] www.code.google.com/yii/
[2] Wikipedia - Yii