【问题标题】:Could not determine access type for property "file"无法确定属性“文件”的访问类型
【发布时间】:2017-05-03 22:32:59
【问题描述】:

我的图片上传有点问题,请您帮帮我:

无法确定属性“文件”的访问类型。

控制器

/**
 * Creates a new Produits entity.
 *
 */
public function createAction(Request $request)
{
    $entity = new Produits();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('adminProduits_show', array('id' => $entity->getId())));
    }

    return $this->render('EcommerceBundle:Administration:Produits/layout/new.html.twig', array(
        'entity' => $entity,
        'form'   => $form->createView(),
    ));
}

/**
 * Creates a form to create a Produits entity.
 *
 * @param Produits $entity The entity
 *
 * @return \Symfony\Component\Form\Form The form
 */
private function createCreateForm(Produits $entity)
{
    $form = $this->createForm(ProduitsType::class, $entity);

    $form->add('submit', SubmitType::class, array('label' => 'Ajouter'));

    return $form;
}

/**
 * Displays a form to create a new Produits entity.
 *
 */
public function newAction()
{
    $entity = new Produits();
    $form   = $this->createCreateForm($entity);

    return $this->render('EcommerceBundle:Administration:Produits/layout/new.html.twig', array(
        'entity' => $entity,
        'form'   => $form->createView(),
    ));
}

表格

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('file', FileType::class, array('data_class' => null))
    ->add('name', TextType::class)
    ;
}

/**
 * @param OptionsResolver $resolver
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Ecommerce\EcommerceBundle\Entity\Media'
    ));
}
/**
 * @return string
 */
public function getName()
{
    return 'ecommerce_ecommercebundle_media';
}

实体

    /**
 * @ORM\Column(name="name",type="string",length=255)
 * @Assert\NotBlank()
 */
private $name;

/**
 * @ORM\Column(type="string",length=255, nullable=true)
 */
private $path;

/**
 * @Assert\File(
 *     maxSize = "1024k",
 *     mimeTypes = {"image/png", "image/jpg", "image/bmp"},
 *     mimeTypesMessage = "Please upload a valid PDF"
 * )
 */
public $file;

public function getUploadRootDir()
{
    return __dir__.'/../../../../web/uploads';
}

public function getAbsolutePath()
{
    return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path;
}

public function getAssetPath()
{
    return 'uploads/'.$this->path;
}

/**
 * @ORM\PrePersist()
 * @ORM\PreUpdate()
 */
public function preUpload()
{
    $this->tempFile = $this->getAbsolutePath();
    $this->oldFile = $this->getPath();
    $this->updateAt = new \DateTime();

    if (null !== $this->file)
        $this->path = sha1(uniqid(mt_rand(),true)).'.'.$this->file->guessExtension();
}

/**
 * @ORM\PostPersist()
 * @ORM\PostUpdate()
 */
public function upload()
{
    if (null !== $this->file) {
        $this->file->move($this->getUploadRootDir(),$this->path);
        unset($this->file);

        if ($this->oldFile != null) unlink($this->tempFile);
    }
}

/**
 * @ORM\PreRemove()
 */
public function preRemoveUpload()
{
    $this->tempFile = $this->getAbsolutePath();
}

/**
 * @ORM\PostRemove()
 */
public function removeUpload()
{
    if (file_exists($this->tempFile)) unlink($this->tempFile);
}

/**
 * Get id
 *
 * @return integer
 */
public function getId()
{
    return $this->id;
}

public function getPath()
{
    return $this->path;
}

public function getName()
{
    return $this->name;
}

public function getFile()
{
    return $this->file;
}

/**
 * Set path
 *
 * @param string $path
 * @return String
 */
public function setPath($path)
{
    $this->path = $path;
    return $this;
}

/**
 * Set alt
 *
 * @param string $alt
 * @return String
 */
public function setAlt($alt)
{
    $this->alt = $alt;
    return $this;
}

/**
 * Set name
 *
 * @param string $name
 * @return String
 */
public function setName($name)
{
    $this->name = $name;
    return $this;
}

/**
 * Set updateAt
 *
 * @param \DateTime $updateAt
 *
 * @return Media
 */
public function setUpdateAt($updateAt)
{
    $this->updateAt = $updateAt;

    return $this;
}

/**
 * Get updateAt
 *
 * @return \DateTime
 */
public function getUpdateAt()
{
    return $this->updateAt;
}

感谢你们的帮助:)

【问题讨论】:

  • 完全不清楚您在做什么以及何时收到错误。在任何情况下,堆栈跟踪都可以让您了解错误发生的位置。
  • 上传图片时出现此错误。我很难用英语解释,对此我深表歉意。我想我在配置中遗漏了一些东西,因为在另一台计算机上这工作正常。我就像驾驶舱里的狗,我不明白我在做什么哈哈

标签: symfony


【解决方案1】:

发生这种情况是因为我有一个实体属性,但缺少 getter/setter。我用过:

php bin/console make:entity --regenerate MyBundle\\Entity\\MyEntity

重新生成它们

【讨论】:

    【解决方案2】:

    对我来说同样的错误,但在 OneToMany 关系上。尽管设置“mapped => false”也解决了错误,但还有另一种选择。我在实体上只有一个 getter、adder 和 remover 方法。我也需要添加一个“setter”

    在我的情况下是:

    /**
     * @param ArrayCollection|SubStatusOptions[]
     */
    public function setSubStatusOptions(ArrayCollection $subStatusOptions)
    {
        $this->subStatusOptions = $subStatusOptions;
    }
    

    【讨论】:

      【解决方案3】:

      在为我的问题搜索解决方案时偶然发现了这个问题,这是同样的错误,我也在使用 ArrayCollection 类,所以这可能对某人有帮助:

      我在 ArrayCollection 中的字段名为 $files,所以我必须像这样添加构造函数:

      use Doctrine\Common\Collections\ArrayCollection;
      
      public function __construct()
      {
          $this->files = new ArrayCollection();
      }
      

      然后我添加了添加和删除方法,如下所示:

      public function addFile(MyFile $file) : self
      {
          $file->setParentMyItem($this); // Setting parent item 
          $this->files->add($file);
          return $this;
      }
      
      public function removeFile(MyFile $file) : self
      {
          $this->files->removeElement($file);
          return $this;
      }
      

      但是要注意的是,即使我的字段名称是 $files,我也必须命名 addremove 方法 addFile()removeFile(),最后没有“s”,这对我来说完全不合逻辑,但这解决了问题。

      【讨论】:

        【解决方案4】:

        请在表单生成器中添加“'mapped' => false,”。

        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
           ->add('file', FileType::class, 
             array(
                'data_class' => null,
                'mapped' => false,            
            ))
            ->add('name', TextType::class)
            ;
         }
        

        那些说解散是错误的人,看看那里的测试。不是我弄错了。

        测试代码: https://github.com/symfony/property-access/blob/master/Tests/PropertyAccessorCollectionTest.php#L151

        第二种解决方案是将 function setXxx 添加到在 class Entity 中给出错误的属性中。

        public $xxx;
        
        public function setXxx(Array $xxx)
        {
            $this->xxx = $xxx;
        }
        

        或者

        public function __construct()
        {
            $this->xxx = new ArrayCollection();
        }
        

        视频链接:https://knpuniversity.com/screencast/doctrine-relations/create-genus-note

        我的英语不好,我可以告诉你。

        【讨论】:

        • 删除错误但不正确。实体已映射,问题不存在
        • Gauthier,你有解决办法吗?
        • 不,还没有......仍在寻找解决方案。我看到有人遇到同样的问题,他通过初始化一个新的 ArrayCollection 来解决它: $this->val = new ArrayCollection();在构造函数中。但这不是我的情况
        • 第二个解决方案帮助我意识到我已经将一个属性从一个集合更改为单个实体(作者到作者)并且没有清理我的类。谢谢!
        • 仅供参考,以防它帮助任何人,在我的情况下,我错过了 removeXxx() 方法......所以从列表中删除时它抛出了这个错误......
        【解决方案5】:

        设置 mapped => false 不是真正的解决方案,因为该字段已映射到实体。

        在我的例子中,我有一个 OneToMany 关系,所以我需要映射的字段才能使用 'cascase' => {"all"} 选项。

        如果该字段未映射,则必须手动持久化相关实体。这样不好。

        【讨论】:

        • 'mapped' => false,我是这样解决的,你的问题可能不一样。
        猜你喜欢
        • 2023-03-24
        • 2019-09-26
        • 2021-09-19
        • 2020-11-07
        • 2019-07-25
        • 1970-01-01
        • 2023-03-20
        • 2017-07-03
        • 2021-05-07
        相关资源
        最近更新 更多