CakePHP3:修改所有读取的实体

时间:2017-12-20 20:07:46

标签: php cakephp cakephp-3.0

我很难找到解决问题的最佳方法。我的Elements模型中有两个字段,例如filesfile_path。每当读取file_name字段时(无论是通过file_nameget()调用它,无论是JSON还是常规视图)我都希望被修改并返回两个字段(find())的连接。

我想在一个地方执行此操作以使代码DRY。我认为这样做的一种方法是文档中指定的实体的访问器方法,但访问器仅在通过对象表示法访问实体时才起作用,并且它们不与$file_name = $file_path .'/'.$file_name一起工作。

有没有办法在一个地方透明地做这件事(最好是模特)?我正在研究模型事件,但无法确定哪种事件在我的情况下会有用(看起来我需要像afterRead那样......)

这是我尝试的但是它没有与发现者合作:

find()

1 个答案:

答案 0 :(得分:2)

您已经为名为_getFileName($f)的实体添加了一个方法,它会改变您的数据。它没有按照你的想法做到。

关于Accessors和Mutators的CakePHP手册:

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

  

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

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

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

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

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

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

使用功能

我所做的就是让它变得简单。

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

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

支持序列化

如果需要用于序列化的自定义属性(即JSON)。上述功能方法不起作用。您需要使用virtual properties方法并使用不同的字段名称。这里的关键是虚拟属性不会与任何表列冲突。

class Document extends Entity {
     protected $_virtual = ['full_path'];

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

所以在上面的例子中我们使用的是 Accessor 函数。我们还将此 new 字段名称添加到$_virtual,以便CakePHP知道包含在JSON输出中。由于名为full_path的表模式中没有列,因此不会将其保留到数据库中。