问题
If I am inside a controller, I can easily read the config parameters using:
$this->container->getParameter('profession');
But when I am in some other class, say a Form type, how can I get hold of the config parameters?
$container = new Container();
$container->getParameter('profession');
The above code shouldn't and doesn't work.
回答1:
Another similar solution is make your form type a service and inject the needed parameters. Then all your controller needs to do is to grab the service. Surround the parameter name with percent signs.
In services.xml
<service
id = "zayso_area.account.create.formtype"
class = "Zayso\AreaBundle\Component\FormType\Account\AccountCreateFormType"
public = "true">
<argument type="service" id="doctrine.orm.accounts_entity_manager" />
<argument type="string">%zayso_core.user.new%</argument>
</service>
And if you really wanted to then you could inject the complete container though that is discouraged.
回答2:
Now you can use ContainerAwareInterface:
class ContactType extends AbstractType implements ContainerAwareInterface
{
use ContainerAwareTrait;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('choice_field', ChoiceType::class, [
'choices' => $this->container->get('yourservice')->getChoices()
]);
}
}
in services.yml:
app.contact_type:
class: AppBundle\Form\ContactType
calls:
- [setContainer, ['@service_container']]
tags:
- { name: form.type, alias: 'container_aware' }
回答3:
One easy solution is to give your Type a new variable where you store the value of your config parameter. You can either make it public (not recommended), add a constructor parameter or use a setter:
class MyType extends AbstractType{
private $profession;
public function __construct($profession){
$this->profession = $profession;
}
// ...
}
You would use this in your controller like this:
$myType = new MyType($this->container->getParameter('profession'));
// use mytype with form
After all, the form should not know about the container at all as you would tie them together making it hard to test or exchange the container. This would be against the whole idea of the container.
On the other hand, using a constructor/setter to inject parameters is rather nice, as you don't need to know where they come from when testing, can change their source anytime you want and, as said, don't have a dependency to the container.
回答4:
in Symfony 4 you should first define your form as a Service then in config/services.yaml
pass your proper parameter to it
parameters:
locale: 'en'
upload_dir: '%kernel.project_dir%/public/uploads/avatars'
services:
App\Form\FilemanagerType:
arguments: ['%upload_dir%']
tags: [form.type]
and inside your form class get parameter (here upload dir) like this
class FilemanagerType extends AbstractType
{
private $upload_dir;
function __construct(string $upload_dir)
{
$this->upload_dir= $upload_dir;
}
}
I hope it helps
回答5:
You can also use a Setter Injection. From http://symfony.com/doc/current/book/service_container.html#optional-dependencies-setter-injection :
If you have optional dependencies for a class, then "setter injection" may be a better option. This means injecting the dependency using a method call rather than through the constructor. The class would look like this:
namespace AppBundle\Newsletter;
use AppBundle\Mailer;
class NewsletterManager
{
protected $mailer;
public function setMailer(Mailer $mailer)
{
$this->mailer = $mailer;
}
// ...
}
Injecting the dependency by the setter method just needs a change of syntax:
# app/config/services.yml
services:
app.mailer:
# ...
app.newsletter_manager:
class: AppBundle\Newsletter\NewsletterManager
calls:
- [setMailer, ['@app.mailer']]
回答6:
In Symfony3, It can be done like this -
At Controller
$form = $this->createForm(FormType::class, $abc, array('firstargument' => $firstargumentvalue, 'second' => $secondvalue));
At FormType
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array('data_class' => abc::class, 'firstargument' => null, 'second' => null));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$first = $options['firstargument'];
$second = $options['second'];
}
You can use the above values in the form
回答7:
In Symfony 4.1
services:
# ...
_defaults:
bind:
$projectDir: '%kernel.project_dir%'
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class MessageGenerator
{
private $params;
public function __construct(ParameterBagInterface $params)
{
$this->params = $params;
}
public function someMethod()
{
$parameterValue = $this->params->get('parameter_name');
// ...
}
}
Please refer this https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service
来源:https://stackoverflow.com/questions/10204219/symfony2-how-to-get-config-parameters-in-form-classes