上传的文件不是在服务器上创建的

Uploaded file isn't created on the server

我正在尝试使用 Symfony2 上传文件,但虽然我在 return 或日志中没有收到任何错误,但上传的文件并未在服务器上创建。我正在使用虚拟小文本文件测试上传。

这是文档实体的代码,from the cookbook :

<?php

namespace Crm\EntiteBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Doc
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    public $name;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    public $path;

    /**
     * @Assert\File(maxSize="6000000")
     */
    private $file;

    private $temp;

    public function getAbsolutePath()
    {
        return null === $this->path
            ? null
            : $this->getUploadRootDir().'/'.$this->path;
    }

    public function getWebPath()
    {
        return null === $this->path
            ? null
            : $this->getUploadDir().'/'.$this->path;
    }

    protected function getUploadRootDir()
    {
        // the absolute directory path where uploaded
        // documents should be saved
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }

    protected function getUploadDir()
    {
        // get rid of the __DIR__ so it doesn't screw up
        // when displaying uploaded doc/image in the view.
        return 'uploads/docs';
    }

    /**
     * Sets file.
     *
     * @param UploadedFile $file
     */
    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';
        }
    }

    /**
     * Get file.
     *
     * @return UploadedFile
     */
    public function getFile()
    {
        return $this->file;
    }

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


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

        // if there is an error when moving the file, an exception will
        // be automatically thrown by move(). This will properly prevent
        // the entity from being persisted to the database on error
        $this->getFile()->move($this->getUploadRootDir(), $this->path);

        // check if we have an old image
        if (isset($this->temp)) {
            // delete the old image
            unlink($this->getUploadRootDir().'/'.$this->temp);
            // clear the temp image path
            $this->temp = null;
        }
        $this->file = null;
    }

    /**
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        $file = $this->getAbsolutePath();
        if ($file) {
            unlink($file);
        }
    }

}

这是我的(测试)控制器:

public function uploadAction(Request $request)
{
    $document = new Doc();
    $form = $this->createFormBuilder($document)
        ->add('name')
        ->add('file', 'file')
        ->add('submit','submit')
        ->getForm();

    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        $em->persist($document);
        $em->flush();

        return new Response();
    }

    return $this->render('CrmEntiteBundle:Form:upload.html.twig', array(
                'form' => $form->createView(),
    ));
}    

uploadAction 的路由:

crmentite_upload:
    path:   /upload
    defaults: { _controller: CrmEntiteBundle:Entite:upload }

这是(简单的)Twig:

<form {{ form_enctype(form) }} action="{{ path('crmentite_upload') }}" method="POST">
     {{ form_rest(form) }}
</form>

这里是HTML生成的:

<form enctype="multipart/form-data" action="/web/app_dev.php/upload" method="POST">
     <div class="form-group">
                    <span class="required" title="Ce champ est requis">*</span>
                    <label class="control-label required" for="form_name">Name</label>
                    <input type="text" id="form_name" name="form[name]" required="required" maxlength="255" class="form-control" />

    </div><div class="form-group">
                    <span class="required" title="Ce champ est requis">*</span>
                    <label class="control-label required" for="form_file">File</label>
        <div class="form-group"><div class="input-group"><span class="input-group-btn"><span class="btn btn-primary btn-file"><span class="glyphicon glyphicon-folder-open"></span>&nbsp;&nbsp;Parcourir&hellip; <input type="file" multiple></span></span><input type="text" class="form-control" readonly></div></div><!--div class="input-group col-md-10"><span class="input-group-btn"><span class="btn btn-primary btn-file"><span class="glyphicon glyphicon-folder-open"></span>&nbsp;Parcourir&hellip;<input type="file" id="form_file" name="form[file]" required="required"></span><input type="text" class="form-control" readonly></span></div-->

    </div><div><button type="submit" id="form_submit" name="form[submit]" class="btn btn">Submit</button></div>            <input type="hidden" id="form__token" name="form[_token]" class="form-control" value="p_JPyYzTR2Es37Eocp_X2WkG0GtrJUJH9_ZvyuEj29U" />
</form>

关于信息,我之前创建了 uploads/docs 文件夹,具有正确的权限,并且记录添加到文档 table。

upload函数returnNULL中的var_dump($this->getFile());exit();preUpload函数也一样。 $request->files 的转储是空的,作为 $_FILES 的转储。

在你的树枝上试试这个:

<form {{ form_enctype(form) }} action="{{ path('youruploadactionroutename') }}" method="POST">
     {{ form_rest(form) }}
</form>

我想可能是没有设置enctype。 您可能想尝试放入表单生成器

->add('file', 'file')

编辑:

输入字段没有表单的名称或 ID,这是 html 中的错误,更具体地说是 field.html.twig:

{% block file_widget -%}
    {% spaceless %}
        <div class="form-group">
            <div class="input-group">
                <span class="input-group-btn">
                    <span class="btn btn-primary btn-file">
                        <span class="glyphicon glyphicon-folder-open"></span>&nbsp;&nbsp;Parcourir&hellip; <input type="file" multiple>
                    </span>
                </span>
                <input type="text" class="form-control" readonly>
            </div>
        </div>
    {% endspaceless %}
{% endblock file_widget %}

更正:

{# with error #}
{% block file_widget -%}
    {% spaceless %}
        <div class="form-group">
            <div class="input-group">
                <span class="input-group-btn">
                    <span class="btn btn-primary btn-file">
                        <span class="glyphicon glyphicon-folder-open"></span>&nbsp;&nbsp;Parcourir&hellip; <input type="file" multiple {{ block('widget_attributes') }}>
                    </span>
                </span>
                <input type="text" class="form-control" readonly>
            </div>
        </div>
    {% endspaceless %}
{% endblock file_widget %}