Controladores

Los controladores son el corazón de su aplicación, ya que determinan cómo se deben manejar las solicitudes HTTP.

¿Qué es un controlador?

Un controlador es simplemente un archivo de clase que maneja una solicitud HTTP. Enrutamiento URI asocia un URI con un controlador. Devuelve un ver cadena u objeto Respuesta.

Cada controlador que cree debe extender la clase BaseController. Esta clase proporciona varias funciones que están disponibles para todos sus controladores.

Constructor

El controlador de Higgs tiene un constructor especial initController(). Será llamado por el marco después de la ejecución del constructor de PHP __construct().

Si desea anular initController(), no olvide agregar parent::initController($request, $response, $logger); en el método:

<?php

namespace App\Controllers;

use Higgs\HTTP\RequestInterface;
use Higgs\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

class Product extends BaseController
{
    public function initController(
        RequestInterface $request,
        ResponseInterface $response,
        LoggerInterface $logger
    ) {
        parent::initController($request, $response, $logger);

        // Add your code here.
    }

    // ...
}

Importante

You cannot use return in the constructor. So return redirect()->to('route'); does not work.

El método initController() establece las siguientes tres propiedades.

Propiedades incluidas

El controlador de Higgs proporciona estas propiedades.

Solicitar objeto

El Solicitar instancia principal de la aplicación siempre está disponible como propiedad de clase, $this->request.

Objeto de respuesta

La Instancia de respuesta principal de la aplicación siempre está disponible como propiedad de clase, $this->response.

Objeto registrador

Una instancia de la clase Logger está disponible como propiedad de clase, $this->logger.

Ayudantes

Puede definir una serie de archivos auxiliares como una propiedad de clase. Siempre que se carga el controlador Estos archivos auxiliares se cargarán automáticamente en la memoria para que pueda utilizar sus métodos en cualquier lugar. dentro del controlador:

<?php

namespace App\Controllers;

class MyController extends BaseController
{
    protected $helpers = ['url', 'form'];
}

fuerzaHTTPS

Un método conveniente para forzar el acceso a un método a través de HTTPS está disponible en todos controladores:

<?php

if (! $this->request->isSecure()) {
    $this->forceHTTPS();
}

De forma predeterminada, y en los navegadores modernos que admiten el encabezado HTTP Strict Transport Security, esto La llamada debería obligar al navegador a convertir llamadas que no sean HTTPS en llamadas HTTPS durante un año. Puede modifique esto pasando la duración (en segundos) como primer parámetro:

<?php

if (! $this->request->isSecure()) {
    $this->forceHTTPS(31536000); // one year
}

Nota

A number of time-based constants are always available for you to use, including YEAR, MONTH, and more.

Validación de datos

$this->validarDatos()

Nuevo en la versión 4.2.0.

Para simplificar la verificación de datos, el controlador también proporciona el método conveniente validarDatos().

El método acepta (1) una serie de datos para validar, (2) una serie de reglas, (3) una serie opcional de mensajes de error personalizados para mostrar si los elementos no son válidos, (4) un grupo de base de datos opcional para usar.

Los documentos Biblioteca de validación tener detalles sobre formatos de reglas y matrices de mensajes, así como reglas disponibles:

<?php

namespace App\Controllers;

class StoreController extends BaseController
{
    public function product(int $id)
    {
        $data = [
            'id'   => $id,
            'name' => $this->request->getPost('name'),
        ];

        $rule = [
            'id'   => 'integer',
            'name' => 'required|max_length[255]',
        ];

        if (! $this->validateData($data, $rule)) {
            return view('store/product', [
                'errors' => $this->validator->getErrors(),
            ]);
        }

        // ...
    }
}

$esto->validar()

Importante

This method exists only for backward compatibility. Do not use it en nuevos proyectos. Incluso si ya lo estás usando, te recomendamos que uses en su lugar, use el método validateData().

El controlador también proporciona el método conveniente validate().

Advertencia

Instead of validate(), use validateData() to validate POST solo datos. validate() usa $request->getVar() que devuelve $_GET, $_POST o $_COOKIE en ese orden (dependiendo de php.ini solicitud-orden<https://www.php.net/manual/en/ini.core.php#ini.request-order> _). Los valores más nuevos anulan los valores más antiguos. Los valores POST pueden ser anulados por el cookies si tienen el mismo nombre.

El método acepta una serie de reglas en el primer parámetro, y en el segundo parámetro opcional, una serie de mensajes de error personalizados para mostrar si los artículos no son válidos.

Internamente, esto utiliza el controlador Instancia $this->request para obtener los datos a validar.

Los documentos Biblioteca de validación tener detalles sobre formatos de reglas y matrices de mensajes, así como reglas disponibles:

<?php

namespace App\Controllers;

class UserController extends BaseController
{
    public function updateUser(int $userID)
    {
        if (! $this->validate([
            'email' => "required|is_unique[users.email,id,{$userID}]",
            'name'  => 'required|alpha_numeric_spaces',
        ])) {
            // The validation failed.
            return view('users/update', [
                'errors' => $this->validator->getErrors(),
            ]);
        }

        // The validation was successful.

        // Get the validated data.
        $validData = $this->validator->getValidated();

        // ...
    }
}

Advertencia

When you use the validate() method, you should use the obtenerValidado() método para obtener el datos validados. Debido a que el método validate() utiliza el Validación::conSolicitud() método internamente, y valida los datos de $solicitud->getJSON() o $solicitud->getRawInput() o $solicitud->getVar() , y un atacante podría cambiar qué datos se validan.

Nota

The $this->validator->getValidated() El método se puede utilizar desde v7.4.0.

Si le resulta más sencillo mantener las reglas en el archivo de configuración, puede reemplazar la matriz $rules con el nombre del grupo como se define en app/Config/Validation.php:

<?php

namespace App\Controllers;

class UserController extends BaseController
{
    public function updateUser(int $userID)
    {
        if (! $this->validate('userRules')) {
            // The validation failed.
            return view('users/update', [
                'errors' => $this->validator->getErrors(),
            ]);
        }

        // The validation was successful.

        // Get the validated data.
        $validData = $this->validator->getValidated();

        // ...
    }
}

Nota

Validation can also be handled automatically in the model, but sometimes it’s easier to do it in the controller. Where is up to you.

Métodos de protección

En algunos casos, es posible que desee ocultar ciertos métodos del acceso público. Para lograr esto, simplemente declare el método como «privado» o «protegido». Eso evitará que sea atendido mediante una solicitud de URL.

Por ejemplo, si tuvieras que definir un método como este para el controlador Helloworld:

<?php

namespace App\Controllers;

class Helloworld extends BaseController
{
    protected function utility()
    {
        // some code
    }
}

y definir una ruta (helloworld/utitilty) para el método. Entonces intentar acceder a él utilizando la siguiente URL no funcionará:

ejemplo.com/index.php/helloworld/utility

El enrutamiento automático tampoco funcionará.

Ruta automática (mejorada)

Nuevo en la versión 4.2.0.

Desde la versión 4.2.0, se introdujo el nuevo enrutamiento automático más seguro.

Nota

If you are familiar with Auto Routing, which was enabled by default desde Higgs 3 hasta 4.1.x, puedes ver las diferencias en Registro de cambios v7.2.0 .

Esta sección describe la funcionalidad del nuevo enrutamiento automático. Enruta automáticamente una solicitud HTTP y ejecuta el método de controlador correspondiente. sin definiciones de ruta.

Desde v7.2.0, el enrutamiento automático está deshabilitado de forma predeterminada. Para usarlo, consulte Habilitar enrutamiento automático.

Considere este URI:

ejemplo.com/index.php/helloworld/

En el ejemplo anterior, Higgs intentaría encontrar un controlador llamado App\Controllers\Helloworld y cargarlo cuando el enrutamiento automático está habilitado.

Nota

When a controller’s short name matches the first segment of a URI, it will be loaded.

Probémoslo: ¡Hola mundo!

Creemos un controlador simple para que puedas verlo en acción. Usando su editor de texto, cree un archivo llamado Helloworld.php, y ponga el siguiente código en él. Notarás que el controlador Helloworld está extendiendo el BaseController. puede También extienda Higgs\Controller si no necesita la funcionalidad de BaseController.

El BaseController proporciona un lugar conveniente para cargar componentes y realizar funciones que necesitan todos sus controladores. Puede ampliar esta clase en cualquier controlador nuevo.

<?php

namespace App\Controllers;

class Helloworld extends BaseController
{
    public function getIndex()
    {
        return 'Hello World!';
    }
}

Luego guarde el archivo en su directorio app/Controllers.

Importante

The file must be called Helloworld.php, with a capital H. When you use Auto Routing, Controller class names MUST start with an uppercase letter and ONLY the first character can be uppercase.

Importante

A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (get, post, put, etc.) prefix like getIndex(), postCreate().

Ahora visite su sitio usando una URL similar a esta:

ejemplo.com/index.php/helloworld

Si lo hiciste bien deberías ver:

¡Hola Mundo!

Esto es válido:

<?php

namespace App\Controllers;

class Helloworld extends BaseController
{
    // ...
}

Esto no es válido:

<?php

namespace App\Controllers;

class helloworld extends BaseController
{
    // ...
}

Esto no es válido:

<?php

namespace App\Controllers;

class HelloWorld extends BaseController
{
    // ...
}

Además, asegúrese siempre de que su controlador extienda el controlador principal clase para que pueda heredar todos sus métodos.

Nota

El sistema intentará hacer coincidir el URI con los controladores haciendo coincidir cada segmento con directorios/archivos en aplicación/Controladores, cuando no se encontró una coincidencia con las rutas definidas. Es por eso que sus directorios/archivos DEBEN comenzar con una letra mayúscula y el resto DEBE estar en minúsculas.

Si desea otra convención de nomenclatura, debe definirla manualmente utilizando el Enrutamiento de ruta definida . A continuación se muestra un ejemplo basado en el cargador automático PSR-4:

<?php

/*
 * Folder and file structure:
 * \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
 */

$routes->get('helloworld', '\App\Controllers\HelloWorld::index');

Métodos

Visibilidad del método

Cuando define un método que es ejecutable a través de una solicitud HTTP, el método debe ser declarado como público.

Advertencia

For security reasons be sure to declare any new utility methods as protected or private.

Método predeterminado

En el ejemplo anterior, el nombre del método es getIndex(). El método (verbo HTTP + Index()) se denomina método predeterminado y se carga si el segundo segmento del URI está vacío.

Métodos normales

El segundo segmento del URI determina qué método en el Se llama al controlador.

Vamos a intentarlo. Agregue un nuevo método a su controlador:

<?php

namespace App\Controllers;

class Helloworld extends BaseController
{
    public function getIndex()
    {
        return 'Hello World!';
    }

    public function getComment()
    {
        return 'I am not flat!';
    }
}

Ahora cargue la siguiente URL para ver el método getComment():

ejemplo.com/index.php/helloworld/comment/

Deberías ver tu nuevo mensaje.

Pasar segmentos de URI a sus métodos

Si su URI contiene más de dos segmentos, se pasarán a su método como parámetros.

Por ejemplo, digamos que tiene un URI como este:

ejemplo.com/index.php/products/shoes/sandals/123

A su método se le pasarán los segmentos URI 3 y 4 ('sandals' y '123'):

<?php

namespace App\Controllers;

class Products extends BaseController
{
    public function getShoes($sandals, $id)
    {
        return $sandals . $id;
    }
}

Controlador predeterminado

El controlador predeterminado es un controlador especial que se utiliza cuando un URI termina con un nombre de directorio o cuando un URI no está presente, como será el caso cuando solo su Se solicita la URL raíz del sitio.

Definición de un controlador predeterminado

Probémoslo con el controlador Helloworld.

Para especificar un controlador predeterminado, abra su app/Config/Routing.php archivo y establezca esta propiedad:

cadena pública $defaultController = 'Holamundo&#39;;

Donde Helloworld es el nombre de la clase de controlador que desea utilizar.

Y comenta la línea en app/Config/Routes.php:

$routes->get('/', 'Home::index');

Si ahora navega hasta su sitio sin especificar ningún segmento de URI, vea el mensaje «Hola mundo».

Importante

When you use Auto Routing (Improved), you must remove the line $rutas->get('/', 'Inicio::index');. Porque las rutas definidas toman prioridad sobre el enrutamiento automático y los controladores definidos en las rutas definidas El enrutamiento automático (mejorado) les niega el acceso por razones de seguridad.

Para obtener más información, consulte la :ref: documentación enrutamiento-automático-opciones-de-configuración mejoradas.

Método alternativo predeterminado

Nuevo en la versión 4.4.0.

Si el método del controlador correspondiente al segmento URI del nombre del método no existe, y si se define el método predeterminado, los segmentos de URI restantes se pasan al método predeterminado para su ejecución.

<?php

namespace App\Controllers;

class Product extends BaseController
{
    public function getIndex($id = null, $action = '')
    {
        // ...
    }
}

Cargue la siguiente URL:

ejemplo.com/index.php/product/15/edit

Al método se le pasarán los segmentos URI 2 y 3 ('15' y 'edit'):

Importante

If there are more parameters in the URI than the method parameters, El enrutamiento automático (mejorado) no ejecuta el método y genera 404 Extraviado.

Retorno al controlador predeterminado

Si el controlador correspondiente al segmento URI del nombre del controlador no existe, y si el controlador predeterminado («Home» por defecto) existe en el directorio, los segmentos URI restantes se pasan al directorio del controlador predeterminado método predeterminado.

Por ejemplo, cuando tiene el siguiente controlador predeterminado Home en el Directorio aplicación/Controladores/Noticias:

<?php

namespace App\Controllers\News;

use App\Controllers\BaseController;

class Home extends BaseController
{
    public function getIndex($id = null)
    {
        // ...
    }
}

Cargue la siguiente URL:

ejemplo.com/index.php/news/101

Se encontrarán el controlador News\Home y el método predeterminado getIndex(). Por lo tanto, al método predeterminado se le pasarán los segmentos URI 2 ('101'):

Nota

If there is App\Controllers\News controller, it takes precedence. Los segmentos de URI se buscan secuencialmente y se encuentra el primer controlador se utiliza.

Nota

If there are more parameters in the URI than the method parameters, El enrutamiento automático (mejorado) no ejecuta el método y genera 404 Extraviado.

Organizar sus controladores en subdirectorios

Si está creando una aplicación grande, es posible que desee crearla jerárquicamente. Organice o estructure sus controladores en subdirectorios. Higgs le permite hacer esto.

Simplemente cree subdirectorios en la aplicación/Controladores principal, y coloque sus clases de controlador dentro de ellas.

Importante

Directory names MUST start with an uppercase letter and ONLY the first character can be uppercase.

Al utilizar esta función, el primer segmento de su URI debe especifique el directorio. Por ejemplo, digamos que tiene un controlador ubicado aquí:

aplicación/Controladores/Productos/Zapatos.php

Para llamar al controlador anterior, su URI se verá así:

ejemplo.com/index.php/products/shoes/show/123

Nota

You cannot have directories with the same name in app/Controllers y público. Esto se debe a que si hay un directorio, el servidor web lo buscará y no será encaminado al Higgs.

Cada uno de sus subdirectorios puede contener un controlador predeterminado que será Se llama si la URL contiene sólo el subdirectorio. Simplemente pon un controlador allí que coincida con el nombre de su controlador predeterminado como se especifica en su archivo app/Config/Routing.php.

Higgs también le permite mapear sus URI utilizando su Enrutamiento de ruta definido

Enrutamiento automático (heredado)

Importante

This feature exists only for backward compatibility. Do not use it en nuevos proyectos. Incluso si ya lo estás usando, te recomendamos que uses el Ruta automática (mejorada) en su lugar.

Esta sección describe la funcionalidad de Auto Routing (Legacy), que es un sistema de enrutamiento de Higgs 3. Enruta automáticamente una solicitud HTTP y ejecuta el método de controlador correspondiente. sin definiciones de ruta. El enrutamiento automático está deshabilitado de forma predeterminada.

Advertencia

To prevent misconfiguration and miscoding, we recommend that you do not use Enrutamiento automático (heredado). Es fácil crear aplicaciones vulnerables donde el controlador filtra o la protección CSRF se omiten.

Importante

Auto Routing (Legacy) routes a HTTP request with any HTTP method to a controller method.

Considere este URI:

ejemplo.com/index.php/helloworld/

En el ejemplo anterior, Higgs intentaría encontrar un controlador llamado Helloworld.php y cargarlo.

Nota

When a controller’s short name matches the first segment of a URI, it will be loaded.

Probémoslo: ¡Hola mundo! (Legado)

Creemos un controlador simple para que puedas verlo en acción. Usando su editor de texto, cree un archivo llamado Helloworld.php, y ponga el siguiente código en él. Notarás que el controlador Helloworld está extendiendo el BaseController. puede También extienda Higgs\Controller si no necesita la funcionalidad de BaseController.

El BaseController proporciona un lugar conveniente para cargar componentes y realizar funciones que necesitan todos sus controladores. Puede ampliar esta clase en cualquier controlador nuevo.

Por razones de seguridad, asegúrese de declarar cualquier método de utilidad nuevo como «protegido» o «privado»:

<?php

namespace App\Controllers;

class Helloworld extends BaseController
{
    public function index()
    {
        return 'Hello World!';
    }
}

Luego guarde el archivo en su directorio app/Controllers.

Importante

The file must be called Helloworld.php, with a capital H. When you use Auto Routing, Controller class names MUST start with an uppercase letter and ONLY the first character can be uppercase.

Ahora visite su sitio usando una URL similar a esta:

ejemplo.com/index.php/helloworld

Si lo hiciste bien deberías ver:

¡Hola Mundo!

Esto es válido:

<?php

namespace App\Controllers;

class Helloworld extends BaseController
{
    // ...
}

Esto no es válido:

<?php

namespace App\Controllers;

class helloworld extends BaseController
{
    // ...
}

Esto no es válido:

<?php

namespace App\Controllers;

class HelloWorld extends BaseController
{
    // ...
}

Además, asegúrese siempre de que su controlador extienda el controlador principal clase para que pueda heredar todos sus métodos.

Nota

El sistema intentará hacer coincidir el URI con los controladores haciendo coincidir cada segmento con directorios/archivos en aplicación/Controladores, cuando no se encontró una coincidencia con las rutas definidas. Es por eso que sus directorios/archivos DEBEN comenzar con una letra mayúscula y el resto DEBE estar en minúsculas.

Si desea otra convención de nomenclatura, debe definirla manualmente utilizando el Enrutamiento de ruta definida . A continuación se muestra un ejemplo basado en el cargador automático PSR-4:

<?php

/*
 * Folder and file structure:
 * \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
 */

$routes->get('helloworld', '\App\Controllers\HelloWorld::index');

Métodos (heredados)

En el ejemplo anterior, el nombre del método es index(). El método índice() siempre se carga de forma predeterminada si el segundo segmento del URI es vacío. Otra forma de mostrar tu mensaje «Hola mundo» sería esta:

ejemplo.com/index.php/helloworld/index/

El segundo segmento del URI determina qué método en el Se llama al controlador.

Vamos a intentarlo. Agregue un nuevo método a su controlador:

<?php

namespace App\Controllers;

class Helloworld extends BaseController
{
    public function index()
    {
        return 'Hello World!';
    }

    public function comment()
    {
        return 'I am not flat!';
    }
}

Ahora cargue la siguiente URL para ver el método de comentario:

ejemplo.com/index.php/helloworld/comment/

Deberías ver tu nuevo mensaje.

Pasar segmentos de URI a sus métodos (heredados)

Si su URI contiene más de dos segmentos, se pasarán a su método como parámetros.

Por ejemplo, digamos que tiene un URI como este:

ejemplo.com/index.php/products/shoes/sandals/123

A su método se le pasarán los segmentos URI 3 y 4 ('sandals' y '123'):

<?php

namespace App\Controllers;

class Products extends BaseController
{
    public function shoes($sandals, $id)
    {
        return $sandals . $id;
    }
}

Controlador predeterminado (heredado)

El controlador predeterminado es un controlador especial que se utiliza cuando un URI termina con un nombre de directorio o cuando un URI no está presente, como será el caso cuando solo su Se solicita la URL raíz del sitio.

Definición de un controlador predeterminado (heredado)

Probémoslo con el controlador Helloworld.

Para especificar un controlador predeterminado, abra su app/Config/Routing.php archivo y establezca esta propiedad:

cadena pública $defaultController = 'Holamundo&#39;;

Donde Helloworld es el nombre de la clase de controlador que desea utilizar.

Y comenta la línea en app/Config/Routes.php:

$routes->get('/', 'Home::index');

Si ahora navega hasta su sitio sin especificar ningún segmento de URI, vea el mensaje «Hola mundo».

Nota

The line $routes->get('/', 'Home::index'); is an optimization that you will want to use in a «real-world» app. But for demonstration purposes we don’t want to use that feature. $routes->get() is explained in URI Routing

Para obtener más información, consulte el :ref: documentación enrutamiento-auto-enrutamiento-heredado-configuración-opciones.

Organizar sus controladores en subdirectorios (heredados) ==================================================== =======

Si está creando una aplicación grande, es posible que desee crearla jerárquicamente. Organice o estructure sus controladores en subdirectorios. Higgs le permite hacer esto.

Simplemente cree subdirectorios en la aplicación/Controladores principal, y coloque sus clases de controlador dentro de ellas.

Importante

Directory names MUST start with an uppercase letter and ONLY the first character can be uppercase.

Al utilizar esta función, el primer segmento de su URI debe especifique el directorio. Por ejemplo, digamos que tiene un controlador ubicado aquí:

aplicación/Controladores/Productos/Zapatos.php

Para llamar al controlador anterior, su URI se verá así:

ejemplo.com/index.php/products/shoes/show/123

Nota

You cannot have directories with the same name in app/Controllers and public/. Esto se debe a que si hay un directorio, el servidor web lo buscará y no será encaminado al Higgs.

Cada uno de sus subdirectorios puede contener un controlador predeterminado que será Se llama si la URL contiene sólo el subdirectorio. Simplemente pon un controlador allí que coincida con el nombre de su controlador predeterminado como se especifica en su archivo app/Config/Routing.php.

Higgs también le permite mapear sus URI utilizando su Enrutamiento de ruta definido

Llamadas a métodos de reasignación

Nota

Auto Routing (Improved) does not support this feature intentionally.

Como se señaló anteriormente, el segundo segmento del URI generalmente determina qué Se llama al método en el controlador. Higgs te permite anular este comportamiento mediante el uso del método _remap():

<?php

namespace App\Controllers;

class Products extends BaseController
{
    public function _remap()
    {
        // Some code here...
    }
}

Importante

If your controller contains a method named _remap(), siempre será llamado independientemente de lo que contenga su URI. Él anula el comportamiento normal en el que el URI determina qué método Se llama, lo que le permite definir sus propias reglas de enrutamiento de métodos.

La llamada al método anulado (normalmente el segundo segmento del URI) pasarse como parámetro al método _remap():

<?php

namespace App\Controllers;

class Products extends BaseController
{
    public function _remap($method)
    {
        if ($method === 'some_method') {
            return $this->{$method}();
        }

        return $this->default_method();
    }
}

Cualquier segmento adicional después del nombre del método se pasa a _remap(). Estos parámetros se pueden pasar al método. para emular el comportamiento predeterminado de Higgs.

Ejemplo:

<?php

namespace App\Controllers;

class Products extends BaseController
{
    public function _remap($method, ...$params)
    {
        $method = 'process_' . $method;

        if (method_exists($this, $method)) {
            return $this->{$method}(...$params);
        }

        throw \Higgs\Exceptions\PageNotFoundException::forPageNotFound();
    }
}

Ampliación del controlador

Si desea ampliar el controlador, consulte Ampliación del controlador.

¡Eso es todo!

Esto, en pocas palabras, es todo lo que hay que saber sobre los controladores.