Php Yii 1.1.16中的观察者设计模式,附加事件处理程序和上升事件
在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';
<?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中可能吗?
- 我如何实现这一点?
- **是否有替代方案(除了在控制器操作中手动处理方法调用)**
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);