Дата обновления перевода 2022-02-01
Как внедрять значения, основанные на сложных выражениях¶
Сервис-контейнер также поддерживает “выражение”, которое позволяет вам внедрять очень особенные значения в сервис.
Например, представьте, что у вас есть сервис (здесь не показан), под названием
App\Mail\MailerConfiguration
, который в себе имеет метод getMailerMethod()
.
Он возвращает строку вроде sendmail
, основываясь на какой-то конфигурации.
Представьте, что вы хотите передать результат этого метода в качестве аргумента
конструктора другому сервису: App\Mailer
. Одним из способов сделать это
- с помощью выражения:
- YAML
1 2 3 4 5 6 7 8 9 10 11
# config/services.yaml services: # ... App\Mail\MailerConfiguration: ~ App\Mailer: # префикс '@=' обязателен при использовании выражений для аргументов в файлах YAML arguments: ['@=service("App\\Mail\\MailerConfiguration").getMailerMethod()'] # при использовании строк с двойными кавычками, братный слэш должен быть экранирован дважды (см. https://yaml.org/spec/1.2/spec.html#id2787109) # аргументы: ["@=service('App\\\\Mail\\\\MailerConfiguration').getMailerMethod()"]
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<!-- config/services.xml --> <?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <!-- ... --> <service id="App\Mail\MailerConfiguration"></service> <service id="App\Mailer"> <argument type="expression">service('App\\Mail\\MailerConfiguration').getMailerMethod()</argument> </service> </services> </container>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\Mail\MailerConfiguration; use App\Mailer; return function(ContainerConfigurator $configurator) { // ... $services->set(MailerConfiguration::class); $services->set(Mailer::class) // из-за экранирования, примененного PHP, вы должны добавить 4 обратных слэша для каждого изначального обратного слэша ->args([expr("service('App\\\\Mail\\\\MailerConfiguration').getMailerMethod()")]); };
Чтобы узнать больше о синтаксисе языка выражений, см. The Expression Syntax.
В этом контексте, у вас есть доступ к 2 функциям:
service
- Возвращает данный сервис (смотрите пример выше).
parameter
- Возвращает конкретное значение параметра (синтаксис такой же, как в
service
).
Вы также имеете доступ к Container
через переменную container
. Вот ещё один пример:
- YAML
1 2 3 4 5
# config/services.yaml services: App\Mailer: # префикс '@=' обязателен при использовании выражений для аргументов в файлах YAML arguments: ["@=container.hasParameter('some_param') ? parameter('some_param') : 'default_value'"]
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13
<!-- config/services.xml --> <?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="App\Mailer"> <argument type="expression">container.hasParameter('some_param') ? parameter('some_param') : 'default_value'</argument> </service> </services> </container>
- PHP
1 2 3 4 5 6 7 8 9 10 11
// config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\Mailer; return function(ContainerConfigurator $configurator) { $services = $configurator->services(); $services->set(Mailer::class) ->args([expr("container.hasParameter('some_param') ? parameter('some_param') : 'default_value'")]); };
Выражения могут быть использованы в arguments
, properties
, в качестве аргументов
с configurator
и аргументов к calls
(вызовы метода).
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.