【问题标题】:doctrine entities implementing interface in order to typehint学说实体实现接口以输入提示
【发布时间】:2017-04-17 14:03:50
【问题描述】:

我正在尝试创建一种上传文件的方法。可以上传两种类型的文件:GPS 文件和媒体文件。它们非常相似,但存储的信息略有不同。服务处理他们的上传。但是因为我希望服务的上传功能能够使用正确的类型提示参数,所以我创建了一个 FileInterfaceGpsFileMediaFile 都实现了它。但这对 symfony/doctrine 实体仍然有意义吗?

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
    }
}

【问题讨论】:

标签: php symfony doctrine


【解决方案1】:

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

1.单表继承 如果不同类型的上传大多有相似的字段要存储在数据库中,并且如果您可以在 Symfony 端委派正确处理所需/可为空的字段,那么考虑到您的用例,这是一个不错的选择。通过这种方法,Doctrine 将 File、Media 和 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

【讨论】:

  • 超级有帮助。喜欢这个解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 2012-02-15
相关资源
最近更新 更多