我有一个PageController允许添加,编辑和删除页面。对于每个页面,我们可以上传一个单一的图像,我将使用作为横幅。我正在使用蛋糕安全哈希来更改文件名,但我不确定我是否正确地使用它。一些页面可能有相同的图像,所以,使用我下面的代码,删除或更新一个页面将删除所有其他页面的图像有相同的图像...
你能检查一下我下面的代码是否有意义,或者有什么方法可以改进它吗?
public function add()
{
$page = $this->Pages->newEmptyEntity();
if ($this->request->is('post'))
{
$page = $this->Pages->patchEntity($page, $this->request->getData());
if(!$page->getErrors()) {
$image = $this->request->getData('image_file');
$filename = $image->getClientFilename();
$filename = \Cake\Utility\Security::hash($image->getClientFilename(), 'sha1');
$image->moveTo(WWW_ROOT . 'img' . DS . 'pages' . DS . $filename);
$page->image = $filename;
}
if ($this->Pages->save($page))
{
$this->Flash->success(__('Your page has been created.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your page.'));
}
$this->set('page', $page);
}
/**
* Edit method
*
* @param string|null $id Page id.
* @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function edit($id)
{
$page = $this->Pages->get($id);
if ($this->request->is(['post', 'put']))
{
$this->Pages->patchEntity($page, $this->request->getData());
if(!$page->getErrors()) {
$oldImage = $page->image;
$image = $this->request->getData('image_file');
$filename = $image->getClientFilename();
$filename = \Cake\Utility\Security::hash($image->getClientFilename(), 'sha1');
$image->moveTo(WWW_ROOT . 'img' . DS . 'pages' . DS . $filename);
$page->image = $filename;
unlink(WWW_ROOT . 'img' . DS . 'pages' . DS . $oldImage);
}
if ($this->Pages->save($page))
{
$this->Flash->success(__('Your page has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your page.'));
}
$this->set('page', $page);
}
/**
* Delete method
*
* @param string|null $id Page id.
* @return \Cake\Http\Response|null|void Redirects to index.
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($id)
{
$page = $this->Pages->get($id);
if ($this->Pages->delete($page))
{
unlink(WWW_ROOT . 'img' . DS . 'pages' . DS . $page->image);
$this->Flash->success(__('The {0} page has been deleted.', $page->title));
return $this->redirect(['action' => 'index']);
}
}
谢谢你的帮助。
1条答案
按热度按时间wvmv3b1j1#
如果你真的不希望这种“* 在页面之间共享图像 *”的行为,那么你需要想出一个不同的命名/存储方案。例如,你可以使用UUID,重复的机会非常非常非常小(假设PHP使用的伪随机数生成器是好的)。
最重要的是,在保存文件名的数据库列上放置一个唯一的索引,并且只有在记录成功保存后才上传文件,这有助于避免PHP级别的争用条件问题。
当然,为了最大限度地减少代码在第一时间存储重复项的可能性,实现某种类型的重复检查策略也没有什么坏处,例如检查名称是否已经存在,如果存在,则会出错,并且可能会尝试先多次生成一个唯一的名称。为了进一步减少冲突的可能性,可以使用名称随时间变化的子文件夹。例如使用年和月。
快速和肮脏的例子:
尽管如此,您还应该考虑将此功能移到一个服务、一个behavior或表本身中。在**
afterSave
事件**中处理上载将允许在移动文件失败时自动回滚(这将触发异常)!