cakephp3:所有读取中修改实体



我很难找出解决问题的最佳方法。我的files模型中有两个字段,例如file_pathfile_name。每当读取file_name字段时(无论是通过get()find()调用它,无论是JSON还是常规视图),我都希望将其修改并返回两个字段的con派($file_name = $file_path .'/'.$file_name)。

我想在一个地方这样做以使代码干燥。我认为这样做的一种方法将是文档中指定的实体的访问方法,但是只有在通过对象符号访问实体并且它们不使用find()时,配件才能使用。

是否有任何方法可以在一个地方透明地进行此操作(最好是模型)?我一直在研究模型事件,但无法弄清楚哪个事件在我的情况下会很有用(看来我需要诸如AfterRead ...)

之类的东西。

这是我尝试过的,但它与Finders无法使用:

namespace AppModelEntity;
use CakeORMEntity;
class File extends Entity
{
    protected function _getFileName($f)
    {
        return $this->file_path.''.$f;
    }
}

您已经在名为 _getFileName($f)的实体中添加了一种方法,它将突变您的数据。它没有做您认为的事情。

摘自CakePHP手册上的登录机和突变器:

https://book.cakephp.org/3.0/en/orm/entities.html#accessors-mutators

保存实体时将使用访问者,因此在定义格式数据的方法时要小心,因为格式化数据将被持续。

因此,当您保存实体时,file_name字段将被保存为$this->file_path.''.$f,并且每次保存时都会发生。

对于大多数CakePPP开发人员来说,这是一个非常令人困惑的问题。我会给您快速解释这些方法。

function _getXXXX()将值返回数据库中保存的值。当您返回不同的值时。这意味着存储在实体对象中的值不是您想要在数据库中存储的值。这可以欺骗人们,因为他们在视图中看到了更新的值。因此,他们认为它用于格式化。

function _setXXXX()将值返回为分配的返回到实体对象。当您执行此$entity->title = 'FooBar';时,实体将调用_setTitle("FooBar"),并将返回的值用作分配给实体的title值。同样,这将是在数据库中保存的

你知道。两种方法都会更改数据库中存储的内容。

使用功能

我要做的是使它变得简单。

public function getFullFileName() {
     return $this->file_path.' '.$this->file_name;
}

在您的视图中,只需调用函数echo $entity->getFullFileName()

支持序列化

如果您需要用于序列化的自定义属性(即JSON)。以上功能方法无法正常工作。您需要使用虚拟属性方法并使用不同的字段名称。这里的关键是虚拟属性不会与任何表列相撞。

class Document extends Entity {
     protected $_virtual = ['full_path'];
     public function _getFullPath() {
           return $this->file_path.' '.$this->file_name;
     }
 }

因此,在上面的示例中,我们使用的是 concepor 函数。我们还向$_virtual添加了此 new 字段名称,以便CakePHP知道将包括在JSON输出中。由于名为full_path的表模式中没有列,它不会持续到数据库。

最新更新