yii2 行为 behavior (3) —— yii2启示录 [ 新手入门 ]
yii2 行为 behavior (1) —— yii2启示录 yii2 行为 behavior (2) —— yii2启示录 这里再举几个栗子
// backend\controllers\DreamController.php
<?php
namespace backend\controllers;
use Yii;
use yii\web\Controller;
use backend\libs\dream\Doraemon;
use backend\libs\dream\Bear;
use backend\libs\dream\MyClass;
use backend\libs\behaviors\Behavior1;
use backend\libs\behaviors\MyBehavior;
/**
* Site controller
*/
class DreamController extends Controller
{
/**
* Displays homepage.
*
* @return string
*/
public function actionIndex()
{
return '';
}
public function actionTa()
{
$bear = new Bear();
$behavior1 = new Behavior1();
$bear->attachBehavior('beh1',$behavior1);
//$doraemon->detachBehavior('beh1');
$bear->eat();
}
public function actionTb()
{
$doraemon = new Doraemon();
$doraemon->look();
$doraemon->eat();
$doraemon->height = '15cm';
echo $doraemon->height . PHP_EOL ;
$doraemon->trigger('wang');
}
public function actionTc()
{
$myClass = new MyClass();
$myBehavior = new MyBehavior();
// Step 3: 将行为绑定到类上
$myClass->attachBehavior('myBehavior', $myBehavior);
/**
* Step 4: 访问行为中的属性和方法,就和访问类自身的属性和方法一样
* yii\base\Component::__get()
* http://www.cnblogs.com/dragon16/p/5521199.html
* @param $name
* @return mixed
* 属性的注入
*
public function __get($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
return $this->$getter();
} else {
// 注意这个 else 分支的内容,正是与 yii\base\Object::__get() 的
// 不同之处
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
// 属性在行为中须为 public。否则不可能通过下面的形式访问呀。
return $behavior->$name;
}
}
}
if (method_exists($this, 'set' . $name)) {
throw new InvalidCallException('Getting write-only property: ' .
get_class($this) . '::' . $name);
} else {
throw new UnknownPropertyException('Getting unknown property: ' .
get_class($this) . '::' . $name);
}
}
*/
echo $myClass->property1;
/**
* yii\base\Component::__call
* 方法的注入
*
public function __call($name, $params)
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $object) {
if ($object->hasMethod($name)) {
return call_user_func_array([$object, $name], $params);
}
}
throw new UnknownMethodException('Calling unknown method: ' .
get_class($this) . "::$name()");
}
*/
echo $myClass->method1();
}
}
// backend\controllers\BehaviorController.php
<?php
/**
* Created by sallency.
* User: sallency
* Date: 2016/5/31 0031
* Time: 16:23
*/
namespace backend\controllers;
use backend\libs\behaviors\CtrlBehavior;
use yii\web\Controller;
class BehaviorController extends Controller
{
const PHP_WEB_EOL = "<br>";
public function init()
{
parent::init(); // TODO: Change the autogenerated stub
}
//绑定行为 静态绑定 还有 attachBehavior/attachBehaviors 动态绑定
public function behaviors()
{
return [
"ctrlBehavior" => [
"class" => CtrlBehavior::className(),
"param_1" => "hello",
"param_2" => "world"
]
];
}
public function actionIndex()
{
echo "组件访问行为的属性和方法:" . __METHOD__ . self::PHP_WEB_EOL;
//使用 __set __get 方法遍历访问行为队列 $_behaviors 中是否有行为对象包含以下属性
//有则通过此行为对象访问操作属性
echo "在行为中定义的属性:" . $this->param_1 . "\t" . $this->param_2 . self::PHP_WEB_EOL;
//使用 __call 方法遍历访问行为队列 $_behaviors 中是否有行为对象包含以下方法
//有则通过此行为对象访问方法
$this->extendMethodForCtrl();
$this->trigger(CtrlBehavior::EVENT_CTRL);
}
}
// backend\libs\behaviors\Behavior1.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2016/12/9
* Time: 11:02
*/
namespace backend\libs\behaviors;
use yii\base\Behavior;
class Behavior1 extends Behavior
{
public $height;
public function eat()
{
echo "heloo i am behavior1 !";
echo PHP_EOL;
}
public function events()
{
return [
'wang' => 'shout',
];
}
public function shout($event)
{
echo 'wang wang wang !';
}
}
// backend\libs\behaviors\CtrlBehavior.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2016/12/9
* Time: 21:24
*/
namespace backend\libs\behaviors;
use yii\base\Behavior;
use yii\base\Event;
use yii\rest\Controller;
class CtrlBehavior extends Behavior
{
const PHP_WEB_EOL = "<br>";
const EVENT_CTRL = 'ctrl' ;
public $param_1;
public $param_2;
/**
* 行为是为 Controller 做的扩展 故可以注册 Controller 的事件
* 重载events() 使得在事件触发时,调用行为中的一些方法
* @return array events for component owner
*/
public function events()
{
// EVENT_BEFORE_ACTION 事件触发时,调用成员函数 handlerBeforeAction
return [
Controller::EVENT_BEFORE_ACTION => "handlerBeforeAction",
Controller::EVENT_AFTER_ACTION => "handlerAfterAction",
self::EVENT_CTRL => "handerMyAction",
];
// 事件 handler("handlerBeforeAction") 可以是以下形式:
// 字符串,表示行为类的方法,如上面的例就是这种情况。
// 这个是与事件handler不同的,事件handler中使用字符串时,是表示PHP全局函数,而这里表示行为类内部的方法。
// 一个对象或类的成员函数,以数组的形式,如 [$object, 'methodName'] 。这个与事件handler是一致的。
// 一个匿名函数。
}
/**
* event handler
* 注意 handlerBeforeAction 是行为的成员函数,而不是绑定的类的成员函数。
* 还要注意,这个函数的签名,要满足事件handler的要求。
* @param \yii\base\Event $event
*/
public function handlerBeforeAction(Event $event)
{
echo __METHOD__ . self::PHP_WEB_EOL;
echo '由行为注册的组件事件,传递的$event->sender属性为此组件对象' . self::PHP_WEB_EOL;
echo "组件的控制器和动作:" . $event->sender->uniqueId . '/' . $event->sender->action->id . self::PHP_WEB_EOL;
echo self::PHP_WEB_EOL;
}
/**
* event handler
* @param \yii\base\Event $event
*/
public function handlerAfterAction(Event $event)
{
echo self::PHP_WEB_EOL;
echo __METHOD__ . self::PHP_WEB_EOL;
echo '由行为注册的组件事件,传递的$event->sender属性为此组件对象' . self::PHP_WEB_EOL;
echo "组件的控制器和动作:" . $event->sender->uniqueId . '/' . $event->sender->action->id . self::PHP_WEB_EOL;
}
public function handerMyAction(Event $event)
{
echo self::PHP_WEB_EOL;
echo __METHOD__ . self::PHP_WEB_EOL;
echo "组件的控制器和动作:" . $event->sender->uniqueId . '/' . $event->sender->action->id . self::PHP_WEB_EOL;
}
/**
* 扩展方法 通过 __METHOD__ 我么可以看出这货被组件调用时到底是不是组件的一个方法
*/
public function extendMethodForCtrl()
{
echo "在行为中定义的方法:";
echo __METHOD__ . self::PHP_WEB_EOL;
}
}
// backend\libs\behaviors\MyBehavior.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2016/12/9
* Time: 21:02
*/
namespace backend\libs\behaviors;
use yii\base\Behavior;
class MyBehavior extends Behavior
{
// 行为的一个属性
public $property1 = 'This is property in MyBehavior.'.PHP_EOL;
// 行为的一个方法
public function method1()
{
return 'Method in MyBehavior is called.'.PHP_EOL;
}
}
共 0 条回复
没有找到数据。
qiuxis
注册时间:2016-10-31
最后登录:2017-10-25
在线时长:22小时6分
最后登录:2017-10-25
在线时长:22小时6分
- 粉丝21
- 金钱215
- 威望40
- 积分835