gpt4 book ai didi

file - Symfony2文件上传步骤

转载 作者:行者123 更新时间:2023-12-03 05:51:15 25 4
gpt4 key购买 nike

我还在学习 Symfony2,不明白如何上传文件。

别担心,我已经查过了the documentation 。这确实很好,但我的问题没有在任何教程中得到解释。

我正在寻找有关如何使用 Symfony2 上传文件的指南,但包含每个人都需要的所有内容(例如扩展名约束、根据 id 和内容重命名文件、将路径存储在数据库中等。 ..)

我找到了很好的教程,尝试将它们混合起来,但没有成功。每次都会出现不同的问题:每次提交表单时都会重新上传文件(即使文件字段为空)、无法​​使用guessExtension、存储在数据库中的 tmp 路径而不是正确的路径、文件未移动、不可能在重命名中使用了 id,因为 id 是自动递增的,因此尚未生成)。

所以,我将放置一个“标准”实体,比如说:Photo.php

/**
* Photo
*
* @ORM\Table(name="photo")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Photo
{
// Annotation for the id and auto increment etc
private $id;

/**
* @var string
* @Assert\File( maxSize = "3072k", mimeTypesMessage = "Please upload a valid Image")
* @ORM\Column(name="image", type="string", length=245, nullable=false)
*/
private $image

private $title

private $description

// all the function get, set for the 4 previous variables
}

和 Controller :

public function addPhotoAction()
{
$add_photo = new Photo;
$formBuilderPhoto = $this->createFormBuilder($add_photo);
$formBuilderPhoto
->add('title','text',array('label' => 'Title of the photo', 'required' => true))
->add('image','file', array('required' => true, 'data_class' => null))
->add('description','textarea',array('label' => 'Description of your photo', 'required' => false))
;

$form_photo = $formBuilderPhoto->getForm();

if ($request->getMethod() == 'POST') {
$form_photo->bind($request);
if ($form_photo->isValid()) {
// ...
}
}
return $this->render('MyBundle:frontend:photo.html.twig',
array('form_photo' => $form_photo->createView())
);
}

您现在知道要添加哪些“重要”功能才能上传照片并重命名吗?

如何检查扩展程序是否可以上传?

你用 Symfony2 做这样的事情的实际方法是什么?我知道有很多 Bundle 可以为您完成所有这些事情,但我想学习如何做到这一点并了解整个过程。

使用 Symfony2 实现文件上传表单和重命名功能的“经典”方法是什么?

最佳答案

Do you know now what are the 'important' function to add to be able to upload the photo and rename it?

请参阅official documentation关于如何做到这一点。对于简单的文件上传有很好的工作示例。另请检查 lifecycle callbacks 的学说文档.

How do you check the extension to see if the upload is possible?

每个浏览器中都有一些 HTML 表单验证。请参阅this question对于 input 元素中的 HTML accept="" 属性。同样在 Symfony2 中您可以 specify the MIME-type使用此注释的上传文件的:

/**
* @Assert\File(
* maxSize = "1024k",
* mimeTypes = {"application/pdf", "application/x-pdf"},
* mimeTypesMessage = "Please upload a valid PDF"
* )
*/

即使您不想使用任何 bundle ,我也必须向您推荐 KnpDoctrineBehavioursBundle这使得文件上传更加容易。

<小时/>

逐步说明:

因为您已经阅读了文档,所以我将为您提供一个逐步的代码示例。

首先你需要一个实体。我们称之为图像:

/**
* Class Image
*
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks
*/
class Image extends BaseEntity
{

注意@ORM\HasLifecycleCallbacks注释。它非常重要,稍后您会需要它。我们创建所有基本字段,例如 ID 等。我们还需要一个字段来存储文件路径:

    /**
* Image path
*
* @var string
*
* @ORM\Column(type="text", length=255, nullable=false)
*/
protected $path;

还有一个用于图像本身。在这里我们还定义了图像的验证。在我的示例中,它必须为 5M 大,并且属于定义的 mimeTypes 之一。它应该是不言自明的。否则 official docs一如既往的帮助。

    /**
* Image file
*
* @var File
*
* @Assert\File(
* maxSize = "5M",
* mimeTypes = {"image/jpeg", "image/gif", "image/png", "image/tiff"},
* maxSizeMessage = "The maxmimum allowed file size is 5MB.",
* mimeTypesMessage = "Only the filetypes image are allowed."
* )
*/
protected $file;

添加所有Getters & Setters并使用以下命令更新您的数据库架构:

php app/console doctrine:schema:update --force

接下来我们需要生命周期。它们是 Entity 中的方法,在某些事件上调用。例如,方法之前的 @ORM\PreUpdate() 注释表示该方法在实体更新之前被调用。

/**
* Called before saving the entity
*
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->file) {
// do whatever you want to generate a unique name
$filename = sha1(uniqid(mt_rand(), true));
$this->path = $filename.'.'.$this->file->guessExtension();
}
}

在存储或更新实体之前,会调用此方法。您可以使用它来例如生成唯一的文件名。

/**
* Called before entity removal
*
* @ORM\PreRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}

在实体被删除之前调用。这让您有时间从文件夹中删除图像或根据需要记录消息。

/**
* Called after entity persistence
*
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
// The file property can be empty if the field is not required
if (null === $this->file) {
return;
}

// Use the original file name here but you should
// sanitize it at least to avoid any security issues

// move takes the target directory and then the
// target filename to move to
$this->file->move(
$this->getUploadRootDir(),
$this->path
);

// Set the path property to the filename where you've saved the file
//$this->path = $this->file->getClientOriginalName();

// Clean up the file property as you won't need it anymore
$this->file = null;
}

这是重要的部分,您的文件实际上被移动到正确的目录。请注意,我使用了一些额外的方法。您都可以从 official docs 获取它们.

接下来您需要的是一个表格。表单类本身非常简单。只需确保您设置默认的 data_class 如下:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'FSchubert\SiyabongaBundle\Entity\Image',
)
);
}

可以在 buildForm() 方法中非常轻松地创建文件上传字段:

$builder->add('file', 'file');

您的 Controller 的方法有点长,无法将它们粘贴到此处,恕我直言,这不是回答您的问题的一部分。有无数的例子可以根据您的目的编写适当的 Controller 操作

<小时/>

您必须记住的更多事项:

  • 您需要向您的应用授予您将文件上传到的文件夹的写入权限。虽然这看起来很明显,但如果您有多个服务器运行应用程序,这可能会很烦人。
  • 您的实体也有一个图像约束。可以找到here 。但由于您谈论的是文件上传,所以我使用了文件约束
  • 正如我在这篇文章的顶部提到的,有许多 Bundle 可以为您处理所有这些事情。如果您想要轻松的生活,请查看它们。

编辑:

  • DoctrineExtensionsBundle 更改为 DoctrineBehaviours,因为旧版本的开发已停止,取而代之的是 DoctrineBehaviours bundle 。

关于file - Symfony2文件上传步骤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17951294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com