我是php和symfony的新手 我在symfony 2.8中使用文件服务进行上传 我有两张桌子一个沙龙到很多档案
我可以在newaction中上传多个文件。 问题出现在我的SalonController的editAction上。
我想删除旧文件,以便在editfiles.html.twig中添加新文件。我尝试了一个foreach以获得这个数组...
你能帮帮我吗?这是错误
类型错误:传递给DefaultBundle \ Service \ FileService :: upload()的参数1必须是DefaultBundle \ Entity \ File的实例,Doctrine \ ORM \ PersistentCollection的实例,在/ var / www / html / salon中调用第131行的-beaute / src / SalonBundle / Controller / SalonController.php
堆栈跟踪集中在fileservice.php的第18行
公共函数上传(文件$文件= NULL,$型){
这是我的SalonController的新动作和编辑动作
class SalonController extends Controller
{ / ** *创建一个新的沙龙实体。 * * @Route(“/ new”,name =“salon_new”) * @Method({“GET”,“POST”}) * / public function newAction(Request $ request) { $这 - > denyAccessUnlessGranted( 'ROLE_SALON'); $ em = $ this-> getDoctrine() - > getManager(); $ salon = new Salon();
$options = array('role' => $this->getUser()->getRoles(), 'page' => 'add');
$form = $this->createForm( 'SalonBundle\Form\SalonType',$salon, $options);
$user = $this->getUser();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$uploadService = $this->get('app.file');
$myFiles = $form->get('file')->getData();
foreach($myFiles['path'] as $new_file) {
$file = new File();
$file->setPath($new_file);
$file->setSalon($salon);
$salon->addFile($file);
$uploadService->upload($file, 'salon');
$em->persist($file);
}
$user->setSalon($salon);
$salon->setEnable(false);
$em->persist($user);
$em->persist($salon);
$em->flush();
$this->get('email')->salon($salon);
return $this->redirectToRoute('salon_show', array('id' => $salon->getId()));
}
/** * Displays a form to edit an existing salon entity. * * @Route("/edit", name="salon_edit") * @Method({"GET", "POST"}) * @Security("has_role('ROLE_SALON')") */ public function editAction(Request $request) { $em = $this->getDoctrine()->getManager(); $user = $this->getUser(); $salon = $user->getSalon(); $deleteForm = $this->createDeleteForm($salon);
$options = array('role' => $this->getUser()->getRoles(), 'page' => 'edit');
$editForm = $this->createForm('SalonBundle\Form\SalonType', $salon, $options);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
// If new file
$edit_file = $editForm->get('edit_file')->getData();
if (!is_null($edit_file)) {
$file_current = $salon->getFiles();
$salon->getFiles($edit_file);
if (!$this->get('app.file')->upload($salon->getFiles(), 'salon'))
$salon->getFiles($file_current);
}
foreach($edit_file['path'] as $new_edit_file) {
$file = new File();
$file->setPath($new_edit_file);
$file->setSalon($salon);
$salon->addFile($file);
$this->get('app.file')->upload($file);
$em->persist($file);
}
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', 'Le partenaire a bien été modifié');
return $this->redirectToRoute('salon_show');
}
return $this->render('@Salon/salon/edit.html.twig', array(
'salon' => $salon,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
return $this->render('@Salon/salon/new.html.twig', array(
'salon' => $salon,
'form' => $form->createView(),
));
}
我SalonType的一部分
class SalonType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$page = $options['page'];
$builder
->add('name', TextType::class, array(
'label' => 'Nom du salon'
))
->add('content', TextareaType::class, array(
'label' => 'Descriptif'
))
->add('address_salon', AddressType::class, array(
'label' => ' '
))
;
if($page == 'add') {
$builder
->add('file', FileType::class, array(
'label' => 'Vous pouvez téléchargez jusqu\'à 3 images',
'required' => false,
'mapped' =>false,
));
}
if($page == 'edit') {
$builder
->add('edit_file', FileType::class, array(
'label' => 'Nouveau fichier',
'required' => false,
'mapped' => false
));
};
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SalonBundle\Entity\Salon',
'role' => null
));
$resolver
->setRequired(['page']);
}
My fileType
class FileType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('path', \Symfony\Component\Form\Extension\Core\Type\FileType::class, array(
'label' => 'Image',
'multiple' => true,
))
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => null,
));
}
}
My fileService
<?php
namespace DefaultBundle\Service;
use DefaultBundle\Entity\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileService {
private $directory_root;
private $directory_default;
public function __construct($directory_root, $directory_default) {
$this->directory_root = $directory_root;
$this->directory_default = $directory_default;
}
public function upload(File $file = null, $type) {
$path = $this->getDirectory($type);
if (is_null($file))
return false;
// Get file (Class UploadFile)
$file_uploaded = $file->getPath();
if ($file_uploaded->getError())
return false;
// Move file
$file_name = md5(uniqid()) . '.' . $file_uploaded->guessExtension();
$file_uploaded->move($this->directory_root . $path, $file_name);
// Update object file
$path .= '/' . $file_name;
$file->update($file_uploaded, $path);
return true;
}
public function delete(File $file){
$path = $this->directory_root.$file->getPath();
if(file_exists($path))
unlink($path);
}
private function getDirectory($type) {
switch ($type) {
default:
return $this->directory_default;
}
}
}
答案 0 :(得分:1)
你的代码有点混乱,我的意思是你的控制器中有很多逻辑: - )
只知道控制器中哪一行是131?
这里有错误(不知道是否为131行)
if (!$this->get('app.file')->upload($salon->getFiles(), 'salon'))
在这里你发送一个集合到upload()
,你自己说了
一个沙龙到多个文件
但在尝试修补此修改之前,请参阅教程here,了解如何处理多个文件上传。
此教程还提供full demo source code。代码很清楚,您应该能够轻松理解它。
修改强>
如果您不想重写代码,可能需要修改代码
if (!is_null($edit_file)) {
$file_current = $salon->getFiles();
//$salon->getFiles($edit_file); What is the goal of this?
foreach ($salon->getFiles() as $file) {
// Note that now we send a single File object not a collection
if (!$this->get('app.file')->upload($file, 'salon')) {
$salon->setFiles($file_current); // You want to set the files no?
break;
}
}
}
这是200%的丑陋,我甚至不确定它是否会起作用。你应该考虑重构你的代码。
修改2
您现在遇到的问题是您正在混合File
对象和symfony中的UploadedFile
对象。
你做$file_uploaded = $file->getPath();
然后你有错误
在字符串
上调用成员函数getError()
这是正常的,因为getPath()
会返回一个字符串。
我假设您已经查看了symfony doc的Uploader Service。您可以看到它们传递了UploadedFile
对象,该对象是symfony包的一部分,而不是自定义实体。
如果我想快速修复,这绝对不是我推荐的,我会做这样的事情
// Your controller (newAction)
foreach($myFiles['path'] as $new_file) {
// $new_file is an uploadedFile object, this is the file you want to upload
$file = new File();
$file->setPath($new_file);
$file->setSalon($salon);
$salon->addFile($file);
$uploadService->upload($file, $new_file, 'salon');
$em->persist($file);
}
// Your FileService
public function upload(File $file = null, UploadedFile $file_uploaded = null, $type) {
$path = $this->getDirectory($type);
if (is_null($file_uploaded) || is_null($file))
return false;
// Get file (Class UploadFile), No here you get the file path => a string
//$file_uploaded = $file->getPath();
if ($file_uploaded->getError())
return false;
//... end of your method
}