Сервисы в Symfony: Создание и Использование
Сервисы — это маленькие полезные кирпичики, которые можно использовать почти везде в вашем приложении Symfony. Если объект нужно использовать в различных контроллерах, его следует записать как сервис(service). В этом кратком руководстве разберем простую реализацию Services, объясним, как получить доступ к диспетчеру сущностей и другим компонентам Symfony внутри Сервиса, и показать несколько примеров того, как Сервисы можно вызывать и использовать в Контроллерах и в Командах.
Создание пользовательского класса сервиса
<?php namespace MyApp\MyAppBundle\Services; class CookieTools { public function giveACookie() { return 'Keep calm and have a cookie.'; } }
Чтобы использовать Сервис, нам нужно зарегистрировать его в Symfony:
# app/config/services.yml services: myapp_bundle.cookie_tools: # any name you want, just make it unique class: MyApp\MyAppBundle\Services\CookieTools # the class arguments: []
В этом примере Сервис зарегистрирован в основном файле services.yml. Но если Сервис используется только внутри одного пакета, его также можно зарегистрировать в файле services.yml этого пакета. Теперь Сервис готов к использованию!
Внедрение сервисов в другой в сервис
Теперь предположим, что нам нужно получить какие-то данные из базы данных, или, может быть, нам нужно что-то перевести или сгенерировать маршрут. Затем нам потребуется доступ к диспетчеру сущностей и к контейнеру. Для этого мы можем использовать метод __construct() для передачи этих вещей в сервис.
Класс сервиса:
<?php namespace MyApp\MyAppBundle\Services; use Doctrine\ORM\EntityManager; use Symfony\Component\DependencyInjection\Container; use MyApp\MyAppBundle\Entity; use MyApp\MyAppBundle\Cookie; class CookieTools { protected $em; private $container; public function __construct(EntityManager $entityManager, Container $container) { $this->em = $entityManager; $this->container = $container; } public function giveACookie($user = null) { // Get the translator $translator = $this->container->get('translator'); // Get a repository $cookieRep = $this->em->getRepository('MyAppBundle:Cookie'); // If the user is not null, get its favorite cookie if ($user !== null) { $cookie = $cookieRep->findOneBy(array( 'favorite' => $user )); if ($cookie !== null) { // Translate the message for the user and include the cookie name $msg = $translator->trans( 'cookie_for_you', array("cookie"=>$cookie->getName()), 'cookie_translations'); // Send the message return $msg; } } // Default return null; } }
Далее нам нужно также включить аргументы __construct() в регистрацию сервиса:
# app/config/services.yml services: myapp_bundle.cookie_tools: class: MyApp\MyAppBundle\Services\CookieTools arguments: ["@doctrine.orm.entity_manager", "@service_container"]
Конечно, пользовательские сервисы также могут быть внедрены таким же образом.
Вызов и использование сервиса внутри контроллера
Использование службы внутри контроллера очень просто:
<?php // Inside the Controller, call the service using the exact name used in its regiostration (services.yml) $cookieTools = $this->get('myapp_bundle.cookie_tools'); // Use any function inside the Service like this : $cookieForUser = $cookieTools->giveACookie($user);
Вызов и использование сервиса внутри команды
Использование сервиса внутри команды похоже на ее использование внутри контроллера. Единственное отличие состоит в том, что Команде нужен доступ к Контейнеру для вызова Сервиса:
<?php namespace MyApp\MyAppBundle\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; class CreateInvoiceableCommand extends ContainerAwareCommand { protected function configure () { // Name $this->setName('cookie:giveCookieToEveryone'); // Description $this->setDescription("Gives its favorite cookie to every user."); // Help $this->setHelp("Call this command from Cron task every day at midnight"); } public function execute (InputInterface $input, OutputInterface $output) { // Get the Service $cookieTools = $this->getContainer()->get('myapp_bundle.cookie_tools'); // Get the Entity Manager $entityManager = $this->getContainer()->get('doctrine')->getEntityManager(); // Get all the users $users = $entityManager->getRepository('SecurityBundle:User')->findAll(); // Give them cookies $cookiesForAll = array(); foreach ($users as $user) { // Get the user's favorite cookie using the Service $cookie = $cookieTools->giveACookie($user); if ($cookie !== null) { $cookiesForAll[]['user'] = $user->getId(); $cookiesForAll[]['cookie'] = $cookie; } } return $cookiesForAll; } }