【问题标题】:What is the difference between trait and behavior in cakephp 3?cakephp 3中的特征和行为有什么区别?
【发布时间】:2015-05-23 06:58:44
【问题描述】:

我在 cakephp 3 中发现了通过特征实现的软删除。我尝试通过行为来实现它。但与 trait 版本不同的是,SoftDeleteBehavior 不起作用。 我的模型初始化方法中有这一行:

$this->addBehavior('SoftDelete');

这是我的 SoftDeleteBehavior

namespace App\Model\Behavior;

use Cake\ORM\Behavior;
use Cake\ORM\RulesChecker;
use Cake\Datasource\EntityInterface;
use App\Model\Behavior\MyQuery;

class SoftDeleteBehavior extends Behavior {

public $user_id = 1;

public function getDeleteDate() {
    return isset($this->deleteDate) ? $this->deleteDate : 'deleted';
}

public function getDeleter() {
    return isset($this->deleter) ? $this->deleter : 'deleter_id';
}

public function query() {
    return new MyQuery($this->connection(), $this);
}

/**
 * Perform the delete operation.
 *
 * Will soft delete the entity provided. Will remove rows from any
 * dependent associations, and clear out join tables for BelongsToMany associations.
 *
 * @param \Cake\DataSource\EntityInterface $entity The entity to soft delete.
 * @param \ArrayObject $options The options for the delete.
 * @throws \InvalidArgumentException if there are no primary key values of the
 * passed entity
 * @return bool success
 */
protected function _processDelete($entity, $options) {
    if ($entity->isNew()) {
        return false;
    }

    $primaryKey = (array)$this->primaryKey();
    if (!$entity->has($primaryKey)) {
        $msg = 'Deleting requires all primary key values.';
        throw new \InvalidArgumentException($msg);
    }

    if (isset($options['checkRules']) && !$this->checkRules($entity, RulesChecker::DELETE, $options)) {
        return false;
    }

    $event = $this->dispatchEvent('Model.beforeDelete', [
        'entity' => $entity,
        'options' => $options
    ]);

    if ($event->isStopped()) {
        return $event->result;
    }

    $this->_associations->cascadeDelete(
        $entity,
        ['_primary' => false] + $options->getArrayCopy()
    );

    $query = $this->query();
    $conditions = (array)$entity->extract($primaryKey);
    $statement = $query->update()
        ->set([$this->getDeleteDate() => date('Y-m-d H:i:s') , $this->getDeleter() => $this->user_id])
        ->where($conditions)
        ->execute();

    $success = $statement->rowCount() > 0;
    if (!$success) {
        return $success;
    }

    $this->dispatchEvent('Model.afterDelete', [
        'entity' => $entity,
        'options' => $options
    ]);

    return $success;
}

如果我使用 trait,SoftDeleteTrait 会以真实的方式工作。但是 SoftDeleteBehavior 不能正常工作!

【问题讨论】:

    标签: behavior cakephp-3.0 traits


    【解决方案1】:

    一个是 PHP 语言结构,另一个是编程概念。您可能想read upon what traits are,以便您了解这个问题,就目前而言,没有太大意义。此外,诸如“不起作用”之类的内容也不能作为正确的问题描述,请在未来更加具体。

    话虽如此,CakePHP 行为确实服务于水平代码重用的目的,类似于特征,而不是通过继承进行垂直重用。

    但是,即使它们在概念上有相似之处,您也不能像在代码中那样简单地交换它们,一个特征将被组合到使用它的类中,因此它就像它一样成为它的一部分直接写在类定义中,因此能够覆盖继承的代码,如Table::_processDelete() 方法,另一方面,行为是一个完全独立的类,它被实例化并作为依赖注入到表类中运行时,并且对其方法的调用是通过表类委托的(请参阅Table::__call()),除非表类中已经存在同名的方法,这在您的情况下意味着永远不会调用_processDelete()

    我建议您多学习一点 PHP/OOP 基础知识,因为这是相当基本的东西,只需查看源代码即可轻松解开。能够理解 CakePHP 代码库和使用的概念如何工作将使您的生活更轻松。

    【讨论】:

    • 谢谢@ndm。我每天都在学习,我努力提高自己。我阅读了文档。我几乎不工作。如果我没有成功,那么我会问我的问题:)
    • 您能指导我如何在行为中覆盖表的删除方法吗?我搜索了它。但我什么也没找到。
    • @anghazighermezi 正如我的回答中提到的,行为根本无法覆盖表方法。如果您想在调用 delete 时执行某些操作,则必须使用事件:book.cakephp.org/3.0/en/orm/…
    猜你喜欢
    • 2011-06-03
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 2017-04-15
    • 2016-04-05
    • 1970-01-01
    相关资源
    最近更新 更多