我很难找到解决问题的最佳方法。我的files模型中有两个字段,例如file_path和file_name。每当读取file_name字段时(无论是通过get()、find()调用它,还是通过JSON还是常规视图),我都希望修改它并返回两个字段($file_name = $file_path .'/'.$file_name)的级联。
我想在一个地方这样做,使代码变干。我认为这样做的一种方法是文档中指定的实体的访问器方法,但是访问器只在通过对象表示法访问该实体并且它们不使用find()时才能工作)。
有没有办法透明地在一个地方(最好是一个模型)这样做?我在研究模型事件,但不知道在我的情况下哪个事件是有用的(看起来我需要一些类似afterRead的东西.)
这是我尝试过的,但它不适用于查找者:
namespace App\Model\Entity;
use Cake\ORM\Entity;
class File extends Entity
{
protected function _getFileName($f)
{
return $this->file_path.''.$f;
}
}发布于 2017-12-20 23:01:16
您已经向名为_getFileName($f)的实体中添加了一个方法,它将对数据进行变异。它不像你想的那样。
来自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)。上面的函数方法是行不通的。您需要使用虚拟属性方法并使用不同的字段名。这里的关键是,虚拟属性不会与任何表列发生冲突。
class Document extends Entity {
protected $_virtual = ['full_path'];
public function _getFullPath() {
return $this->file_path.' '.$this->file_name;
}
}因此,在上面的示例中,我们使用了访问器函数。我们还将这个新的字段名添加到$_virtual中,以便CakePHP知道将包含在JSON输出中。由于表模式中没有名为full_path的列,所以不会将其持久化到数据库。
https://stackoverflow.com/questions/47913646
复制相似问题