访问实体存储库或Anywhere中的Symfony配置参数

Cha*_*yer 5 php symfony

我有很多配置设置,我希望能够在整个应用程序中访问.例如,我有一个包含一些自定义查询的实体存储库.我想有一个全局参数,将默认的"限制"设置为10条记录,除非我专门更改它.

class ViewVersionRepository extends EntityRepository {

    /**
     * Get all the versions for the specified view id, ordered by modification time.
     * @param integer $id
     * @param integer $limit
     * @param integer $offset default 0
     * @return array
     */
    public function findByViewIdLimit($id, $limit = NULL, $offset = 0) {

        // this won't work because we don't have access to the container... ;(
        $limit = ($limit != NULL) ? $limit : $this->container->getParameter('cms.limit');

        return $this->createQueryBuilder('v')
            ->where('v.viewId = :id')
            ->orderBy('v.timeMod', 'DESC')
            ->setParameter('id', $id)
            ->setFirstResult($offset)
            ->setMaxResults($limit)
            ->getQuery()
            ->getResult();
    }

}
Run Code Online (Sandbox Code Playgroud)

在我之前的Symfony生活中,我可以在我的parameters.yml中轻松设置它:

cms.limit: 10
Run Code Online (Sandbox Code Playgroud)

或者在某些应用配置文件中为此创建一个常量:

define('cms.limit', 10);
Run Code Online (Sandbox Code Playgroud)

但是在Symfony中,如果我使用参数,我如何从我的实体存储库中访问它,因为"容器"在实体存储库中不可用?

人们说"将其作为一个参数传递"但老实说,每次调用查询时,这都是混乱和毫无意义的工作.如果您无法访问参数,那么有什么意义呢!

其他人说你必须构建一些全局服务模型(我还没有理解它,对于仅获取参数似乎是一项巨大的努力).

那么在任何上下文(包括这里的那个)中访问这样的全局参数的"最佳"方法是什么?

我不想访问内核,但如果这是最后的手段,为什么从内核获取参数是"错误的",如:

global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');?
Run Code Online (Sandbox Code Playgroud)

我无法相信这很难访问全局参数.我理解需要明确依赖关系的想法.但是在一个参数永远可用的应用程序中,你总是希望将它们用作默认值,为什么这个标准不容易?


更新

根据下面的答案,我已将我的ViewVersionRepository转换为服务(这是你建议的那样吗?).

class ViewVersionRepository extends EntityRepository
Run Code Online (Sandbox Code Playgroud)

{

    // do not evidently need to set $this->viewVersion either
    // protected $viewVersion;
    protected $limit;

    /**
     * Allow limit to be set by parameter, injected by service definition
     * @param $limit
     */
    public function setLimit($limit) {
        $this->limit = $limit;
    }



    /**
     * Get all the versions for the specified view id, ordered by modification time.
     * @param integer $id
     * @param integer $limit default from global parameter
     * @param integer $offset default 0
     * @return array
     */
    public function findByViewIdLimit($id, $limit = NULL, $offset = 0) {

        $limit = (!empty($limit)) ? $limit : $this->limit;

        return $this->createQueryBuilder('v')
            ->where('v.viewId = :id')
            ->orderBy('v.timeMod', 'DESC')
            ->setParameter('id', $id)
            ->setFirstResult($offset)
            ->setMaxResults($limit)
            ->getQuery()
            ->getResult();
    }

}
Run Code Online (Sandbox Code Playgroud)

添加服务:

gutensite_cms.view_version_repository:
    class: Gutensite\CmsBundle\Entity\View\ViewVersionRepository
    factory_service: 'doctrine.orm.default_entity_manager'
    factory_method: 'getRepository'
    arguments:
        - 'Gutensite\CmsBundle\Entity\View\ViewVersion'
    calls:
        - [setLimit, ['%cms.limit.list.admin%']]
Run Code Online (Sandbox Code Playgroud)

这会导致抱怨factory_service定义的错误:

You have requested a non-existent service "doctrine.orm.default_entity_manager". Did you mean one of these: "doctrine.orm.cms_entity_manager", "doctrine.orm.billing_entity_manager"?
Run Code Online (Sandbox Code Playgroud)

幸运的是,如果我改为factory_service建议doctrine.orm.cms_entity_manager它可行.有人可以解释原因吗?

但后来我得到另一个与存储库中的方法不存在的错误(因为存储库已损坏).我认为在服务定义中使用参数意味着我需要__construct($viewVersion)向ViewVersionRepository 添加一个方法来接受参数列表.但这导致了一个令人讨厌的错误,打破了存储库.所以我删除了它,因为显然这必须在默认的Symfony EntityRepository中(我应该怎么知道?).我确实保留了一个自定义的setLimit()方法,用于将全局参数传递给调用.

所以现在服务工作......但是这看起来像是大量的工作,只是为了访问全局参数,如果没有参数传递给方法,它应该作为DEFAULT.

为什么我们不应该在这些我们设置默认值的情况下使用配置文件中的$ GLOBAL或常量?这不会破坏依赖模型,自定义变量仍然可以传递给方法,只有我们有一个全局应用程序范围的默认值.我不明白为什么这是不赞成的......

Cer*_*rad 9

学习和理解如何将存储库创建为服务是值得的.就像是:

view_version_repository:
    class:  My\SomeBundle\Entity\ViewVersionRepository
    factory_service: 'doctrine.orm.default_entity_manager'
    factory_method:  'getRepository'
    arguments:  
        - 'My\SomeBundle\Entity\ViewVersion'
    calls:
         - [setLimit, ['%limit_parameter%']]
Run Code Online (Sandbox Code Playgroud)

在你的控制器中你会做:

$viewVersionRepository = $this->container->get('view_version_repository');
Run Code Online (Sandbox Code Playgroud)

请参阅文档:http://symfony.com/doc/current/components/dependency_injection/factories.html

学习如何使用服务所花费的精力将多次回报自己.

  • aiyayai ...因此,它有望提供很多服务。经验法则是什么?每当需要访问全局变量的内容时,就应该提供服务并将这些变量作为调用传递? (2认同)