【问题标题】:Symfony2 global functionsSymfony2 全局函数
【发布时间】:2012-04-26 15:18:59
【问题描述】:

例如,我有计算特定哈希码的算法函数。函数本身是 300 多行代码。我需要在捆绑包中的许多不同控制器中多次使用该功能。我在哪里可以存储我的 calculate_hash() 以在我的捆绑包中使用它?我可以从其他捆绑包中访问它吗? 我也可以写全局calculate_hash() 可以访问entity manager吗?

没有找到我的答案here

【问题讨论】:

标签: php symfony


【解决方案1】:

在 Symfony2 世界中,这显然属于服务。服务实际上是绑定到依赖注入容器的普通类。您可以向它们注入您需要的依赖项。例如,假设函数calculate_hash 所在的类是AlgorithmicHelper。该服务具有“全局”功能。你定义你的类是这样的:

namespace Acme\AcmeBundle\Helper;

// Correct use statements here ...

class AlgorithmicHelper {

    private $entityManager;

    public function __construct(EntityManager $entityManager) {
        $this->entityManager = $entityManager;
    }

    public function calculate_hash() {
        // Do what you need, $this->entityManager holds a reference to your entity manager
    }
}

然后需要让这个类知道 symfony 依赖容器。为此,您可以在 app/config/config.yml 文件中定义您的服务,方法是添加一个 service 部分,如下所示:

services:
  acme.helper.algorithmic:
    class: Acme\AcmeBundle\Helper\AlgorithmicHelper
    arguments:
      entityManager: "@doctrine.orm.entity_manager"

服务的正下方是服务 ID。例如,它用于在控制器中检索您的服务。之后,您指定服务的类,然后,将参数传递给类的构造函数。 @ 表示法表示传递对 ID 为 doctrine.orm.entity_manager 的服务的引用。

然后,在您的控制器中,您执行以下操作来检索服务并使用它:

$helper = $this->get('acme.helper.algorithmic');
$helper-> calculate_hash();

请注意,调用$this->get('acme.helper.algorithmic') 的结果将始终返回相同的帮助程序实例。这意味着,默认情况下,服务是唯一的。这就像有一个单例类。

更多详情,我邀请您阅读 Symfony2 book。也检查这些链接

  1. 来自 Symfony2 书中的服务容器 section
  2. 我给出的关于访问控制器外部服务的答案,here

希望对你有帮助。

问候,
马特

【讨论】:

  • 你调用了方法test_method()。这让我觉得这与单元测试有关,但据我所知,并非如此。您可以编辑您的答案并将其命名为example_method() 或其他名称,或者如果这是关于单元测试,您将要使用/测试的方法放在哪里?
  • 我将其命名为test_function(),因为原始发帖人确实将他的算法方法命名为test_function()。它与单元测试无关,但如果要在单元测试中使用该算法,它可以。如果我更改函数名称,我需要编辑原始问题,使其与新命名同步。
  • 好点,我现在觉得自己很蠢 :-)。我将冒昧地将所有内容重命名为calculate_hash()
  • 呵呵 没什么蠢的,我经常看答案,忘了看相关问题 :) 好的,改名没问题。
  • 我们如何在 symfony 3 上做到这一点?
【解决方案2】:

Braian 在评论中询问 Symfony 3 的答案,所以这里有一个 Symfony 3.3(2017 年 5 月发布):

1。原来的类保持不变

namespace Acme\AcmeBundle\Helper;

use Doctrine\ORM\EntityManager;

final class AlgorithmicHelper
{
    /**
     * @var EntityManager
     */
    private $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function calculateHash()
    {
        // Do what you need, $this->entityManager holds a reference to your entity manager
    }
}

2。服务注册is much simpler

# app/config/services.yml
services:
    _defaults: autowire # this enabled constructor autowiring for all registered services

    Acme\AcmeBundle\Helper\AlgorithmicHelper: ~

3。使用构造函数注入获取服务

use Acme\AcmeBundle\Helper\AlgorithmicHelper;

class SomeController
{
    /**
     * @var AlgorithmicHelper
     */
    private $algorithmicHelper;

    public function __construct(AlgorithmicHelper $algorithmicHelper)  
    {
        $this->algorithmicHelper = $algorithmicHelper;
    }

    public function someAction()
    {
        // some code
        $hash = $this->algorithmicHelper->calculateHash();
        // some code
    }
}

您可以在以下 2 篇文章中阅读有关 Symfony 3.3 依赖注入(在这种情况下在配置中注册服务并在控制器中使用它)的新闻:

【讨论】:

  • 这应该是一个单独问题的答案。您可以提出和回答自己的问题。事实上,由于这个答案没有投票,我建议提出一个新问题并将这个答案复制到它,然后在此处删除答案。完成此操作后,您可以留下评论,将用户指向新的问题和答案。
  • 你为什么这么认为?
  • 您在第一句话中自己给出了原因:“Braian in comment ask for Symfony 3 answer”。所以他们在你在这里回答的评论中提出了一个新问题,即使这个问题是特定于 Symfony2 的。
  • 我认为在多个版本中使用 1 个问题是一种趋势并且更好,而不是为每个版本创建一个新的自己的问题 + 对该版本的答案。例如,请参阅:stackoverflow.com/questions/13901256/… 主要目标不是关于 Symfony 2,尽管它可能看起来如此,而是如何“在提出该问题时在新版本的 Symfony 中工作”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 2012-07-31
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多