Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Yii 1.1.16中的观察者设计模式,附加事件处理程序和上升事件_Php_Yii_Yii Components - Fatal编程技术网

Php Yii 1.1.16中的观察者设计模式,附加事件处理程序和上升事件

Php Yii 1.1.16中的观察者设计模式,附加事件处理程序和上升事件,php,yii,yii-components,Php,Yii,Yii Components,在Yii中,1.1.16使用事件和行为实现(事件可以在扩展的所有组件之间共享)。我有以下型号: User.php(见下文) Work.php(见下文) Activity.php 我想做到的是: 让我们在DefaultController: <?php public function actionExampleWork() { $work = new Work(); $work->description = 'some random description';

在Yii中,1.1.16使用事件和行为实现(事件可以在扩展的所有组件之间共享)。我有以下型号:

  • User.php(见下文)
  • Work.php(见下文)
  • Activity.php
  • 我想做到的是: 让我们在DefaultController:

    <?php
      public function actionExampleWork()
      {
        $work = new Work();
        $work->description = 'some random description';
        $work->created_at = new CDbException('NOW()');
        $work->user_id = 1;
    
        //$work->attach() INVOKE EVENT that will be handled by all models which listen to this event
    
        $work->save();
     }
     public function actionExampleUser()
     {
        $user = new User();
        $user->email = 'foo@example.com';
        $user->username = 'example';
        $user->password = '123';
    
        //$user->attach( something ) invoke Event that should be handled only by Activity model
    
        $user-> save();
     }
    
    ?>
    
    
    
    事实上,我见过很多Yii做相关事情的例子,但到目前为止,还没有找到符合我需要的答案:(

    • 这在Yii中可能吗?
    • 我如何实现这一点?
    • **是否有替代方案(除了在控制器操作中手动处理方法调用)**
    User.php

    
    
    Work.php


    您的场景不需要观察员类

    使用内置事件处理程序 Yii模型类有一些内置函数,您可以在类中覆盖这些函数

    更多详情,请参阅CActiveRecord的官方文档。 提示:搜索XXXX之前、XXXX之后、XXXXX之后

    例如,这里是我的用户模型的预持久化处理程序

        /**
     * Runs just before the models save method is invoked. It provides a change to
     * ...further prepare the data for saving. The CActiveRecord (parent class)
     * ...beforeSave is called to process any raised events.
     *
     * @param <none> <none>
     * @return boolean the decision to continue the save or not.
     *
     * @access public
     */
    
    public function beforeSave() {
        // /////////////////////////////////////////////////////////////////////
        // Some scenarios only require certain fields to be updated. We handle
        // ...this separately.
        // /////////////////////////////////////////////////////////////////////
    if ($this->scenario == self::SCENARIO_LOGIN)
    {
        /** Login scenario */
        $this->last_login = new CDbExpression('NOW()');
    }
    
    if ($this->scenario == self::SCENARIO_ACTIVATION)
    {
        /** Account activation scenario */
    
        if ($this->activation_status == 'activated')
        {
            $this->activation_code = '';
            $this->status          = 'active';
            $this->activation_time = new CDbExpression('NOW()');
        }
    }
    
    if ( ($this->scenario == self::SCENARIO_CHANGE_PASSWORD) ||
         ($this->scenario == self::SCENARIO_REGISTER) ||
         ($this->scenario == 'insert') ||
         ($this->scenario == 'update')
       )
    {
        /** Password change scenario */
    
        // /////////////////////////////////////////////////////////////////////
        // Encrypt the password. Only do this if the password is set
        // /////////////////////////////////////////////////////////////////////
        if (isset($this->password) && (!empty($this->password)))
        {
            $this->password    =  CPasswordHelper::hashPassword($this->password);
    
        }
    }
    
    
    /** All other scenarios */
    
    // /////////////////////////////////////////////////////////////////////
    // Set the create time and user for new records
    // /////////////////////////////////////////////////////////////////////
    if ($this->isNewRecord) {
        $this->created_time = new CDbExpression('NOW()');
        $this->created_by   = '1';  // Special case for not logged in user
        $this->modified_by  = '1';
    }
    else
    {
        $this->modified_by   = isset(Yii::app()->user->id)?Yii::app()->user->id:1;
    }
    
    // /////////////////////////////////////////////////////////////////////
    // The modified log details is set for record creation and update
    // /////////////////////////////////////////////////////////////////////
    $this->modified_time = new CDbExpression('NOW()');
    
    return parent::beforeSave();
    }
    
    然后在你的控制器里

    $userModel->attachEventHandler('onNewUser',newuserEventHandler);
    
    function newuserEventHandler($event){
          // Add custom handling code here 
          do_some_things_here($event->new, $event->id);
        }
    
    在您的模型中,您需要引发事件

    $event=new NewUserEvent;
    // Add custom data to event.
    $event->new=$this->isNewRecord;
    $event->order=$this->id;
    $this->raiseEvent('onNewUser',$event);
    

    这应该有助于您更清楚地了解这一点。如果调用了用户模型中的事件,Yii将如何理解这一事实,而不是执行其他模型的方法?问题是:我想在
    User.php
    模型中调用全局事件,这将在所有模型中处理(
    Works.php
    ExampleModel.php
    …等),它们有特定的方法(从
    User.php
    model引发的handleGlobalEvent)对应于此事件。仍然混淆:(我认为Yii事件模型还不够成熟,无法处理这种情况。您仍然可以创建自定义事件,但必须手动引发事件。您必须手动管理工作单元。我更新了我的响应,以演示如何创建自定义事件。您可以在扩展CActiveRecord的组件中创建类并更改模型扩展该类。您的新父类可以包含可用于所有模型调用的已处理事件。
    class NewUser extends CModelEvent{
        public $userRecord;
    }
    
    $userModel->attachEventHandler('onNewUser',newuserEventHandler);
    
    function newuserEventHandler($event){
          // Add custom handling code here 
          do_some_things_here($event->new, $event->id);
        }
    
    $event=new NewUserEvent;
    // Add custom data to event.
    $event->new=$this->isNewRecord;
    $event->order=$this->id;
    $this->raiseEvent('onNewUser',$event);