Вопрос по php, symfony – Symfony2 глобальные функции

19

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

Не нашел мой ответВот.

Но здесь:symfony.com/doc/current/book/service_container.html ? KingCrunch

Ваш Ответ

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. The service container section from Symfony2 book.
  2. An answer I gave on accesing service outside controllers, here.

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

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

Хороший вопрос, я чувствую себя действительно глупо сейчас :-). Я позволю себе просто переименовать все вcalculate_hash()
Вы назвали методtest_method(), Это заставляет меня думать, что это что-то связанное с модульным тестированием, но, насколько я могу судить, это не так. Можете ли вы отредактировать свой ответ и назвать егоexample_method() или что-то, или если речь идет о модульном тестировании, куда вы помещаете метод, который хотите использовать / test?
Как мы можем сделать это на Symfony 3?
Я назвал этоtest_function() потому что оригинальный постер назвал его алгоритмический методtest_function(), Он не связан с модульным тестированием, но может, если алгоритм будет использоваться в модульных тестах. Если я изменю имя функции, мне нужно будет отредактировать исходный вопрос, чтобы он синхронизировался с новым наименованием.
Хе-хе, здесь ничего глупого, я часто читаю ответ и забываю прочитать связанный вопрос :) Окей, проблем с переименованием нет.
0

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

1. The original class remains the same

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. Service registration is much simpler

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

    Acme\AcmeBundle\Helper\AlgorithmicHelper: ~

3. Use constructor injection to get the service

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 и использовать его в контроллере) в следующих двух постах:

Вы сами указали причину в первом предложении: «Брайан в комментарии попросил ответить на Symfony 3». Поэтому они задали новый вопрос в комментарии, на который вы ответили здесь, хотя этот вопрос относится к Symfony2.
Это должен был быть ответ на отдельный вопрос. Вам разрешено задавать и отвечать на свои вопросы. Фактически, поскольку по этому ответу нет голосов, я бы предложил создать новый вопрос и скопировать на него этот ответ, а затем удалить ответ здесь. Как только это будет сделано, вы можете оставить комментарий, указывающий пользователю на новый вопрос и ответ.
Почему ты так думаешь?
Я думаю, что это тенденция, и лучше использовать 1 вопрос для многих версий, а не создавать новый собственный вопрос + ответ на эту версию для каждой версии. Например, см .:stackoverflow.com/questions/13901256/…  Основная цель не в Symfony 2, хотя это может показаться, а в том, как "добиться того, чтобы в Symfony работала версия, которая была нова по времени, когда задавался этот вопрос".

Похожие вопросы