好吧,因爲經常有許多方法去皮膚貓,但我會說爲了保持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