How to create a Yii Behavior

Yii Framework

Yii FrameworkFirst of all let’s find out what is exactly a behavior in Yii’s language (text extracted from Yii’s Definitive Guide):

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.

This means that if we require additional features to the models we could extend them by using behaviors and also, that a model could actually implement more than one behavior thus extending endlessly its functionality.

Behaviors is the answer to those who wish to do things that differ from normal use and they need to be shared among other models but not to all of them. What that means? Well, IMHO, I think that if you need a special functionality that is shared among model objects then I suggest that would it better that you create a class that extends from the CActiveRecord and then extend your models from it.

I heard so many times that people wishes to create functions in controllers and we should stick to the MVC approach as it is, and not try to reinvent the wheel with things that come out our creative minds. If you need to do specific actions thing about a controller but if that action involves DB data then work with Models. This is a long discussion that could hold an article by itself; let’s be focus with this article.

Building and Using a Behavior

Our behavior will transform a model into a JSON array and as the Yii guide says, it implements the IBehavior interface as it extends from CBehavior. The code is extracted from my own extension behavior EJsonBehavior, here it is:

//
// EJsonBehavor extends from CBehavior
class EJsonBehavior extends CBehavior{
//
// this property will hold a reference to
// its owner - the model class that will
// have this behavior attached to it
private $owner;
//
// this property will reference the
// relations of the model class -owner
private $relations;
public function toJSON(){
//
// getting a reference to model class
// having this behavior attached to it
$this->owner = $this->getOwner();
//
// making sure it is a CActiveRecord descendant
if (is_subclass_of($this->owner,'CActiveRecord')){
//
// play with it!
//
// get model attributes
$attributes = $this->owner->getAttributes();
//
// if this model has related model classes
// get them attributes
$this->relations 	= $this->getRelated();
//
// structure the to-be-converted JSON
$jsonDataSource = array('jsonDataSource'=>array('attributes'=>$attributes,'relations'=>$this->relations));
//
// return the JSON result
return CJSON::encode($jsonDataSource);
}
return false;
}
//
// returns related model's attributes
private function getRelated()
{
$related = array();
$obj = null;
$md=$this->owner->getMetaData();
foreach($md->relations as $name=>$relation){
$obj = $this->owner->getRelated($name);
$related[$name] = $obj instanceof CActiveRecord ? $obj->getAttributes() : $obj;
}
return $related;
}
} // end of class

The important thing about the above code is not the funcitonality exposed, converting the model to a JSON array, but how we could get a hold to the behavior’s parent and access all its properties. That means, that by the same technique we could use that reference (owner) to play with the database referred by the object itself (check for example the code of the SLUG behavior).

Attaching the Behavior to a Model

This is the easiest part -yes, it is true, writing behaviors is a pretty easy thing with Yii. One way is the one referred on the wiki, which is the way I use it when I just need the use of a behavior certain times but the way I mostly use them is like this:

//
// This function is in the model
// where we want to attach the
// behavior too
public function behaviors() {
//
// needs to return an array
// of behavior objects
return array(
'EJsonBehavior'=>array(
//
// please check how it says to Yii
// where the class is located
'class'=>'application.behaviors.EJsonBehavior'
),
);
}

In the code above, you see how I tell Yii where the class is located in my applications folder; in this case I say to Yii to look for our behavior in the protected/behaviors folder and inside it there is a file EJsonBehavior.php which holds a behavior with a class name as the name of the file -EJsonBehavior.

Once we have attached the behavior to our model class, to use it is as simple as to call its public methods and/or properties. With our behavior above, we just do:

//
// pfff, so easy...
echo $model->toJSON();

After you have seen how easy is to create behaviors, having a look to the code of the Behaviors list at Yii’s site, will incredibly help your current learning curve. Hope this article has helped you to better understand behaviors.

Agile Web Application Development with Yii 1.1 and PHP5

7 comments

  1. Diego   •  

    Hola Antonio, se que lo que te voy a pedir no es muy razonable, pero es que no me entero del tema… Podrías explicar un poco en castellano el tema de los “Behavior”/Mixin de Yii (y por ende de php)? Por más que leo la documentación no lo pillo, no entiendo de que van, como funcionan, cual es su propósito. Y veo que tu los has usado más o menos de manera extensiva.

    Tanto si te es posible como si no, muchas gracias y genial el blog!

    Un saludo!

  2. Pingback: Berkenalan dengan Behavior di Yii - Computesta Blog

  3. Pingback: Berkenalan dengan Behavior di Yii | Computesta

  4. Steve Chen   •  

    Thank you so much for this article!

  5. Santi   •  

    Gran explicacion! Muchas gracias!

  6. Vova   •  

    Thank you for the article. I begin to understand, why should I use behaviors.

  7. Pingback: Berkenalan dengan Behavior di Yii

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>