好吧,因为经常有许多方法去皮肤猫,但我会说为了保持DRY,为了方便测试,并且为了保持符合the recommended fat model concept,你应该把逻辑放在模型。
并且为了分离清理和异常处理,您可以使用event system,让可能需要清理的模型将他们自己作为听众(他们应该知道他们是否需要清理),并让自定义错误处理程序调度适当的事件,这样异常处理程序不需要知道应用程序内部。
这里有一些非常基本的,未经测试示例代码应该说明的想法:
<?php
App::uses('CakeEventManager', 'Event');
class ExampleModel extends AppModel
{
public $name = 'Example';
public function __construct($id = false, $table = null, $ds = null)
{
CakeEventManager::instance()->attach(array($this, 'cleanup'), 'AppErrorHandler.beforeHandleException');
parent::__construct($id, $table, $ds);
}
public function cleanup()
{
// do some magic
}
}
?>
<?php
App::uses('CakeEvent', 'Event');
App::uses('CakeEventManager', 'Event');
class AppErrorHandler extends ErrorHandler
{
public static function handleException(Exception $exception)
{
CakeEventManager::instance()->dispatch(new CakeEvent('AppErrorHandler.beforeHandleException', get_called_class(), array($exception)));
parent::handleException($exception);
}
}
?>
更新
为了能够到只有特定的异常反应,例如,您可以利用事件名称中的例外类名称,因此它会触发像...beforeHandleFooBarException
这样的事件,您可以明确订阅:
<?php
class AppErrorHandler extends ErrorHandler
{
public static function handleException(Exception $exception)
{
CakeEventManager::instance()->dispatch(new CakeEvent('AppErrorHandler.beforeHandle' . get_class($exception), get_called_class(), array($exception)));
parent::handleException($exception);
}
}
?>
<?php
class ExampleModel extends AppModel
{
public $name = 'Example';
public function __construct($id = false, $table = null, $ds = null)
{
$eventManager = CakeEventManager::instance();
$callback = array($this, 'cleanup');
$eventManager->attach($callback, 'AppErrorHandler.beforeHandleInvalidCallException');
$eventManager->attach($callback, 'AppErrorHandler.beforeHandleIncompleteCallException');
parent::__construct($id, $table, $ds);
}
public function cleanup()
{
// do some magic
}
}
?>
如果你将与通用的异常事件坚守,那么另一种选择将是检查的模型事件侦听器回调的异常的类型:
public function __construct($id = false, $table = null, $ds = null)
{
CakeEventManager::instance()->attach(array($this, 'beforeHandleException'), 'AppErrorHandler.beforeHandleException', array('passParams' => true));
parent::__construct($id, $table, $ds);
}
public function beforeHandleException($exception)
{
if($exception instanceof InvalidCallException ||
$exception instanceof IncompleteCallException)
{
$this->cleanup();
}
}
public function cleanup()
{
// do some magic
}
究竟什么是你的“清理”代码在做什么? – ndm
@ndm:从数据库中删除一些“死”的条目。 – nahri