doctrine实体实现接口以进行typehint

时间:2017-04-17 14:03:50

标签: php symfony doctrine

我正在尝试创建一种上传文件的方法。可以上传两种类型的文件:GPS文件和媒体文件。它们非常相似,但存储的信息略有不同。服务处理他们的上传。但是因为我希望服务的上传功能能够使用正确的类型化参数,所以我创建了FileInterface GpsFileMediaFile实现的interface FileInterface { } class MediaFile implements FileInterface { private $id; private $orientation; } class GpsFile implements FileInterface { private $id; private $date; } class FileUploaderService { public function upload(FileInterface $file) { // code to upload } } 。但这对symfony / doctrine实体仍然有意义吗?

content

1 个答案:

答案 0 :(得分:1)

您的方法对于实现类型提示绝对正确。如果上传的文件存储在数据库中并使用Doctrine / Entities进行访问,那么您可能需要考虑在Doctrine中处理此类文件的方法。

<强> 1。单表继承 如果不同类型的上传大多数都有类似的字段存储在数据库中,并且你可以在Symfony端委托正确的处理required / nullable字段,那么这是一个很好的选择。使用这种方法,Doctrine存储文件,媒体和GPS的所有字段存储在同一个表中,并使用鉴别器字段和字段组合设置为NULL的其他继承实体。

对于实体,您将拥有以下内容:

声明为抽象的基本文件实体:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\FileRepository")
 * @ORM\Table(name="file")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "media" = "Media",
 *     "gps" = "Gps"
 * })
 */
abstract class File
{
    // Properties, ORM column mappings, assertions and getters/setters for Id, filename, mimetype and other common fields needed for the file uploads...
}

媒体扩展文件的实体

/**
 * Media
 *
 * @ORM\Entity(repositoryClass="AppBundle\Repository\MediaRepository")
 */
class Media extends File
{
    // Media Upload specific properties, ORM column mappings etc...
}

GPS扩展文件的实体

/**
 * GPS
 *
 * @ORM\Entity(repositoryClass="AppBundle\Repository\GpsRepository")
 */
class Gps extends File
{
    // Gps Upload specific properties, ORM column mappings etc...
}

对于类型提示,那么您可以让抽象的File类实现您的FileInterface并对Media和Gps实体执行相同的操作,或者更好的是,使用特定于Media和Gps的其他接口来定义自己的接口并扩展FileInterface

<强> 2。类表继承。 如果Media / Gps实体有很多独特的字段,那么最好使用类继承,这将为File创建一个父表,为每个Media和Gps创建一个表,通过外键关系和鉴别字段链接它们。由于依赖JOIN调用,这会导致性能下降。 see Doctrine docs