Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Vincular argumentos globalmente

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

En la práctica, rara vez tienes que hacer algo dentro de services.yaml. La mayoría de las veces, cuando añades un argumento al constructor de un servicio, es autoconductible. Así que añades el argumento, le das una pista de tipo... ¡y sigues codificando!

Pero el argumento de $isDebug no es autoconductible... ya que no es un servicio. Y eso nos obligó a anular por completo el servicio para poder especificar ese único argumento con bind. Funciona, pero... ¡eso era... mucho teclear para hacer una cosa tan pequeña!

Mover el bind a _defaults

Así que aquí tienes una solución diferente. Copia esa tecla bind, borra el servicio por completo, y arriba, bajo _defaults, pega.

Cuando nos movemos y probamos esto... ¡la página sigue funcionando! ¿No es genial? Y tiene sentido. Esta sección registrará automáticamente MixRepository como servicio... y entonces todo lo que esté bajo _defaults se aplicará a ese servicio. Así que el resultado final es exactamente el que teníamos antes.

¡Me encanta hacer esto! Me permite establecer convenciones para todo el proyecto. Ahora que tenemos esto, podemos añadir un argumento $isDebug al constructor de cualquier servicio y funcionará al instante.

Vinculación con Type_hints

Por cierto, si quieres, también puedes incluir el tipo con el bind.

Así, ahora sólo funcionaría si utilizamos la sugerencia de tipo bool con el argumento. Si utilizáramos string, por ejemplo, Symfony no intentaría pasar ese valor.

El atributo Autowire

Así que el bind global es genial. Pero a partir de Symfony 6.1, hay otra forma de especificar un argumento no autoconductible. Comenta el global bind. Todavía me gusta hacer esto... pero probemos la nueva forma.

Si actualizamos ahora, obtendremos un error porque Symfony no sabe qué pasar al argumento $isDebug. Para solucionarlo, entra en MixRepository y, por encima del argumento (o antes del argumento si no estás usando varias líneas), añade un atributo de PHP 8 llamado Autowire. Normalmente, los atributos de PHP 8 se autocompletan, pero este no se autocompleta para mí. Esto se debe a un error en PhpStorm. Para evitarlo, voy a escribir Autowire... luego iré a la parte superior y empezaré a añadir la declaración usepara esto manualmente, lo que sí nos da una opción de autocompletar. Pulsa "tab" y... ¡tah dah! Si quieres hacerlos por orden alfabético, puedes moverlo.

También puedes observar que está subrayado con un mensaje

No se puede aplicar el atributo a una propiedad [...]

De nuevo, PhpStorm está un poco confundido porque esto es tanto una propiedad como un argumento.

De todos modos, sigue adelante y pasa esto como un argumento %kernel.debug%.

Actualiza ahora y... ¡lo tienes! Bastante bien, ¿verdad?

Siguiente: la mayoría de las veces, cuando se autoconduce un argumento como HttpClientInterface, sólo hay un servicio en el contenedor que implementa esa interfaz. Pero, ¿y si hubiera varios clientes HTTP en nuestro contenedor? ¿Cómo podríamos elegir el que queremos? Es hora de hablar del autocableado con nombre.

Leave a comment!

5
Login or Register to join the conversation
Philipp Avatar
Philipp Avatar Philipp | posted hace 23 días | edited

The Autowire annotation is amazing!

Heads-up for anyone else who might have trouble using the #[Autowire()] attribute:

It requires Symfony 6.1 (and PHP 8.1)
My dev environment used PHP 8.0.8, and as a result always installed Symfony 6.0.
After upgrading PHP to v 8.1.11, my new Symfony project start out using Symfony 6.2, and the annotation works.

1 Reply
Braunstetter Avatar
Braunstetter Avatar Braunstetter | posted hace 3 meses | edited

This Autowire Annoation is very cool. I like to use the ParameterBag (ParameterBagInterface) object whenever I need some parameter inside my services.

But when I think about it more, it might be better for testing reasons to use the parameter itself inside the constructor.
Anyways I love to watch symfonycast videos even after all these years. It doesn't stop to be interesting.

Reply

Hey Braunstetter,

Yeah, it's always a trade-off :) That service is cool, but passing parameters into the constructor might be more straightforward and so simpler to test. Probably it depends on the number of parameters you need, if it's 1-3 params - I'd go with passing them into the constructor. If you need a lot of them - the service would be better in this case.

Cheers!

Reply

I like the Symfony 6.1 new addition on how to wire the service

Reply

Hey Joshua,

We're really happy to hear it, the new way is cool indeed :)

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "knplabs/knp-time-bundle": "^1.18", // v1.19.0
        "symfony/asset": "6.1.*", // v6.1.0-RC1
        "symfony/console": "6.1.*", // v6.1.0-RC1
        "symfony/dotenv": "6.1.*", // v6.1.0-RC1
        "symfony/flex": "^2", // v2.1.8
        "symfony/framework-bundle": "6.1.*", // v6.1.0-RC1
        "symfony/http-client": "6.1.*", // v6.1.0-RC1
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/runtime": "6.1.*", // v6.1.0-RC1
        "symfony/twig-bundle": "6.1.*", // v6.1.0-RC1
        "symfony/ux-turbo": "^2.0", // v2.1.1
        "symfony/webpack-encore-bundle": "^1.13", // v1.14.1
        "symfony/yaml": "6.1.*", // v6.1.0-RC1
        "twig/extra-bundle": "^2.12|^3.0", // v3.4.0
        "twig/twig": "^2.12|^3.0" // v3.4.0
    },
    "require-dev": {
        "symfony/debug-bundle": "6.1.*", // v6.1.0-RC1
        "symfony/maker-bundle": "^1.41", // v1.42.0
        "symfony/stopwatch": "6.1.*", // v6.1.0-RC1
        "symfony/web-profiler-bundle": "6.1.*" // v6.1.0-RC1
    }
}