YII events

1, 创建一个事件类, 继承自ModelEvent,
2, $model->onNewComment($event);
3, model里的onNewComment其实就是$this->raiseEvent('onNewComment', $event);
4, event的实现类。
5, controller附加事件句柄 $post->onNewComment = array(‘event实现类’, 'comment');

----------------------

但其实流程是这样子的:
1, 在控制器里$this->onEventName= [object, method], 这时候应该是把eventNaem, handler放入了$component->_e[], 先把这个东西定义在这。
2, 然后控制器会调用Model类, model类会去调用某个方法, 方法里会调用onEventName方法, oneventname真的就是一个方法, 里面会去激活raiseEvent,
3, 在这个raiseEvent里面会去call_user_func, 以前定义的东西被调用了

 

==================================================================================================================

行为Behavior

行为是 [[yii\base\Behavior]] 或其子类的实例。行为,也称为 mixins,可以无须改变类继承关系即可增强一个已有的 [[yii\base\Component|组件]] 类功能。当行为附加到组件后,它将“注入”它的方法和属性到组件,然后可以像访问组件内定义的方法和属性一样访问它们。此外,行为通过组件能响应被触发的事件,从而自定义或调整组件正常执行的代码。

在行为内部可以通过 [[yii\base\Behavior::owner]] 属性访问行为已附加的组件。

与 PHP traits 的比较

尽管行为在 "注入" 属性和方法到主类方面类似于 traits ,它们在很多方面却不相同。如上所述,它们各有利弊。它们更像是互补的而不是相互替代。

行为的优势

行为类像普通类支持继承。另一方面,traits 可以视为 PHP 语言支持的复制粘贴功能,它不支持继承。

行为无须修改组件类就可动态附加到组件或移除。要使用 traits,必须修改使用它的类。

行为是可配置的而 traits 不能。

行为以响应事件来自定义组件的代码执行。

当不同行为附加到同一组件产生命名冲突时,这个冲突通过先附加行为的优先权自动解决。而由不同 traits 引发的命名冲突需要通过手工重命名冲突属性或方法来解决。

traits 的优势

traits 比起行为更高效,因为行为是对象,消耗时间和内存。

IDE 对 traits 更友好,因为它们是语言结构。


首先附加一个Behavior类 class MyBehavior extends Behavior

Behavior一般用在 class User extends ActiveRecord 类上来附加,
附加的方式:
behaviors方法, 可以通过配置去附加行为,

 

==================================================================================

 qqin2@qqin2-VirtualBox:/var/www/html/acuvue/yii/yii$ ./yii
qinqiu is here
This is Yii version 2.0.40.

The following commands are available:

- asset                        Allows you to combine and compress your JavaScript and
                               CSS files.
    asset/compress (default)   Combines and compresses the asset files according to
                               the given configuration.
    asset/template             Creates template of configuration file for
                               [[actionCompress]].

说明在yii文件里面加上shell bang头就可以运行 php 命令了.
可以在里面打印的

 

======================================================

 qqin2@qqin2-VirtualBox:/var/www/html/acuvue/yii/yii$ php -r  "var_dump(__DIR__);"
Command line code:1:
string(28) "/var/www/html/acuvue/yii/yii"
qqin2@qqin2-VirtualBox:/var/www/html/acuvue/yii/yii$ php -r  "var_dump(dirname(__DIR__));"
Command line code:1:
string(24) "/var/www/html/acuvue/yii"

说明__DIR__就是当前目录的目录名
dirname(__DIR__) 就是当前目录的上一级目录名

=========================================================

 ActiveRecord, 侧重在数据库操作, 数据的获取
model, 侧重在错误逻辑的验证,

=========================================================

 Yii::setAlias('@webroot', dirname($request->getScriptFile()));
Yii::setAlias('@web', $request->getBaseUrl());

这个在appBundle里面有使用

========================================================

  //way to use

return Yii::$app->db->cache( function(){ $query = new Query(); return $query->all(); }, 0, new TagDependency(['tags'=>'cache_table_1']));

//way to flush when modify table

TagDependency::invalidate(Yii::$app->cache, 'cache_table_1');

=======================================================

CActiveRecord scenarios

CActiveRecord sets a number of scenarios internally, any rules you set are validated against these scenarios depending on what operation is performed.

1. Insert

All instances of CActiveRecord instantiated via the constructor with the new keyword are set to this scenario by default. Any rules with the scenario will only be validated on database insert (first call to the save() method).

2. Update

All instances of CActiveRecord instantiated via the find() methods are set to this scenario by default. Any rules with the scenario will only be validated on database updates (subsequent calls to the save() method).

3. Search

This is not used internally but it is worth a mention as all the Gii generated model and crud code uses the 'search' scenario. The models generated by Gii create a rule like:

 

=====================================================

 public function beforeAction($action) {

  if($action->id =='ignore' || $action->id =='accept') {

  $this->enableCsrfValidation = false;

} //return true;

return parent::beforeAction($action);

 

}

=====================================================

 public function behaviors()
{
return [];
}

Yii就是从Component开始有behaviors方法的

=====================================================

 如何 migrate 单个数据表格

./yii migrate/create extend_status_table_for_slugs
Yii Migration Tool (based on Yii v2.0.1)
 
Create new migration '/Users/Jeff/Sites/hello/migrations/m150128_214906_extend_status_table_for_slugs.php'? (yes|no) [no]:yes
New migration created successfully.
 
./yii migrate/(extend_status_table_for_slugs)
() 里面其实就是文件名的一部分
====================================================================
 
behavior有三种功能
前提: 所有从components里面extend出来的, 当定义了behaviors这个函数的时候,就会被加载, 并放到当前的controller或者model类的对象上
1, behavior里面定义的方法/属性会被挂载到某个数组或者当前对象上, 方便可能的调用
2, behavior定义events方法, 可以绑定针对事件的代码, 本来behavior类就有一个方法是events(), 用于绑定的
3,
 
====================================================================
 当log配置的时候, 会配置一个categories, 这个会在实际的使用中被使用, 可以把日志写到不同的文件下。
====================================================================
scalar() 方法和 find() 方法有啥区别呢?
 一个直接返回order_status的数值, 比如:50
一个返回的结果$order_status是OrderModel的一个实例,那个数值50需要用$order_status->order_status来取

find()和scalar()这俩没有这与那的区别。
他俩需要配合才能完成一个正常的代码结果。注意是【配合】。
find()按照文档来说,是返回查询构造器。【查询构造器】是啥东西?这只是个半成品,还需要配合其它方法才能完成一个业务。比如获得一个模型,

OrderModel::find()->one();//这里find()配合one()方法获得了一个模型的实例。
OrderModel::find()->all();//这里find()配合all()方法获得了模型的所有实例。

回到find(),它是【查询构造器】,它和scalar如何配合呢?你去看看文档的这一篇吧:
https://www.yiichina.com/doc/guide/2.0/db-query-builder
希望你把整篇文章读一下,因为这是Yii2数据库操作的精髓。另外在文章里关注下scalar()如何配合就行了。

 =============================================

 对一个东西不太了解的情况下, 一个很轻微的动作就做了修改, 但其实, 改动大的很, 因为Yii是一种叫做配置型编程.

=============================================

 验证码很多时候不能显示, 这个时候是环境的问题,
https://blog.51cto.com/u_6251121/2377641
这个文章就很清楚的讲了这个事情

 

=============================================

acess 里面的类是可以配置的, 基本上可以配置很多东西了.

类是可以被override extend的 基本上全在custom的范围内了

=============================================

 

<?php foreach($managers as $manager): ?>
    <tr>
        <td> <?php echo $manager->adminid; ?> </td>
        <td><?php echo $manager->adminuser; ?></td>
        <td><?php echo $manager->adminemail; ?></td>
        <td> <?php echo date('Y-m-d H:i:s', $manager->logintime); ?></td>
        <td><?php echo long2ip($manager->loginip); ?></td>
        <td><?php echo date("Y-m-d H:i:s", $manager->createtime); ?></td>
        <td class="align-right">

              <?php if ($manager->adminid != 1): ?>
                <a href="<?php echo yii\helpers\Url::to(['manage/del', 'adminid' => $manager->adminid]) ?>">删除</a>
             <?php endif; ?>

        </td>
   </tr>
<?php endforeach; ?>

=============================================

关于behavior的小测试

behavior这个属性/方法是在 controller 类里面的, 或者是extend component下面的, 就可以了

一般在controller里面的

$behaviors['xxx'] = [
'class' => Qinqiu::class,
];

首先这个类要有attach方法, 没有attach方法也没有关系, 也可以只extend behavior这个类.
不然会报错

在controller中可以直接调用behavior类里面的方法

$this->method_in_behavior()
但这样的问题是没有代码提示, 比较的不友好。

于是有个变通就是 $this->behavior_name 加上注释, 就可以有代码提示了。

 /** @var $qinqiu Qinqiu */
$qinqiu = $this->xxx;
$qinqiu->point();
$qinqiu->circle();

behavior就是横切一点代码进去

 /** @var $qinqiu Qinqiu */

$qinqiu = $this->xxx->point();
$this->xxx是绝对不能用的
不然就抱500 internal server error

 

======================================

actions数组是前面覆盖后面的 array +,
如果actions没有返回[], 则rest里面会有好多个action。
会直接访问里面的actiion

======================================

event on

这个方法就是给某个类里面绑定一个事件, 把事件这个东西放到变量里面, 然后等着可能的被调用。

======================================

rule.php 里面的except对全部的actions都有效
======================================
 
yii\db\Connection.php
可以在phpstorm搜索这个
可以找到的, 就是说可以在 ctrl + n 可以按 类的 namespace 来找到
vendor\yiisoft\yii2-dev\framework\db\Connection.php
 
======================================
 Http报头分为通用报头,请求报头,响应报头和实体报头。
请求方的http报头结构:通用报头|请求报头|实体报头
响应方的http报头结构:通用报头|响应报头|实体报头

Accept代表发送端(客户端)希望接受的数据类型。

 比如:Content-Type:text/html(application/json) ;
代表发送端发送的数据格式是html(json)。

 

=======================================

 before action 和 after action是在 controller里面都会运行的方法,
是隐藏的代码。

可能会在不经意之间运行了

=======================================

public $model;
protected $modelClassName="";

class BaseServices extends Component

目前yii整个项目里面只有一个baseservices,

在这个地方, 几乎所有的类都来自于baseservices, 好像controller就没有extend, 但很多的类都extend了这个类,
于是只要extend baseservices, 然后定义 $modelClassName, 于是在new 这个类的时候,就会带出对象。

但这个对象基本上是默认生成的一个对象, 不是具体的哪一个对象。
==========================================

大胆的这么理解:
$this->on('事件名', '事件_handler');
同样的对象下就可以$this->trigger('事件名');
-------------------------
还有一种就是
event:on('类', '事件名', '事件handler')
之后这个类的对象就可以trigger('事件名')

这里面有个$event->sender 就是调用(trigger)的那个对象

=====================================================
yii里面component的功能主要是: on off trigger get set property之类的事情。
coursebase就继承自这个component

======================================================
// Create a dependency on the modification time of file example.txt.
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);

// The data will expire in 30 seconds.
// It may also be invalidated earlier if example.txt is modified.
$cache->set($key, $data, 30, $dependency);

// The cache will check if the data has expired.
// It will also check if the associated dependency was changed.
// It will return false if any of these conditions are met.
$data = $cache->get($key);

同时生效, 如果时间到了, 也会失效, 如果tag变了, 也会失效, 真的是太难了.
https://www.yiiframework.com/doc/guide/2.0/en/caching-data
==============================================================

asArray() query 有这样的一个方法,
只是为了让query对象的一个属性变成asArray=true
没有别的意思

==============================================================

我在action方法里抛出这个错误,
throw new Exception('are you ok');
这时会在 -- runtime logs下面看到这个消息

===============================================================

curl -i -H "Accept:application/json" -H "Content-Type:application/json" \
    -XPOST "http://localhost/users" \
    -d '{"username": "example", "email": "user@example.com"}'

-i 是显示表头
-h header信息
-XPOST 用什么方式来访问
-d 数据
-L 跳转到新的URL

==================================

http://localhost/users?page=2
http://localhost/users?fields=id,email
expand
http://localhost/users?sort=email
http://localhost/users?filter[id]=10
http://localhost/users?filter[email][like]=gmail.com


特殊参数可以访问到不同的信息

==================================
Arrayable is the interface that should be implemented by classes who want to support customizable representation of their instances.
也就是说 ArrayAble 只是一个定义, 没有具体的实现

==================================
yii\base\Model 貌似是主要处理 attributes, validation 之类的活, 具体的数据处理在 ActiveRecord

==================================
yii2 rest url 的 访问方式是:
【PUT HEAD GET POST】 域名+前缀+控制器名+数字, + {json数据}
就成了一个rest访问了。

public $patterns = [
'PUT,PATCH {id}' => 'update',
'DELETE {id}' => 'delete',
'GET,HEAD {id}' => 'view',
'POST' => 'create',
'GET,HEAD' => 'index',
'{id}' => 'options',
'' => 'options',
];

先要找到访问路径和actionXXX方法的对应关系, 然后才可以对症下药,
except对index也是有效的, 如果except index, 那么actionIndex也是访问不了的。
如果only[]也是有效的, 如果only[]不为空, 则只有only的下标可以被访问到, 不然是访问不到的。

===================================================