我們在用
Laravel
開發(fā)項目時常會用到軟刪除的功能随静,此篇文章將用Yii來實現(xiàn)相同的功能坷虑。
實現(xiàn)方式是基于Yii特性Behavior
來實現(xiàn)妄辩,首先建立一個SoftDeleteBehavior
的行為韵洋,如下:
<?php
/**
* IB - SoftDelete - do as Laravel
* User: Great Nomandia
* Date: 2018/12/3 23:38
*/
class SoftDeleteBehavior extends CActiveRecordBehavior
{
/**
* @var string 刪除時間字段
*/
public $deletedAttribute = 'deleted_at';
/**
* @var string 刪除狀態(tài)字段
*/
public $deletedStateAttribute = 'state';
/**
* @var int 刪除狀態(tài)值
*/
public $deletedStateValue = 9;
/**
* @var string
*/
public $timestampExpression;
/**
* @var array 映射數(shù)據(jù)庫(MySQL)字段類型對應的默認值
*/
protected static $map = array(
'datetime' => 'NOW()',
'timestamp' => 'NOW()',
'date' => 'NOW()',
'int' => 'UNIX_TIMESTAMP()',
);
/**
* @param CEvent $event
* @return bool
* @throws CException
* Author Nomandia
* Created At 2018/12/3 23:48
*/
function beforeDelete($event)
{
if ($this->getOwner()) {
if (null !== $this->deletedAttribute ) {
// 這里設置刪除時間字段
$this->getOwner()->{$this->deletedAttribute} = $this->getTimestampByAttribute($this->deletedAttribute);
}
if (null !== $this->deletedStateAttribute ) {
$this->getOwner()->{$this->deletedStateAttribute} = $this->deletedStateValue;
}
$this->getOwner()->update([$this->deletedStateAttribute, $this->deletedAttribute]);
$event->isValid = false; // 注意這需要設置false以阻止刪除行為執(zhí)行摹菠,true則表示實際刪除
return false;
}
}
/**
* 獲取刪除字段對應的列默認值
*
* @param string $attribute $attribute
* @return mixed timestamp (eg unix timestamp or a mysql function)
*/
protected function getTimestampByAttribute($attribute)
{
if ($this->timestampExpression instanceof CDbExpression)
return $this->timestampExpression;
elseif ($this->timestampExpression !== null) {
try {
return @eval('return ' . $this->timestampExpression . ';');
} catch (ParseError $e) {
return false;
}
}
$columnType = $this->getOwner()->getTableSchema()->getColumn($attribute)->dbType;
return $this->getTimestampByColumnType($columnType);
}
/**
* 返回列類型
*
* @param string $columnType $columnType
* @return mixed timestamp (eg unix timestamp or a mysql function)
*/
protected function getTimestampByColumnType($columnType)
{
return isset(self::$map[$columnType]) ? new CDbExpression(self::$map[$columnType]) : time();
}
}
使用起來也很簡單
class User extends CActiveRecord{
// other codes
function behaviors()
{
return array_merge([
['class' => 'SoftDeleteBehavior', 'deletedStateAttribute' => null], // 關閉了state更新
], parent::behaviors());
}
// other codes
}