2015-04-06 41 views
2

我有一個博客。平臺的形式(和反)文件,有了這個實體具有關聯Symfony2中的base64使用DataTransformer

  • 名稱
  • 圖標(小40的實體Category * 40 PNG)

的文件非常小,MIME類型放心總是PNG,我決定來存儲文件內容,在實體/數據庫Base64編碼字符串

通過這種方式,可以一次呈現頁面,而無需爲非常小的文件執行額外的請求(對於API調用GET /api/categories也是如此)。對於預加載的數據,它工作得很好。問題來了,當我要編輯一類

我創建了一個表格與文件類型圖標

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $transformer = new FileToBase64Transformer(); 

    $iconField = $builder->create('iconColor', 'file', ['required' => false]); 
    $iconField->addModelTransformer($transformer); 

    $builder 
     ->add('title') 
     ->add($iconField) 
    ; 
} 

數據變換器是

class FileToBase64Transformer implements DataTransformerInterface 
{ 
    public function transform($base64) 
    { 
     return null; 
    } 
    public function reverseTransform($file) 
    { 
     if (is_null($file)) { 
      return null; 
     } 

     return base64_encode(file_get_contents($file)); 
    } 
} 

但是當我提交形式與一個有效的圖像,形式失敗 在探查器中,在窗體部分我可以看到

Symfony\Component\Validator\ConstraintViolation Object(Symfony\Component\Form\Form).data.icon = THE_BASE_64_OF_THE_FILE

是否因爲數據在驗證發生之前轉換?

  • 如何修改此代碼,使其通過驗證
  • 東西,我需要換我的頭周圍是正在發生的事情,如果用戶上傳沒有新的形象出現時,我會編輯,哪有像被保存?
+0

爲什麼不BLOB作爲數據庫字段? – 2015-04-06 11:19:02

+0

@Paziツ最初的想法是避免每一次都重新轉換成base64(尤其是因爲API調用將在一次更新發生之前計入數十萬次),但是我目前正在考慮這條路徑 – 2015-04-06 11:23:36

+0

@Paziツ實際上它並沒有改變很多事情,它只是刪除了對base64_encode的調用,但仍然需要進行轉換(從File對象到「blob」)否? – 2015-04-06 11:52:07

回答

3

我的當前的解決方案是具有用於圖標兩個字段在我的實體

/** 
* @Constraints\Image(
*  maxWidth = 40, 
*  maxHeight = 40, 
*  allowSquare = true, 
*  mimeTypes = "image/png", 
*) 
*/ 
private $iconFile = null; 

/** 
* Base64 of the icon in color version 
* 
* @var string 
* 
* @ORM\Column(name="icon_color", type="text", nullable=true) 
*/ 
private $icon = null; 

(具有相應的吸氣劑和setter)

然後讓我的數據變換器對整個類分類

class FileToBase64Transformer implements DataTransformerInterface 
{ 
    /** 
    * Transforms an object (file) to a base64. 
    * 
    * @param $file 
    * @return string 
    */ 
    public function transform($channel) 
    { 
     return $channel; 
    } 

    /** 
    * reverse transforms 
    * 
    */ 
    public function reverseTransform($categoryl) 
    { 
     $iconFile = $category->getIconFile(); 
     if (!is_null($iconFile)) { 
      $channel->setIcon(
       base64_encode(file_get_contents($iconFile)) 
      ); 
     } 
     return $channel; 
    } 
} 

然後在我的CategoryType中將數據轉換器關聯到整個通道

/** 
* @param FormBuilderInterface $builder 
* @param array $options 
*/ 
public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $transformer = new FileToBase64Transformer(); 

    $builder 
     ->add('title') 
     ->add('theme_color') 
     ->add('type') 
     ->add('iconFile') 
     ->addModelTransformer($transformer) 
    ; 
} 

驗證仍然發生在數據轉換之後,但現在它不再是一個問題,因爲如果窗體是無效的實體將不會持續