亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > PHP > 正文

Doctrine文件上傳處理例子

2024-09-04 11:45:12
字體:
來源:轉載
供稿:網友

Doctrine是基于數據庫抽像層上的ORM,它可以通過PHP對象輕松訪問所有的數據庫,例如MYSQL,它支持的PHP最低版本為5.2.3,下面我們一起來看看Doctrine文件上傳處理例子,希望文章對各位有幫助.

基本設置,創建一個簡單的Doctrine實體類:

  1. // src/Acme/DemoBundle/Entity/Document.php 
  2. namespace Acme/DemoBundle/Entity; 
  3.    
  4. use Doctrine/ORM/Mapping as ORM; 
  5. use Symfony/Component/Validator/Constraints as Assert; 
  6.    
  7. /** 
  8.  * @ORM/Entity 
  9.  */ 
  10. class Document 
  11.     /** 
  12.      * @ORM/Id 
  13.      * @ORM/Column(type="integer") 
  14.      * @ORM/GeneratedValue(strategy="AUTO") 
  15.      */ 
  16.     public $id
  17.    
  18.     /** 
  19.      * @ORM/Column(type="string", length=255) 
  20.      * @Assert/NotBlank 
  21.      */ 
  22.     public $name
  23.    
  24.     /** 
  25.      * @ORM/Column(type="string", length=255, nullable=true) 
  26.      */ 
  27.     public $path
  28.    
  29.     public function getAbsolutePath() 
  30.     { 
  31.         return null === $this->path 
  32.             ? null 
  33.             : $this->getUploadRootDir().'/'.$this->path; 
  34.     } 
  35.    
  36.     public function getWebPath() 
  37.     { 
  38.         return null === $this->path 
  39.             ? null 
  40.             : $this->getUploadDir().'/'.$this->path; 
  41.     } 
  42.    
  43.     protected function getUploadRootDir() 
  44.     { 
  45.         // the absolute directory path where uploaded 
  46.         // documents should be saved 
  47.         return __DIR__.'/../../../../web/'.$this->getUploadDir(); 
  48.     } 
  49.    
  50.     protected function getUploadDir() 
  51.     { 
  52.         // get rid of the __DIR__ so it doesn't screw up 
  53.         // when displaying uploaded doc/image in the view. 
  54.         return 'uploads/documents'
  55.     } 

該document實體有一個名稱與文件相關聯,這個path屬性存儲一個文件的相對路徑并且在數據庫中存儲,這個getAbsolutePath()會返回一個絕對路徑,getWebPath()會返回一個web路徑,用于模板加入上傳文件鏈接.

如果你還沒有這樣做的話,你應該閱讀http://symfony.com/doc/current/reference/forms/types/file.html首先了解基本的上傳過程.

如果您使用注釋來驗證規則(如本例所示),請確保你啟用了注釋驗證(見http://symfony.com/doc/current/book/validation.html#book-validation-configuration).

在處理一個實際的文件上傳時,使用一個“虛擬”的file字段,例如,如果你在controller中直接構建一個form,他可能是這樣的.

  1. public function uploadAction() 
  2.     // ... 
  3.    
  4.     $form = $this->createFormBuilder($document
  5.         ->add('name'
  6.         ->add('file'
  7.         ->getForm(); 
  8.    
  9.     // ... 

下一步,創建file這個屬性到你的Document類中并且添加一些驗證規則:

  1. use Symfony/Component/HttpFoundation/File/UploadedFile; 
  2.    
  3. // ... 
  4. class Document 
  5.     /** 
  6.      * @Assert/File(maxSize="6000000") 
  7.      */ 
  8.     private $file
  9.    
  10.     /** 
  11.      * Sets file. 
  12.      * 
  13.      * @param UploadedFile $file 
  14.      */ 
  15.     public function setFile(UploadedFile $file = null) 
  16.     { 
  17.         $this->file = $file
  18.     } 
  19.    
  20.     /** 
  21.      * Get file. 
  22.      * 
  23.      * @return UploadedFile 
  24.      */ 
  25.     public function getFile() 
  26.     { 
  27.         return $this->file; 
  28.     } 
  29. annotations 
  30. Annotations 
  31. // src/Acme/DemoBundle/Entity/Document.php 
  32. namespace Acme/DemoBundle/Entity; 
  33.    
  34. // ... 
  35. use Symfony/Component/Validator/Constraints as Assert; 
  36.    
  37. class Document 
  38.     /** 
  39.      * @Assert/File(maxSize="6000000") 
  40.      */ 
  41.     private $file
  42.    
  43.     // ... 

當你使用File約束,symfony會自動猜測表單字段輸入的是一個文件上傳,這就是當你創建表單(->add(‘file’))時,為什么沒有在表單明確設置為文件上傳的原因.

下面的控制器,告訴您如何處理全部過程:

  1. // ... 
  2. use Acme/DemoBundle/Entity/Document; 
  3. use Sensio/Bundle/FrameworkExtraBundle/Configuration/Template; 
  4. use Symfony/Component/HttpFoundation/Request; 
  5. // ... 
  6.    
  7. /** 
  8.  * @Template() 
  9.  */ 
  10. public function uploadAction(Request $request
  11.     $document = new Document(); 
  12.     $form = $this->createFormBuilder($document
  13.         ->add('name'
  14.         ->add('file'
  15.         ->getForm(); 
  16.    
  17.     $form->handleRequest($request); 
  18.    
  19.     if ($form->isValid()) { 
  20.         $em = $this->getDoctrine()->getManager(); 
  21.    
  22.         $em->persist($document); 
  23.         $em->flush(); 
  24.    
  25.         return $this->redirect($this->generateUrl(...)); 
  26.     } 
  27.    
  28.     return array('form' => $form->createView()); 

以前的controller當提交name自動的存儲Document實體,但是他不會做任何關于文件的事情并且path屬性也將是空白.

處理文件上傳一個簡單的方法就是在entity持久化之前設置相應的path屬性,在某一時刻處理文件上傳時,要調用Document實體類一個upload()方法給path賦值.

  1. if ($form->isValid()) { 
  2.     $em = $this->getDoctrine()->getManager(); 
  3.    
  4.     $document->upload(); 
  5.    
  6.     $em->persist($document); 
  7.     $em->flush(); 
  8.    
  9.     return $this->redirect(...); 

這個upload()方法利用UploadedFile對象,是它提交后返回file字段:

  1. public function upload() 
  2.     // the file property can be empty if the field is not required 
  3.     // 該file屬性為空這個屬性就不需要了 
  4.     if (null === $this->getFile()) { 
  5.         return
  6.     } 
  7.    
  8.     // use the original file name here but you should 
  9.     // sanitize it at least to avoid any security issues 
  10.     //  這里你應該使用原文件名但是應該至少審核它避免一些安全問題 
  11.     // move takes the target directory and then the 
  12.     // target filename to move to 
  13.     // 將目標文件移動到目標目錄 
  14.     $this->getFile()->move( 
  15.         $this->getUploadRootDir(), 
  16.         $this->getFile()->getClientOriginalName() 
  17.     ); 
  18.    
  19.     // set the path property to the filename where you've saved the file 
  20.     // 設置path屬性為你保存文件的文件名 
  21.     $this->path = $this->getFile()->getClientOriginalName(); 
  22.    
  23.     // clean up the file property as you won't need it anymore 
  24.     // 清理你不需要的file屬性 
  25.     $this->file = null; 

使用生命周期回調:

生命周期回調是一種有限的技術,他有一些缺點,如果你想移除Document::getUploadRootDir()方法里的寫死的編碼__DIR__,最好的方法是開始使用Doctrine listeners,在哪里你將能夠注入內核參數,如kernel.root_dir來建立絕對路徑.

這種原理工作,他有一個缺陷:也就是說當entity持久化時會有什么問題呢?答:該文件已經轉移到了它的最終位置,實體類下的path屬性不能夠正確的實體化.

如果entity有持久化問題或者文件不能夠移動,什么事情也沒有發生,為了避免這些問題,你應該改變這種實現方式以便數據庫操作和自動刪除文件:

  1. /** 
  2.  * @ORM/Entity 
  3.  * @ORM/HasLifecycleCallbacks 
  4.  */ 
  5. class Document 

接下來,利用這些回調函數重構Document類:

  1. use Symfony/Component/HttpFoundation/File/UploadedFile; 
  2.    
  3. /** 
  4.  * @ORM/Entity 
  5.  * @ORM/HasLifecycleCallbacks 
  6.  */ 
  7. class Document 
  8.     private $temp
  9.    
  10.     /** 
  11.      * Sets file. 
  12.      * 
  13.      * @param UploadedFile $file 
  14.      */ 
  15.     public function setFile(UploadedFile $file = null) 
  16.     { 
  17.         $this->file = $file
  18.         // check if we have an old image path 
  19.         // 檢查如果我們有一個舊的圖片路徑 
  20.         if (isset($this->path)) { 
  21.             // store the old name to delete after the update 
  22.             $this->temp = $this->path; 
  23.             $this->path = null; 
  24.         } else { 
  25.             $this->path = 'initial'
  26.         } 
  27.     } 
  28.    
  29.     /** 
  30.      * @ORM/PrePersist() 
  31.      * @ORM/PreUpdate() 
  32.      */ 
  33.     public function preUpload() 
  34.     { 
  35.         if (null !== $this->getFile()) { 
  36.             // do whatever you want to generate a unique name 
  37.             // 去生成一個唯一的名稱 
  38.             $filename = sha1(uniqid(mt_rand(), true)); 
  39.             $this->path = $filename.'.'.$this->getFile()->guessExtension(); 
  40.         } 
  41.     } 
  42.    
  43.     /** 
  44.      * @ORM/PostPersist() 
  45.      * @ORM/PostUpdate() 
  46.      */ 
  47.     public function upload() 
  48.     { 
  49.         if (null === $this->getFile()) { 
  50.             return
  51.         } 
  52.    
  53.         // if there is an error when moving the file, an exception will 
  54.         // be automatically thrown by move(). This will properly prevent 
  55.         // the entity from being persisted to the database on error 
  56.         //當移動文件發生錯誤,一個異常move()會自動拋出異常。 
  57.         //這將阻止實體持久化數據庫發生錯誤。 
  58.         $this->getFile()->move($this->getUploadRootDir(), $this->path); 
  59.    
  60.         // check if we have an old image 
  61.         if (isset($this->temp)) { 
  62.             // delete the old image 
  63.             unlink($this->getUploadRootDir().'/'.$this->temp); 
  64.             // clear the temp image path 
  65.             $this->temp = null; 
  66.         } 
  67.         $this->file = null; 
  68.     } 
  69.    
  70.     /** 
  71.      * @ORM/PostRemove() 
  72.      */ 
  73.     public function removeUpload() 
  74.     { 
  75.         $file = $this->getAbsolutePath(); 
  76.         if ($file) { 
  77.             unlink($file); 
  78.         } 
  79.     } 

如果更改你的entity是由Doctrine event listener 或event subscriber處理,這個 preUpdate()回調函數必須通知Doctrine關于正在做的改變,有關preUpdate事件限制的完整參考請查看 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#preupdate

現在這個類做了你需要的一切:他會在entity持久化之前生成一個唯一的文件名,持久化之后,移動文件,刪除文件.

現在移動文件是entity自動完成,這個$document->upload()就應該從controller中移除了:

  1. if ($form->isValid()) { 
  2.     $em = $this->getDoctrine()->getManager(); 
  3.    
  4.     $em->persist($document); 
  5.     $em->flush(); 
  6.    
  7.     return $this->redirect(...); 

這個@ORM/PrePersist()和@ORM/PostPersist()事件回調:一個是在entity持久化到數據庫之前觸發,一個是在entity持久化到數據庫之后觸發。另一方面, @ORM/PreUpdate() 和 @ORM/PostUpdate()事件回調時當實體更新時觸發。

當改變entity字段后進行持久化操作時,PreUpdate和PostUpdate回調才會被觸發。這意味著,默認情況下,你只改變了$file屬性,這些事件不會被觸發,因為這個屬性它自己不會持久化到Doctrine。有一個解決方法,就是創建一個updated字段把它持久化到Doctrine,并當文件改變時手動調整它。

使用ID作為文件名

如果要使用ID作為文件名,實現略有不同,您需要保存path屬性為文件擴展名,而不是實際的文件名:

  1. use Symfony/Component/HttpFoundation/File/UploadedFile; 
  2.    
  3. /** 
  4.  * @ORM/Entity 
  5.  * @ORM/HasLifecycleCallbacks 
  6.  */ 
  7. class Document 
  8.     private $temp
  9.    
  10.     /** 
  11.      * Sets file. 
  12.      * 
  13.      * @param UploadedFile $file 
  14.      */ 
  15.     public function setFile(UploadedFile $file = null) 
  16.     { 
  17.         $this->file = $file
  18.         // check if we have an old image path 
  19.         if (is_file($this->getAbsolutePath())) { 
  20.             // store the old name to delete after the update 
  21.             $this->temp = $this->getAbsolutePath(); 
  22.         } else { 
  23.             $this->path = 'initial'
  24.         } 
  25.     } 
  26.    
  27.     /** 
  28.      * @ORM/PrePersist() 
  29.      * @ORM/PreUpdate() 
  30.      */ 
  31.     public function preUpload() 
  32.     { 
  33.         if (null !== $this->getFile()) { 
  34.             $this->path = $this->getFile()->guessExtension(); 
  35.         } 
  36.     } 
  37.    
  38.     /** 
  39.      * @ORM/PostPersist() 
  40.      * @ORM/PostUpdate() 
  41.      */ 
  42.     public function upload() 
  43.     { 
  44.         if (null === $this->getFile()) { 
  45.             return
  46.         } 
  47.    
  48.         // check if we have an old image 
  49.         if (isset($this->temp)) { 
  50.             // delete the old image 
  51.             unlink($this->temp); 
  52.             // clear the temp image path 
  53.             $this->temp = null; 
  54.         } 
  55.    
  56.         // you must throw an exception here if the file cannot be moved 
  57.         // so that the entity is not persisted to the database 
  58.         // which the UploadedFile move() method does 
  59.         $this->getFile()->move( 
  60.             $this->getUploadRootDir(), 
  61.             $this->id.'.'.$this->getFile()->guessExtension() 
  62.         ); 
  63.    
  64.         $this->setFile(null); 
  65.     } 
  66.    
  67.     /** 
  68.      * @ORM/PreRemove() 
  69.      */ 
  70.     public function storeFilenameForRemove() 
  71.     { 
  72.         $this->temp = $this->getAbsolutePath(); 
  73.     } 
  74.    
  75.     /** 
  76.      * @ORM/PostRemove() 
  77.      */ 
  78.     public function removeUpload() 
  79.     {  //Vevb.com 
  80.         if (isset($this->temp)) { 
  81.             unlink($this->temp); 
  82.         } 
  83.     } 
  84.    
  85.     public function getAbsolutePath() 
  86.     { 
  87.         return null === $this->path 
  88.             ? null 
  89.             : $this->getUploadRootDir().'/'.$this->id.'.'.$this->path; 
  90.     } 

你會注意到,在這種情況下,你需要做一點工作,以刪除該文件,在數據刪除之前,你必須保存文件路徑(因為它依賴于ID),然后,一旦對象已經完全從數據庫中刪除,你就可以安全的刪除文件(在數據刪除之后).

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
7m第一福利500精品视频| 久久中文字幕在线视频| 亚洲美女免费精品视频在线观看| 亚洲一区二区三区久久| 欧美大片va欧美在线播放| 奇米4444一区二区三区| 国模吧一区二区| 欧美丝袜一区二区| 欧美亚洲国产另类| 成人精品一区二区三区| 精品久久久久久亚洲国产300| 国产精品精品视频一区二区三区| 成人精品一区二区三区电影免费| 欧美激情在线狂野欧美精品| 日韩精品福利网站| 日韩电影第一页| 亚洲视频在线观看视频| 欧美有码在线观看| 在线观看免费高清视频97| 国产一区二区丝袜| 欧美日韩午夜视频在线观看| 国产美女精彩久久| 欧美大秀在线观看| 日韩电视剧免费观看网站| 懂色av一区二区三区| 亚洲精品久久久久久久久久久| 91久久在线观看| 久久久国产精品一区| 高清欧美性猛交xxxx| 日韩免费精品视频| 国产日产欧美a一级在线| 久久国内精品一国内精品| 中文字幕在线亚洲| 7m精品福利视频导航| 亚洲免费电影一区| 中文字幕成人在线| 亚洲女人天堂色在线7777| 欧美亚洲午夜视频在线观看| 日韩高清不卡av| 欧美日韩国产第一页| 影音先锋欧美在线资源| 国产精品久久久久久久久久三级| 精品国产欧美成人夜夜嗨| 久久久91精品国产| 欧美一区二区三区……| 黑人精品xxx一区一二区| 日韩激情在线视频| 亚洲精品国产福利| 国产精品女人久久久久久| 日韩av在线天堂网| 久久免费视频这里只有精品| 国产一区二区美女视频| 国产精品亚洲自拍| 亚洲精品国产精品乱码不99按摩| 色多多国产成人永久免费网站| 欧美国产高跟鞋裸体秀xxxhd| 日本精品免费一区二区三区| 国产精品免费视频久久久| 欧美成在线视频| 欧美激情乱人伦| 国产成人av在线| 国产午夜精品久久久| 国产精品偷伦免费视频观看的| 国产日韩在线精品av| 亚洲欧美日韩图片| 亚洲欧美精品一区二区| 亚州av一区二区| 亚洲精品免费一区二区三区| 国产日韩欧美在线看| 成人免费网视频| 高清一区二区三区日本久| 日韩成人在线视频| 久久久久这里只有精品| 亚洲福利视频二区| 日韩在线高清视频| 欧美激情精品久久久久久变态| 国产亚洲aⅴaaaaaa毛片| 91精品一区二区| 丝袜亚洲欧美日韩综合| 欧美日韩一区二区免费在线观看| 欧美精品一本久久男人的天堂| 亚洲欧美日韩一区二区在线| 韩日欧美一区二区| 午夜精品99久久免费| 国产欧美精品一区二区| 国产免费一区视频观看免费| 欧美有码在线观看| 久久久久久久久国产精品| 国产精品视频午夜| 亚洲福利视频二区| 成人国产精品一区二区| 日韩精品视频在线播放| 亚洲精品天天看| 日韩国产精品亚洲а∨天堂免| 久久综合五月天| 欧美日韩另类视频| 欧美日韩成人黄色| 国产成人精品优优av| 国产视频精品一区二区三区| 亚洲欧美色图片| 97视频色精品| 久久久成人精品| 久久精品国产亚洲一区二区| 欧美日韩一区免费| 2019亚洲日韩新视频| 国产一区二区在线免费| 日韩精品在线观看网站| 成人黄色免费网站在线观看| 国产最新精品视频| 国产精品久久久久久久久免费看| 国产精品久久久久久久久男| 久久久精品美女| 精品动漫一区二区三区| 91av视频导航| 国自在线精品视频| 中文在线资源观看视频网站免费不卡| 亚洲四色影视在线观看| 97久久久免费福利网址| 久久99精品视频一区97| 日韩在线视频中文字幕| 精品国产一区二区三区久久| 国产拍精品一二三| 中文字幕亚洲专区| 国产色婷婷国产综合在线理论片a| 久久久久久久久久久久久久久久久久av| 国产精品视频1区| 中日韩午夜理伦电影免费| 日韩av在线天堂网| 高清视频欧美一级| 最近的2019中文字幕免费一页| 日韩免费在线看| 久久久久久久激情视频| 91wwwcom在线观看| 91在线色戒在线| 亚洲精品www久久久| 亚洲激情在线观看| 精品视频在线播放色网色视频| 久久久久久尹人网香蕉| 日本韩国在线不卡| 国产精品久久久久久久天堂| 久久久精品2019中文字幕神马| 狠狠色狠色综合曰曰| 亚洲人成欧美中文字幕| 亚洲午夜国产成人av电影男同| 欧洲日韩成人av| 国产美女久久精品香蕉69| 青青草一区二区| 17婷婷久久www| 色综合久久中文字幕综合网小说| 91免费看视频.| 日韩电影免费观看在线| 亚洲欧美日韩一区二区三区在线| 亚洲资源在线看| 欧美激情女人20p| 亚洲一区二区三区乱码aⅴ| 美女福利精品视频| 性欧美亚洲xxxx乳在线观看| 欧美激情亚洲国产| 欧美洲成人男女午夜视频| 亚洲国产精久久久久久久| 中文字幕日韩专区| 国产偷亚洲偷欧美偷精品| 亚洲亚裔videos黑人hd| 久久精品一区中文字幕|