February 18, 2016

PHP Yii2 Framework - Working with Behaviors

Behaviors are instances of yii\base\Behavior, or of a child class. Behaviors allow you to add functionality to an existing component class without modifying the original class or creating a new derived class. Once we attached the behavior's functions and properties to the component class, we can access those functions and properties on the object of that component class, as if these are regular class functions or properties.

Lets use Behavior in an example. We have a Customer component class, that has a regular public property name.

<?php

namespace app\components;

use yii\base\Component;

class Customer extends Component
{
    public $name = "Muhammad Idrees";
}

And we can access this public name property on $customer object as follows:

 ECHO $customer->name;

Now we need to add a new property to $customer object, but we don't want to modify the contents of original Customer class.

Here comes behaviors. To define a behavior, create a class that extends yii\base\Behavior. So we will create a new class CustomerBehavior with the following implementation.

<?php

namespace app\components;

use yii\base\Behavior;

class CustomerBehavior extends Behavior
{
    public $additionalProperty = "Some default value";

    public function additionalFunction()
    {
        $this->additionalProperty = "value changed";
    }
}

This CustomerBehavior class contains a new property additionalProperty and a new function additionalFunction. But at this moment this is just an empty behavior and has no effect on Customer class. To add this behavior functionality to an object of Customer class, we have to attach this behavior with Customer component.

There are two ways you can attach behavior to a component class:

  1. Static attachment

    To attach a behavior statically, we have to write the override behaviors() method of component class to which we want the behavior is being attached. The behaviors() method will return a list of behavior configurations which may contain a single behavior entry or multiple entries of behavior classes. In this example I used static approach, and attach the CustomerBehavior with override of behaviors() method. So the modified Customer class will become like this:

    <?php
    
    namespace app\components;
    
    use yii\base\Component;
    
    class Customer extends Component
    {
        public $name = "Muhammad Idrees";
    
        public function behaviors()
        {
      //return a list of behavior configurations
            return [
                CustomerBehavior::className()
            ];
        }
    }
    
  2. Dynamic attachment

    To attach a behavior dynamically to a component class, we have to call the yii\base\Component::attachBehavior() method of the component to which we want to attach the behavior. For example, to $customer object, we need to attach our newly defined CustomerBehavior, we have to call the attachBehavior() method as follows:

     // attach a behavior object
     $customer->attachBehavior('CustomerBehavior1', new CustomerBehavior);
    

    If you are using dynamic attachment of behaviors then you don't have to write the override behaviors() method in Customer class, attachBehavior() method will do the job.

Now we have defined desired behavior component, and also attached this behavior to the required component class. Now its time to actually use this behavior. Once a behavior is attached to a component, you can access the public members defined in the behavior through the component object:

 // "additionalProperty" a public property, defined in the CustomerBehavior class
 ECHO $customer->additionalProperty;

You can also call a public method of the behavior in the same way as it is a regular method defined within the original component class:

 // "additionalFunction" is a public function, defined in the CustomerBehavior class
 $customer->additionalFunction();

References:

http://www.yiiframework.com/doc-2.0/guide-concept-behaviors.html

No comments:

Post a Comment