If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeAbre src/Controller/VinylController.php
. ¡Puede que sea obvio o no, pero nuestras clases de controlador también son servicios en el contenedor! ¡Sí! Se sienten especiales porque son controladores... pero en realidad sólo son viejos y aburridos servicios como todo lo demás. Bueno, excepto que tienen un superpoder que no tiene nada más: la capacidad de autoconectar argumentos en sus métodos de acción. Normalmente, el autocableado sólo funciona con el constructor.
Los métodos de acción funcionan realmente como los constructores en lo que respecta a la autoconexión. Por ejemplo, añade un argumento bool $isDebug
a la acción browse()
... y a continuación dump($isDebug)
:
... lines 1 - 6 | |
use Symfony\Component\Console\Input\ArrayInput; | |
use Symfony\Component\Console\Output\BufferedOutput; | |
... lines 9 - 13 | |
class MixRepository | |
{ | |
... lines 16 - 24 | |
public function findAll(): array | |
{ | |
$output = new BufferedOutput(); | |
$this->twigDebugCommand->run(new ArrayInput([]), $output); | |
dd($output); | |
... lines 30 - 35 | |
} | |
} |
Y eso... ¡no funciona! Hasta ahora, las únicas dos cosas que sabemos que podemos tener como argumentos de nuestras "acciones" son (A), cualquier comodín en la ruta como$slug
y (B) los servicios autocableables, como MixRepository
.
Pero ahora, vuelve a config/services.yaml
y descomenta el global bind
de antes:
... lines 1 - 12 | |
services: | |
# default configuration for services in *this* file | |
_defaults: | |
... lines 16 - 17 | |
bind: | |
'bool $isDebug': '%kernel.debug%' | |
... lines 20 - 32 |
Esta vez... ¡funciona!
Yendo en la otra dirección, como los controladores son servicios, puedes absolutamente tener un constructor si quieres. Movamos MixRepository
y $isDebug
a un nuevo constructor. Cópialos, quítalos... añade public function __construct()
, pégalos... y luego los pondré en sus propias líneas. Para convertirlos en propiedades, añadeprivate
delante de cada uno:
... lines 1 - 10 | |
class VinylController extends AbstractController | |
{ | |
public function __construct( | |
private bool $isDebug, | |
private MixRepository $mixRepository | |
) | |
{} | |
... lines 18 - 36 | |
'/browse/{slug}', name: 'app_browse') ( | |
public function browse(string $slug = null): Response | |
{ | |
... lines 40 - 48 | |
} | |
} |
De nuevo abajo, sólo tenemos que asegurarnos de cambiar a dump($this->isDebug)
y añadir $this->
delante de mixRepository
:
... lines 1 - 10 | |
class VinylController extends AbstractController | |
{ | |
public function __construct( | |
private bool $isDebug, | |
private MixRepository $mixRepository | |
) | |
{} | |
... lines 18 - 36 | |
'/browse/{slug}', name: 'app_browse') ( | |
public function browse(string $slug = null): Response | |
{ | |
dump($this->isDebug); | |
... lines 41 - 42 | |
$mixes = $this->mixRepository->findAll(); | |
... lines 44 - 48 | |
} | |
} |
¡Bien! Si probamos esto ahora... ¡funciona bien!
Normalmente no sigo este enfoque... principalmente porque añadir argumentos al método de acción es muy fácil. Pero si necesitas un servicio u otro valor en cada método de acción de tu clase, definitivamente puedes limpiar tu lista de argumentos inyectándola a través del constructor. Voy a eliminar ese dump()
.
A continuación, vamos a hablar de las variables de entorno y de la finalidad del archivo .env
que hemos visto antes. Estas cosas serán cada vez más importantes a medida que hagamos nuestra aplicación más y más realista.
"Houston: no signs of life"
Start the conversation!
// 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
}
}