symfony2实战入门信息录入6:文件上传

上一章我们进行了CRUD的操作,很快速的实现了增删改查,是不是很简单呀。本章我们继续完善,增加上传功能以实现照片和简历的上传,为了适应上传的需求我们要调整一些东西,不要被调整的东西搞混乱呀,一定要认真阅读,很容易的哦!

第一步,为了适应上传的需要,我们要调整file和path字段,并调整相关联的变量名称和代码:

打开src\Nlc\InformationBundle\Entity\Employee.php,把以下代码

替换成

也就是说我们把原来的$photo替换成了$photopath,目的是来存储上传文件的路径到数据库。

 

第二步,在Doctrine中处理上传

在Doctrine处理文件上传整体思路是:(注意:具体操作和整体思路不是一一对应的)

  1. 表单提交(附件提交)
  2. 在入库或修改之前,获取上传文件信息并将路径信息入库(在PrePersist和PreUpdate事件中操作)
  3. 入库后将上传的文件移动到相应的路径完成上传步骤(在PostPersist和PostUpdate事件中操作)
  4. 删除信息时,本地附件也相应的清除(在PostRemove事件中操作)

下面我们一点一点操作:

1)首先添加photofile变量(获取上传的照片信息)和jlfile变量(获取上传的简历信息),并分别添加set和get方法,它的set和get方法和之前自动生成的略有不同,一定要注意。下面我们介绍不同在哪里?因为我们要获取上传文件的信息,在symfony2中方法是Entity中引入:

并在set和get中使用它来获取上传文件的信息,来看看新的代码:

以上还加了一些验证,来控制文件上传大小。

2)修改src\Nlc\InformationBundle\Form\EmployeeType.php

让表单能够正常显示上传控件。

006nlcupdateform

 

3)创建文件的唯一名称

添加一个唯一的编码,来重命名上传的文件和图片让他们有一个唯一的名称避免重复。

以上photouniqid(照片唯一名称)和jlfileuniqid(简历文件的唯一名称)不用创建get和set。

 

4)创建文件上传的相关路径

getRootDir()方法:获取web目录在硬盘上的路径,getUploadDir()方法:设置文件上传的相对路径。getUploadRootDir()方法:getRootDir()和getUploadDir()相加获得完整的上传路径;

 

5)添加唯一命名标识后,我们要添加重要的部分了HasLifecycleCallbacks来触发PrePersist、PreUpdate、PostPersist、PostUpdate、PostRemove。

 

要在入库前要在PrePersist、PreUpdate进行文件重命名并创建文件相对路径

好我们要上传文件了,在哪个步骤上传呢,应该在信息入库之后,我们调用PostPersist、PostUpdate来完成上传工作,代码来了很简单的哦!

$this->getPhotofile()主要判断图片是否进行了上传或者上传无误。$this->getPhotofile()->move()的意思是将上传的文件移动到指定的web指定的上传文件夹并把文件进行重命名。$this->setPhotofile(null);清空上传的文件信息。

 

6)删除信息时文件自动清除

7)下面来看一下完整的src\Nlc\InformationBundle\Entity\Employee.php文件,你的思路会更清晰:

很容易吧!下面我们调整一些上传后,模板显示的细节。

 

第三步,调整页面细节

需要调整两个页面

1)src\Nlc\InformationBundle\Resources\views\Employee\show.html.twig上传后会跳转到此页显示,我们要让照片能够显示出来、让简历能够下载,而不是只显示URL。

将此页面的

更改成

 

看看上传后这个页面的效果:

007nlcuploadshow

虽然很简单但是功能已经实现,后面我们再美化模板。

 

2)在调整一下列表页以免他报错

src\Nlc\InformationBundle\Resources\views\Employee\index.html.twig

更改成

剩余的页面细节,会在整体功能完成后,更换我们自己制作的模板时,整体调整,不要着急哦。所以说下面几章也不会将我们之前的模板渲染到这个程序中,只有最后完成了主要功能我们才会进行模板的渲染。

5 Comments

  1. 楼主辛苦了。

    从第一篇看到这里,不明白的是 sql语句执行错误了:
    INSERT INTO employeetable (name, age, sex, education, photopath, jlpath, createtime, updatetime, categoryid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)

    这里 数据库中是photo 和 file,可程序中改成photopath 和jlpath了 这难道要 php bin/console doctrine:schema:update –force?

    麻烦指点一下,谢谢

  2. 楼主,您好,我遇到了和leoric一样的问题?经过调试,我发现是因为 @ORM\PrePersist 这些事件没有生效,我用的是symfony2.8,现在还没解决,下面是我的简单的一个demo:

    entity中部分代码:

    <?php
    namespace Nlc\InformationBundle\Entity;
    use Doctrine\ORM\Mapping as ORM;
    /**
    * @ORM\Entity()
    * @ORM\HasLifecycleCallbacks()
    */
    class Adminuser
    {
    /**
    * @ORM\PrePersist
    */
    public function test(){
    dump(1);die;
    }
    }

    controller中部分代码:

    getDoctrine()->getManager();
    $adminuser = new Adminuser();
    $adminuser->setUsername(‘dave’);
    $adminuser->setPassword(‘123′);
    $em->persist($adminuser);
    $em->flush();
    return new Response();
    }
    }
    希望前辈您看到后能回复我一下,谢谢!

发表评论