2015-04-06 97 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) 
    ; 
} 

验证仍然发生在数据转换之后,但现在它不再是一个问题,因为如果窗体是无效的实体将不会持续