> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Controladores

> Explicamos cómo crear controladores en Laravel y cómo se conectan con el enrutamiento.

## ¿Qué es un controlador?

En lugar de definir toda la lógica de manejo de solicitudes como closures dentro de los archivos de rutas, puedes organizar ese comportamiento usando clases "controladoras".
Los controladores permiten agrupar la lógica de manejo de solicitudes relacionadas en una única clase.

Por ejemplo, la clase `UserController` puede manejar todas las solicitudes entrantes sobre usuarios: mostrar, crear, actualizar y eliminar.
Por defecto, los controladores se guardan en el directorio `app/Http/Controllers`.

## Crear un controlador

Para crear un nuevo controlador rápidamente, usa el comando Artisan `make:controller`.
Todos los controladores de la aplicación se guardan por defecto en el directorio `app/Http/Controllers`.

```shell theme={null}
php artisan make:controller UserController
```

## Controlador básico

Una clase controladora puede tener varios métodos públicos que respondan a las solicitudes HTTP entrantes.

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Muestra el perfil del usuario indicado
     */
    public function show(string $id): View
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}
```

Tras crear la clase y el método, puedes definir una ruta al método así:

```php theme={null}
use App\Http\Controllers\UserController;

Route::get('/user/{id}', [UserController::class, 'show']);
```

Cuando una solicitud entrante coincide con el URI de la ruta, se llama al método `show` de la clase `App\Http\Controllers\UserController` y se le pasan los parámetros de la ruta.

<Info>
  No es necesario que el controlador extienda una clase base. Sin embargo, puede ser útil extender una clase base cuando tienes métodos que deben compartir todos los controladores.
</Info>

## Controladores de una sola acción

Si la acción de un controlador es especialmente compleja, puede ser útil dedicar toda la clase a esa única acción.
Para ello, define un único método `__invoke` dentro del controlador.

```php theme={null}
<?php

namespace App\Http\Controllers;

class ProvisionServer extends Controller
{
    /**
     * Provisiona un nuevo servidor web
     */
    public function __invoke()
    {
        // ...
    }
}
```

Al registrar la ruta de un controlador de una sola acción no hace falta indicar el método.
Basta con pasar el nombre del controlador al router.

```php theme={null}
use App\Http\Controllers\ProvisionServer;

Route::post('/server', ProvisionServer::class);
```

Con la opción `--invokable` de `make:controller` puedes generar un controlador invocable.

```shell theme={null}
php artisan make:controller ProvisionServer --invokable
```

## Resource controllers

Si consideras cada modelo Eloquent de tu aplicación como un "recurso", es habitual realizar el mismo conjunto de operaciones (CRUD) sobre cada uno.
El enrutamiento de recursos de Laravel asigna las rutas típicas de creación/lectura/actualización/eliminación (CRUD) a un controlador con una sola línea de código.

Con la opción `--resource` del comando `make:controller` puedes generar rápidamente un controlador que gestione esas acciones.

```shell theme={null}
php artisan make:controller PhotoController --resource
```

Este comando genera un controlador en `app/Http/Controllers/PhotoController.php`.
El controlador incluye stubs para cada una de las operaciones de recurso disponibles.
A continuación, registra la ruta de recurso que apunta al controlador.

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class);
```

Esta única declaración de ruta crea múltiples rutas para manejar las diversas acciones sobre el recurso.
El controlador generado ya contiene stubs para cada una de esas acciones.

| Método HTTP | URI                    | Acción  | Nombre de ruta |
| ----------- | ---------------------- | ------- | -------------- |
| GET         | `/photos`              | index   | photos.index   |
| GET         | `/photos/create`       | create  | photos.create  |
| POST        | `/photos`              | store   | photos.store   |
| GET         | `/photos/{photo}`      | show    | photos.show    |
| GET         | `/photos/{photo}/edit` | edit    | photos.edit    |
| PUT/PATCH   | `/photos/{photo}`      | update  | photos.update  |
| DELETE      | `/photos/{photo}`      | destroy | photos.destroy |

<Info>
  Ejecutando `php artisan route:list` puedes ver rápidamente el resumen de las rutas de la aplicación.
</Info>

### Rutas de recurso parciales

Al declarar rutas de recurso puedes indicar un subconjunto de acciones que el controlador debe manejar.

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class)->only([
    'index', 'show'
]);

Route::resource('photos', PhotoController::class)->except([
    'create', 'store', 'update', 'destroy'
]);
```

### Rutas de recurso para API

Al declarar rutas de recurso para una API, es frecuente querer excluir rutas como `create` o `edit`, que muestran plantillas HTML.
Con el método `apiResource` puedes excluir automáticamente esas dos rutas.

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::apiResource('photos', PhotoController::class);
```

## Inyección de dependencias

### Inyección por constructor

El contenedor de servicios de Laravel se usa para resolver las dependencias de todos los controladores.
Por eso puedes indicar mediante type-hint en el constructor las dependencias que necesita el controlador.
Las dependencias declaradas se resuelven automáticamente y se inyectan en la instancia del controlador.

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * Crea una nueva instancia del controlador
     */
    public function __construct(
        protected UserRepository $users,
    ) {}
}
```

### Inyección por método

Además de la inyección por constructor, también puedes tipar dependencias en los métodos del controlador.
Un caso habitual es inyectar una instancia de `Illuminate\Http\Request` en el método del controlador.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Guarda un nuevo usuario
     */
    public function store(Request $request): RedirectResponse
    {
        $name = $request->name;

        // Procesamiento para guardar el usuario...

        return redirect('/users');
    }
}
```

Si el método del controlador también recibe entradas de parámetros de ruta, lista los argumentos de la ruta después de las otras dependencias.
Por ejemplo, supongamos que se define la siguiente ruta:

```php theme={null}
use App\Http\Controllers\UserController;

Route::put('/user/{id}', [UserController::class, 'update']);
```

Puedes definir el método del controlador así, para tipar `Illuminate\Http\Request` y acceder también al parámetro `id`:

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Actualiza el usuario indicado
     */
    public function update(Request $request, string $id): RedirectResponse
    {
        // Actualización del usuario...

        return redirect('/users');
    }
}
```

<Tip>
  Aprovechar la inyección de dependencias facilita sustituir por mocks en las pruebas y mejora la testabilidad del código.
</Tip>

## Próximos pasos

<Card title="Enrutamiento" icon="route" href="/es/routing">
  Repasa cómo definir rutas y su relación con los controladores.
</Card>


## Related topics

- [Presentación de Laravel Wayfinder](/es/blog/wayfinder-introduction.md)
- [Desarrollar paquetes con Testbench Workbench](/es/advanced/package-workbench.md)
- [Solicitudes HTTP](/es/requests.md)
- [Resumen de las novedades de Laravel 13](/es/blog/laravel-13-new-features.md)
- [Enrutamiento](/es/routing.md)
