我正在上传一个图像,在存储图像时,我会设置文件名,如"assets/Uploads/54f092af271b9.png",但保存后,文件名字段会丢失一些部分。它变成了"assets/54f092af271b9.png",完全失去了"Uploads/"目录。这应该发生吗?
代码如下:
<?php
$img = new Image();
$baseName = pathinfo($file, PATHINFO_BASENAME);
$fileName = 'assets/Uploads/' . $baseName;
var_dump($fileName);
$img->Name = $baseName;
$img->Filename = $fileName;
$img->OwnerID = ($memberID = Member::currentUserID()) ? $memberID : 0;
$img->write();
var_dump($img->Filename); exit;
输出为:
assets/Uploads/54f092af271b9.pngassets/54f092af271b9.png'
有什么想法吗?
我能够用您提供的代码复制这个问题。经过一番挖掘,以下是我的发现。
这一切都始于File
类中的onAfterWrite
函数(Image
对其进行了扩展)。在调用write
之后激发(显然),它调用updateFilesystem
,其中此行使用getRelativePath
函数调用的结果设置Filename
属性。
在撰写本文时,getRelativePath
如下所示:
public function getRelativePath() {
if($this->ParentID) {
// Don't use the cache, the parent has just been changed
$p = DataObject::get_by_id('Folder', $this->ParentID, false);
if($p && $p->exists()) return $p->getRelativePath() . $this->getField("Name");
else return ASSETS_DIR . "/" . $this->getField("Name");
} else if($this->getField("Name")) {
return ASSETS_DIR . "/" . $this->getField("Name");
} else {
return ASSETS_DIR;
}
}
查看该代码,问题来自于在将记录写入DB时没有在记录中设置ParentID
,因此运行第二个条件,而不是返回ASSETS_DIR . "/" . $this->getField("Name")
的结果。
因此,这就是解决的问题,现在需要解决。Silverstepe想要一个父文件夹,你只需要给它一个。
幸运的是,Folder
类上有一个名为find_or_make
的小函数,它可以按照名称执行,要么在文件系统和数据库中找到文件夹记录,要么为您生成它。
注意:在我自己的测试中,虽然我有一个"Uploads"文件夹,但我没有相应的DB记录,所以这个函数为我写了一个返回的结果
然后,我用这个结果给我正在写入DB的图像一个ParentID
,它使第二个var_dump
返回与第一个相同的值。
这就是在调用write
:之前需要添加到代码中的全部内容
$parentFolder = Folder::find_or_make('Uploads');
$img->setParentID($parentFolder->ID);