gpt4 book ai didi

php - 在实体库或任何地方访问 Symfony 配置参数

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:05:19 25 4
gpt4 key购买 nike

我有很多配置设置,我希望能够在整个应用程序中访问这些设置。例如,我有一个包含一些自定义查询的实体存储库。我想要一个全局参数,将默认“限制”设置为 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();
}

}

在我使用 Symfony 之前的生活中,我可以很容易地在我的 parameters.yml 中设置它:

cms.limit: 10

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

define('cms.limit', 10);

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

人们说“将其作为参数传递”,但老实说,每次我调用查询时,这都是一种困惑和无意义的工作。如果您无法访问它们,那么拥有参数有什么意义!

其他人说你必须构建一些 global service model (我也还没有理解,似乎只是为了获取参数而付出了巨大的努力)。

那么在任何上下文(包括此处的上下文)中访问此类全局参数的“最佳”方法是什么?

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

global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');‏

我不敢相信访问全局参数这么难。我理解需要明确说明依赖关系的想法。但是在参数始终可用的应用程序中,并且您总是希望将它们用作默认值,为什么这不是标准且简单的呢?


更新

根据下面的回答,我已经将我的 ViewVersionRepository 变成了一项服务(这就是您的建议,对吗?)。

class ViewVersionRepository extends EntityRepository

{

    // 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();
}

}

添加服务:

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%']]

这会导致提示 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"?

幸运的是,如果我将 factory_service 更改为建议的 doctrine.orm.cms_entity_manager 它会起作用。 谁能解释为什么?

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

所以现在服务可以工作了……但这似乎是一大堆工作,只是为了访问全局参数,如果没有参数传递到方法中,这些参数应该作为默认值运行。

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

最佳答案

值得研究和了解如何将存储库创建为服务。像这样的东西:

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%']]

在你的 Controller 中你会做:

$viewVersionRepository = $this->container->get('view_version_repository');

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

在学习如何使用服务方面所付出的努力将获得数倍的返回。

关于php - 在实体库或任何地方访问 Symfony 配置参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23701852/

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