我正在尝试创建一种上传文件的方法。可以上传两种类型的文件:GPS文件和媒体文件。它们非常相似,但存储的信息略有不同。服务处理他们的上传。但是因为我希望服务的上传功能能够使用正确的类型化参数,所以我创建了FileInterface
GpsFile
和MediaFile
实现的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
答案 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