2014-10-22 1 views
2

문서를 통해 파일 다운로드가 구현되었습니다. 하지만 '복수'를 사용하기로 결정하면 오류가 발생합니다.Symfony 양식과 Doctrine을 사용한 여러 파일 업로드 처리

"Catchable Fatal Error: Argument 1 passed to Kulabuhov\MainBundle\Entity\Photo::setFile() must be an instance of Symfony\Component\HttpFoundation\File\UploadedFile, array given," 

Object 대신 배열을 전달했다는 것을 이해합니다. 하지만 문서에서 쓴 내용을 깨지 않고 여러 파일 업로드를 구현하는 방법은 무엇입니까?

$builder 
      ->add('file','file',['multiple'=>true]) 
      ->add('article') 
     ; 

답변

2
당신은 파일 이름 지정 규칙이 수행되는 방법을 접근하는 수십 가지 방법이 있기 때문에 도움이 될 것 교리와 파일 업로드 기능을 수행 한 방법으로 약간의 코드를 제공 한

, 플러스 당신은 천국 여러 파일 업로드 작업을 처리하는 엔티티를 수정하려는 시도를 실제로 보여 주긴했지만,이 사실을 알려줄 것입니다. 이것은 모든 지시 사항을 끝까지 따라했다고 가정합니다.

public function setFile(UploadedFile $file = null) 
{ 
    $this->file = $file; 
    // check if we have an old image path 
    if (isset($this->path)) { 
     // store the old name to delete after the update 
     $this->temp = $this->path; 
     $this->path = null; 
    } else { 
     $this->path = 'initial'; 
    } 
} 

하지만

물론, 당신은 UploadedFile 일치하지 않습니다 setFile 기능에 UploadedFile 객체의 배열을 제출 : 당신이 지시 사항을 준수 할 때

, 당신은 아마 같은 같은 setFile 기능을 생성 필요한 인수. 또한 경로에 대해 단일 문자열 만 저장하므로이를 수정해야합니다.

먼저 $path 변수 유형을 string에서 배열 유형으로 변경해야합니다.

/** 
* @ORM\Column(name="paths", type="simple_array") 
*/ 
private $paths = array(); 

그리고 지금 당신이 file 속성에 대한 선언 배열이 필요합니다 : 당신이 가정의 단지 simple_array을 고수하자, 그 어느에 더 쉼표가 없습니다 많은 각 파일과 관련된 데이터와 파일 이름 필요하지 않습니다 :

/** 
* @Assert\File(maxSize="60000000") 
*/ 
private $files = array(); 

는 이제 배열 입력을 처리하기 위해 setFile 기능을 변경해야합니다 (의 일관성을 위해 setFiles로 이름을 변경하자) :

public function setFiles($files) 
{ 
    $this->files = $files; 
    // In this scenario, we'll delete the old batch of uploads, so store it in $temp 
    if (!empty($this->paths)) { 
     $this->temp = $this->getAbsolutePaths(); 
    } 
    $this->paths = array(); 
} 

그리고 getFiles :

public function getFiles() 
{ 
    return $this->files; 
} 

이제 새로운 upload() 기능 : 삭제에 대해 다음

/** 
* @ORM\PostPersist() 
* @ORM\PostUpdate() 
*/ 
public function upload() 
{ 
    if (empty($this->files)) { 
     return; 
    } 

    // Now we have to iterate through each file object 
    foreach ($this->getFiles() as $file) { 
     // Change $tempPath to whatever random filename strategy you use 
     $tempPath = sha1(uniqid(mt_rand(), true)) . '.' . $file->guessExtension(); 
     $file->move(
      $this->getUploadRootDir(), 
      $tempPath 
     ); 
     // Now add it to the paths array 
     $this->paths[] = $tempPath; 
    } 

    // Need to delete all of the old files 
    foreach ($this->temp as $del) { 
     if (is_file($del)) { 
      unlink($del); 
     } 
    } 

    // Reset the $files var 
    $files = array(); 
} 

와는 완전히 모든 파일을 제거 :

/** 
* @ORM\PostRemove() 
*/ 
public function removeUpload() 
{ 
    foreach ($this->getAbsolutePaths() as $path) { 
     if (is_file($path)) { 
      unlink($path); 
     } 
    } 
} 

를 들어 당신이 작업 할 때 개체를 사용하면 이제 경로 배열을 처리하므로 yo를 업데이트해야합니다. UR 웹 및 절대 경로 기능뿐만 아니라 :

public function getAbsolutePaths() 
{ 
    $out = array(); 
    foreach ($this->getPaths() as $path) { 
     $out[] = $this->getUploadRootDir().'/'.$this->path; 
    } 
    return $out; 
} 

public function getWebPath() 
{ 
    $out = array(); 
    foreach ($this->getPaths() as $path) { 
     $out[] = '/' . $this->getUploadDir() . '/' . $this->path; 
    } 
} 

봐라 ... 당신이 빌더 대신 filefiles에 갈 업데이트하면, 제대로 여러 파일 업로드를 처리 할 수 ​​있어야합니다. 위의 코드가 인데도이 테스트되지 않았더라도이 코드를 사용하면 충분히 작업 할 수 있습니다.

+0

했나 Symfony \ Component \ HttpFoundation \ File \ File 클래스의 인스턴스이지만 (n) 배열입니다. "data_class"옵션을 null로 설정하거나 (n) 배열을 Symfony \ Component \ HttpFoundation \ File \ File의 인스턴스로 변환하는 뷰 변환기를 추가하여이 오류를 피할 수 있습니다 .' –

0

문제는 양식과 관련이 없으며 모델에 있습니다. PhotosetFile() 메서드는 배열이 아닌 UploadedFile을 수신합니다. 사진은, 여러 개의 파일을 OneToMany와 관계를 선언하고 배열을 받아들이는 setFiles() 기능을 구현하기위한 것입니다 경우 : 당신이 쓴, 그러나 양식의보기 데이터가 될 것으로 예상된다이 오류를 '가지고로

protected $files; 

function setFiles(array $files) 
{ 
    $this->files = $files; 

    return $this; 
} 
관련 문제