Program Tip

단계별 Symfony2 파일 업로드

programtip 2021. 1. 10. 19:30
반응형

단계별 Symfony2 파일 업로드


저는 여전히 Symfony2를 배우고 있으며 파일 업로드 방법을 이해하지 못합니다.

걱정하지 마세요 . 이미 문서를 확인 했습니다 . 정말 좋지만 내 문제는 어떤 튜토리얼에서도 설명되지 않습니다.

Symfony2로 파일을 업로드하는 방법에 대한 지침을 찾고 있지만 모든 사람이 필요로하는 모든 것 (예 : 확장자 제한, ID 및 항목에 따른 파일 이름 변경, db에 경로 저장 등)

나는 좋은 튜토리얼을 찾았고 그것들을 혼합하려고했지만 성공하지 못했습니다. 다른 문제가 나타날 때마다 : 양식에 제출할 때마다 파일 다시 업로드 (파일 필드가 비어있는 경우에도), guessExtension 사용 불가, 올바른 경로 대신 데이터베이스에 저장된 tmp 경로, 파일 이동 안됨, 불가능 ID가 자동 증분이므로 아직 생성되지 않았기 때문에 이름 바꾸기에 ID를 사용했습니다.

그래서 저는 '표준'엔티티를 넣을 것입니다. Photo.php

/**
 * Photo
 *
 * @ORM\Table(name="photo")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Photo
{
    // Annotation for the id and auto increment etc
    private $id;

    /**
     * @var string
     * @Assert\File( maxSize = "3072k", mimeTypesMessage = "Please upload a valid Image")
     * @ORM\Column(name="image", type="string", length=245, nullable=false)
     */
    private $image

    private $title

    private $description

    // all the function get, set for the 4 previous variables
}

및 컨트롤러 :

public function addPhotoAction()
{
    $add_photo = new Photo;
    $formBuilderPhoto = $this->createFormBuilder($add_photo);
    $formBuilderPhoto
        ->add('title','text',array('label'  => 'Title of the photo', 'required' => true))
        ->add('image','file', array('required' => true, 'data_class' => null))
        ->add('description','textarea',array('label' => 'Description of your photo', 'required' => false))
    ;

    $form_photo = $formBuilderPhoto->getForm();

    if ($request->getMethod() == 'POST') {
        $form_photo->bind($request);
        if ($form_photo->isValid()) {
            // ...
        }
    }
    return $this->render('MyBundle:frontend:photo.html.twig',
        array('form_photo' => $form_photo->createView())
    );
}

이제 사진을 업로드하고 이름을 바꿀 수 있도록 추가해야하는 '중요한'기능이 무엇인지 알고 있습니까?

업로드가 가능한지 확인하기 위해 확장 프로그램을 어떻게 확인합니까?

Symfony2로 그런 일을하는 실제 방법은 무엇입니까? 나는 당신을 위해 모든 것을 수행하는 많은 Bundle이 있다는 것을 알고 있지만 그것을하는 법을 배우고 프로세스를 이해하고 싶습니다.

파일 업로드 양식을 구현하고 Symfony2로 기능 이름을 바꾸는 '전통적인'방법은 무엇입니까?


이제 사진을 업로드하고 이름을 바꿀 수 있도록 추가해야하는 '중요한'기능이 무엇인지 알고 있습니까?

이를 수행하는 방법에 대한 공식 문서참조하십시오 . 간단한 파일 업로드에 대한 좋은 작업 예제가 있습니다. 또한 라이프 사이클 콜백에 대한 교리 문서를 확인하십시오 .

업로드가 가능한지 확인하기 위해 확장 프로그램을 어떻게 확인합니까?

각 브라우저에는 HTML 양식 유효성 검사가 있습니다. 요소 의 HTML 속성에 대해서는 이 질문참조하십시오 . 또한 Symfony2에서 다음 주석을 사용하여 업로드 된 파일 의 MIME 유형지정할 수 있습니다 .accept=""input

/**
 * @Assert\File(
 *     maxSize = "1024k",
 *     mimeTypes = {"application/pdf", "application/x-pdf"},
 *     mimeTypesMessage = "Please upload a valid PDF"
 * )
 */

번들을 사용하고 싶지 않더라도 파일 업로드를보다 쉽게 ​​해주는 KnpDoctrineBehavioursBundle 을 추천해야합니다 .


단계별 :

이미 문서를 읽었으므로 단계별 코드 예제를 제공합니다.

우선 엔티티가 필요합니다. 그것을 부르 자 Image:

/**
 * Class Image
 *
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks
 */
class Image extends BaseEntity
{

@ORM\HasLifecycleCallbacks주석에 유의하십시오 . 이것은 매우 중요하며 나중에 필요합니다. 우리는 모든 기본 필드를 만듭니다 ID. 또한 파일 경로를 저장할 필드가 필요합니다.

    /**
     * Image path
     *
     * @var string
     *
     * @ORM\Column(type="text", length=255, nullable=false)
     */
    protected $path;

그리고 하나는 이미지 자체입니다. 여기에서 이미지에 대한 유효성 검사도 정의합니다. 내 예에서 그것은 5M크고 정의 된 mimeTypes. 자명해야합니다. 그렇지 않으면 공식 문서 가 항상 도움이됩니다.

    /**
     * Image file
     *
     * @var File
     *
     * @Assert\File(
     *     maxSize = "5M",
     *     mimeTypes = {"image/jpeg", "image/gif", "image/png", "image/tiff"},
     *     maxSizeMessage = "The maxmimum allowed file size is 5MB.",
     *     mimeTypesMessage = "Only the filetypes image are allowed."
     * )
     */
    protected $file;

Add all the Getters & Setters and update your database schema with this command:

php app/console doctrine:schema:update --force

Next we need the lifecycles. They are methods in the Entity that are called on certain events. For example the @ORM\PreUpdate() annotation before a method says that this method is being called right before the entity gets updated.

/**
 * Called before saving the entity
 * 
 * @ORM\PrePersist()
 * @ORM\PreUpdate()
 */
public function preUpload()
{   
    if (null !== $this->file) {
        // do whatever you want to generate a unique name
        $filename = sha1(uniqid(mt_rand(), true));
        $this->path = $filename.'.'.$this->file->guessExtension();
    }
}

Before the entity gets stored or updated this method is called. You can use it to e.g. generate a unique file name.

/**
 * Called before entity removal
 *
 * @ORM\PreRemove()
 */
public function removeUpload()
{
    if ($file = $this->getAbsolutePath()) {
        unlink($file); 
    }
}

Called before the entity gets removed. This gives you time to delete the image from your folders or log a message if you want to.

/**
 * Called after entity persistence
 *
 * @ORM\PostPersist()
 * @ORM\PostUpdate()
 */
public function upload()
{
    // The file property can be empty if the field is not required
    if (null === $this->file) {
        return;
    }

    // Use the original file name here but you should
    // sanitize it at least to avoid any security issues

    // move takes the target directory and then the
    // target filename to move to
    $this->file->move(
        $this->getUploadRootDir(),
        $this->path
    );

    // Set the path property to the filename where you've saved the file
    //$this->path = $this->file->getClientOriginalName();

    // Clean up the file property as you won't need it anymore
    $this->file = null;
}

This is the important part where your file is actually moved to the right directory. Note that I have used some additional methods. You can all get them from the official docs.

Next thing you need is a form. The form class itself is very simple. Just make sure you set the default data_class like this:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(
        array(
            'data_class' => 'FSchubert\SiyabongaBundle\Entity\Image',
       )
    );
}

A file upload field can be created very easily in the buildForm() method:

$builder->add('file', 'file');

The methods for your Controller are a little long for just pasting them here and IMHO it's not part of answering your question. There are countless examples out there for writing a proper Controller Action for your purpose.


More things you have to keep in mind:

  • You need to give your app writing permissions to the folders you upload the files to. Although it seems obvious it can be annoying if you have multiple servers you run the application on.
  • There is an Image Constraint for your entity as well. You can find it here. But since you were talking about a file upload I used the File Constraint instead.
  • As I mentioned in the top of this post, there are many Bundles that handle all these things for you. Check them out if you want an easy life.

Edit:

  • Changed from DoctrineExtensionsBundle to DoctrineBehaviours since development on the old one stopped in favour of the DoctrineBehaviours bundle.

I recommend you to use vlabs media bundle.


The VichUploaderBundle is also easy to use for uploading files:

https://github.com/dustin10/VichUploaderBundle

ReferenceURL : https://stackoverflow.com/questions/17951294/symfony2-file-upload-step-by-step

반응형