Also available in these languages:
DeutschEnglishEspañolFrançaisעִבְרִיתBahasa Indonesia日本語polskiPortuguêsRomâniaРусскийsvenska简体中文

Component

Yii applications are built upon components which are objects 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 object's public member variable. We can read its value or assign a value to it. For example,

$width=$component->textWidth;     // get the textWidth property
$component->enableCaching=true;   // set the enableCaching property

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:

public function getTextWidth()
{
    return $this->_textWidth;
}
 
public function setTextWidth($value)
{
    $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.

Note: There is a slight difference between a property defined via getter/setter methods and a class member variable. The name of the former is case-insensitive while the latter is case-sensitive.

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:

public function onClicked($event)
{
    $this->raiseEvent('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').

The signature of an event handler must be as follows:

function methodName($event)
{
    ......
}

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.

Starting from version 1.0.10, an event handler can also be an anonymous function which is supported by PHP 5.3 or above. For example,

$component->onClicked=function($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 object 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:

// $name uniquely identifies the behavior in the component
$component->attachBehavior($name,$behavior);
// 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 object 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 events, 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.

Starting from version 1.1.0, a behavior's properties can also be accessed via the component it is attached to. The properties include both the public member variables and the properties defined via getters and/or setters of the behavior. For example, if a behavior has a property named xyz and the behavior is attached to a component $a. Then we can use the expression $a->xyz to access the behavior's property.

$Id: basics.component.txt 2181 2010-06-14 20:01:23Z qiang.xue $
If you find any typos or errors in the tutorial, please create a Yii ticket to report it. If it is a translation error, please create a Yiidoc ticket, instead. Thank you.

Total 9 comments:

#23
Virtual properties differences
by KJedi at 12:13am on December 17, 2008.

There is one thing you should remember when defining virtual property using getter and setter like in example with textWidth.

You'll be able to write

$component->textWidth = $width

and

$width = $component->textWidth

But you can't use it in construction like empty() or isset(). Why? Reason is simple. Both functions require a variable, and writing

$component->textWidth;

you're calling your

public function getTextWidth()
{
    return $this->_textWidth;
}

So this is not a variable, this is result of function call! You can't pass it by reference, can't get or change it's name (like for normal variable):

$a = $$abc;//$a now holds a string abc
$$abc = 'a';//now we can write $a and it is the same as $abc was. 
// It's not the reference, just changed the variable name.

Please note the main thing - virtual properties are not variables, and write your code understanding this. Good luck!

#31
Little think
by Juan Basso at 12:06pm on December 25, 2008.

In your example: public function getTextWidth( ) { return $this->_textWidth; } public function setTextWidth($value) { $this->_width=$value; }

The set change $this->_width variable, while get read $this->_textWidth variable. Is great if is the same variable. :)

#942
Where components are used in real dev world?
by colt at 1:36pm on January 1, 2010.

From the OO newbie point of view, where would these components be used in real app? Some examples please, thanks:)

#1062
ajsie
by ajsie at 2:27pm on February 2, 2010.

it would be helpful if the tutorials give some more examples. cause after i read this page, i still don´t have a clue what a component is in a real world app.

#1205
Need examples
by yiimann at 3:56am on March 1, 2010.

I guess we need real world examples to understand what behaviors could be used for.

#1712
Include js
by Tyr84 at 7:58am on July 22, 2010.

Is there possible to include JS like in extension? Example : $this->clientScript->registerScriptFile('/view/calculate.js');

Maybe other ways?

#1719
examples.. examples...
by Juan Pablo Sala at 7:18am on July 24, 2010.

Please, I know is tedious to write them, but it's incredible useful for newbies like me and others!!! so please... write lot of them :-)

#1720
examples.. examples...
by Juan Pablo Sala at 7:18am on July 24, 2010.

Please, I know is tedious to write them, but it's incredible useful for newbies like me and others!!! so please... write lot of them :-)

#1759
Abstract examples ...
by uml_mda at 8:54pm on August 4, 2010.

in order to resolve any problem, mathematicians decompose this problem into several smaller problems, because they are more easy to understand and to resolve step by step. Ecquivalent of this math example is our project, which can be decompose also into several modules, but modules can be decompose into several smaller subsystems, which are named components. By this algorithm of decomposition we can easy and efficiently maintain any kind of scaled projects. I hope this description will help you to clearly imagine this easy way.

http://www.yiiframework.com/doc/guide/basics.module A module is a self-contained software unit that consists of models, views, controllers and other supporting components. In many aspects, a module resembles to an application.

P.S.: sorry for my bad english.

Your Comment:

You may enter comment using Markdown syntax.

Please login with your forum account.
Note: you must have at least ONE forum post with your account.