глобальные функции Symfony2

19

Например, у меня есть алгоритмическая функция, которая вычисляет конкретный хэш-код. Сама функция - это 300+ строк кода. Мне нужно использовать эти функции много раз во многих различных контроллерах в моем комплекте. Где я могу хранить мой calculate_hash() , чтобы использовать его в моем комплекте? Могу ли я получить доступ к нему из других пакетов? Могу ли я также написать глобальный calculate_hash() , у которого есть доступ к диспетчеру сущностей ?

Не нашел мой ответ здесь .

    
задан twoface88 26.04.2012 в 17:18
источник
  • Но здесь: symfony.com/doc/current/book/service_container.html? –  KingCrunch 26.04.2012 в 17:24

2 ответа

42

В мире 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"

Чуть ниже службы находится идентификатор службы. Например, он используется для получения вашего сервиса в контроллерах. После этого вы указываете класс службы, а затем аргументы для передачи конструктору класса. Нотация @ означает передачу ссылки на сервис с идентификатором doctrine.orm.entity_manager .

Затем в вашем контроллере вы делаете что-то вроде этого, чтобы извлечь службу и использовать ее:

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

Обратите внимание, что результат вызова $this->get('acme.helper.algorithmic') всегда будет возвращать один и тот же экземпляр помощника. Это означает, что по умолчанию сервис уникален. Это как синглтон-класс.

Для получения дополнительной информации я предлагаю вам прочитать книгу Symfony2 . Проверьте эти ссылки также

  1. Служебный контейнер раздел из книги Symfony2.
  2. Ответ, который я дал при доступе к службе вне контроллеров, здесь .

Надеюсь, это поможет.

С уважением,
Matt

    
ответ дан Matt 26.04.2012 в 17:33
  • Вы вызвали метод test_method (). Это заставляет меня думать, что это что-то связано с модульным тестированием, но, насколько я могу судить, это не так. Можете ли вы отредактировать свой ответ и называть его example_method () или что-то в этом роде, или если это касается модульного тестирования, где вы помещаете метод, который хотите использовать / проверить? –  rjmunro 18.07.2012 в 18:14
  • Я назвал его test_function (), потому что исходный плакат назвал его алгоритмический метод test_function (). Он не связан с модульным тестированием, но может быть, если алгоритм должен использоваться в модульных тестах. Если я изменю имя функции, мне нужно будет отредактировать исходный вопрос, чтобы он синхронизировался с новым именем. –  Matt 18.07.2012 в 18:28
  • Хорошая мысль, сейчас я чувствую себя глупо :-). Я собираюсь позволить себе просто переименовать все в calculate_hash () –  rjmunro 19.07.2012 в 13:32
  • Ничего глупого здесь, я часто читал ответ и забыл прочитать связанный вопрос :) Хорошо, никаких проблем с переименованием. –  Matt 19.07.2012 в 20:11
  • как мы можем сделать это на symfony 3? –  Braian Mellor 07.07.2017 в 18:25
0

Браян в комментарии попросил ответить на Symfony 3, так что вот вам один Symfony 3.3 (выпущен в мае 2017 года):

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. Регистрация службы намного проще

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

Вы можете прочитать о внедрении зависимостей в Symfony 3.3 (в данном случае зарегистрировать сервисы в config и использовать его в контроллере) в следующих двух статьях:

ответ дан Tomáš Votruba 20.08.2017 в 23:32