Php 在symfony中使用表单上传图片

Php 在symfony中使用表单上传图片,php,doctrine,symfony-1.4,symfony-forms,Php,Doctrine,Symfony 1.4,Symfony Forms,我需要使用symfony上传图像,但我无法使用我的表单 简化模型为: Offer: columns: id: name: pic: flyer: description: . . . relations: Picture: local: pic foreign: id type: one Picture_2: class: Picture

我需要使用symfony上传图像,但我无法使用我的表单

简化模型为:

Offer:
  columns:
    id:
    name:
    pic:
    flyer:
    description:
      .
      .
      .
  relations:
    Picture:
      local: pic
      foreign: id
      type: one
    Picture_2:
      class: Picture
      local: flyer
      foreign: id
      type: one
Picture:
  columns:
    id:
    path:
    name:
      .
      .
      .
现在,我使用一个扩展OfferForm的表单,因为我需要我的表单有文件小部件,而不是“pic”和“flyer”字段的选择小部件。在保存过程中,我需要创建两个“Picture”实例,以创建与此报价关联的两个Picture对象

我还没有找到好的和完整的文件上传。。。或者至少对我来说不是。。。每个教程或文章都神奇地使用了
$form->save()
方法,一切都很顺利!,但是我在做这件事的时候犯了很多错误

这是我的表单类:

class myOfferForm extends OfferForm {

  protected $statusChoices = array(
                                   'A' => 'Active',
                                   'E' => 'Expired',
                                   );
  protected $validStatus = array('A','E');

  public function configure() {
    parent::configure();

    $this->setWidgets(array(
       'id'          => new sfWidgetFormInputHidden(),
       'name'        => new sfWidgetFormInputText(),
       'picFile'     => new sfWidgetFormInputFileEditable(array(
                             'file_src'     => $this->getObject()->getPicFileSrc(),
                             'is_image'     => true,
                             'with_delete'  => !is_null($this->getObject()->getPicFileSrc())
                                                               )),
       'flyerFile'   => new sfWidgetFormInputFileEditable(array(
                             'file_src'     => $this->getObject()->getFlyerFileSrc(),
                             'is_image'     => true,
                             'with_delete'  => !is_null($this->getObject()->getFlyerFileSrc())
                                                               )),
       'from'        => new sfWidgetFormDate(array(
                             'format'       => '%day%/%month%/%year%',
                             'can_be_empty' => false,
                             'default'      => date('Y/m/d')
                                                  )),
       'to'          => new sfWidgetFormDate(array(
                             'format'       => '%day%/%month%/%year%',
                             'can_be_empty' => false,
                             'default'      => date('Y/m/d')
                                                  )),
       'description' => new sfWidgetFormTextarea(),
       'status'      => new sfWidgetFormChoice(array(
                             'choices' => $this->statusChoices)),
       'products'    => new sfWidgetFormDoctrineChoice(array(
                             'model'        => 'Product',
                             'table_method' => 'getActivesOrderedByName',
                             'add_empty'    => 'Check associated products',
                             'multiple'     => true,
                                                             )
                                                       ),
    ));
    $this->widgetSchema->setLabels(array(
        'id'          => '',
        'name'        => 'Name *:',
        'picFile'     => 'Picture *:',
        'flyerFile'   => 'Flyer *:',
        'from'        => 'Valid From *:',
        'to'          => 'Valid To *:',
        'description' => 'Description :',
        'status'      => 'Status *:',
        'products'    => 'Associated Products :',
    ));
    $this->setValidators(array(
        'id'          => new sfValidatorChoice(array(
                             'choices' => array($this->getObject()->get('id')),
                             'empty_value' => $this->getObject()->get('id'),
                             'required' => false,
                                                     )),
        'name'        => new sfValidatorString(),
        'picFile'    => new sfValidatorFile(array(
                             'required'    => false,
                             'mime_types'  => 'web_images',
                             'path'        => WebPromocion::getStaticDirPath().'/',
                             'validated_file_class' => 'OfferValidatedFile',
                                                   )),
        'flyerFile'   => new sfValidatorFile(array(
                             'required'    => false,
                             'mime_types'  => 'web_images',
                             'path'        => WebPromocion::getStaticDirPath().'/',
                             'validated_file_class' => 'OfferValidatedFile',
                                                   )),
        'from'        => new sfValidatorDate(),
        'to'          => new sfValidatorDate(),
        'description' => new sfValidatorString(),
        'status'      => new sfValidatorChoice(array(
                             'choices' => $this->validStatus,
                             'required' => true,
                                                     )),
        'products'    => new sfValidatorDoctrineChoice(array(
                                                 'required' => false,
                                                 'model'    => 'Product',
                                                 'column'   => 'id',
                                                 'multiple' => true, )),
    ));
    $this->validatorSchema['fotoFile_delete'] = new sfValidatorPass();
    $this->validatorSchema['flyerFile_delete'] = new sfValidatorPass();
    $this->widgetSchema->setIdFormat('offer_form_%s');
    $this->widgetSchema->setNameFormat('offer[%s]');
  }
}
OfferValidatedFile类:

class OfferValidatedFile extends sfValidatedFile {
  /**
   * Generates a random filename for the current file, in case
   * it already exists.
   *
   * @return string A convenient name to represent the current file
   */
  public function generateFilename()
  {
    $filename = $this->getOriginalName().$this->getExtension($this->getOriginalExtension());
    if (file_exits(WebPromocion::getStaticDirSrc().$filename)) {
      return sha1($this->getOriginalName().rand(11111, 99999)).$this->getExtension($this->getOriginalExtension());
    } else {
      return $filename;
    }
  }
}
在我的行动中,我正在做的还有其他事情:

$this->form->save()
有一个问题。保存表单时,提供对象没有任何要关联的现有图片对象

我认为主要的问题是我想使用一个表单来处理与两个不同对象相关的信息提交

那么,我做错了什么?我没在做什么?有人知道我可以使用的关于这个主题的完整文档吗?有没有一种干净的symfonian方法可以做到这一点?

适用于您正在使用的Symfoni和doctrine版本。不幸的是,它们没有为您概述初始设置,而是包含一个安装程序脚本。请注意,对于版本1.4,此类型的设置在“”以及“”的其他部分的其他地方都有概述。幸运的是,在第一个链接中对重构脚本的表单类也有相当详细的介绍,我认为这对您也会有相当大的好处-它很好地解释了模型对表单的处理(您似乎遇到了问题),这可能会使调试对您来说不那么神秘


我建议好好读一读。几个月前,我在一个项目中遵循了这一点,并顺利完成了它。

我已经阅读了推荐的文档,它似乎正是我所需要的!!!我真的希望如此!,但是现在很晚了,我要睡觉了,呵呵,我明天再试试。。。同时,我接受这个答案!非常感谢你!!令人惊叹的!如果你在这方面有任何问题,请随意向我提问。