<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 15103 -->
<!-- Reviewed: no -->
<sect3 id="zend.controller.router.routes.regex">
    <title>Zend_Controller_Router_Route_Regex</title>

    <para>
        Además de los tipos de ruta estáticos y por defecto, también está 
        disponible el tipo de ruta Expresión Regular. 
        Esta ruta ofrece más potencia y flexibilidad que los otros, pero a 
        costa de un ligero aumento en la complejidad. 
        Al mismo tiempo, debería ser más rápido que la standard Route.
    </para>

    <para>
        Al igual que la standard Route, esta ruta tiene que ser inicializada 
        con una definición de ruta y algunos valores predeterminados. 
        Vamos a crear un archivo ruta como un ejemplo, similar al previamente 
        definido, sólo que esta vez usaremos la ruta Regex:
    </para>

     <programlisting language="php"><![CDATA[
$route = new Zend_Controller_Router_Route_Regex(
    'archive/(\d+)',
    array(
        'controller' => 'archive',
        'action'     => 'show'
    )
);
$router->addRoute('archive', $route);
]]></programlisting>

    <para>
        Cada sub-patrón regex definido será inyectado al objeto solicitud. 
        Con nuestro ejemplo anterior, después de un matching exitoso
        <methodname>http://domain.com/archive/2006</methodname>, el valor resultante del 
        array puede verse como:
    </para>

     <programlisting language="php"><![CDATA[
$values = array(
    1            => '2006',
    'controller' => 'archive',
    'action'     => 'show'
);
]]></programlisting>

    <note>
        <para>
            Las barras de comienzo y final están recortadas de la URL en el 
            Router antes de una concordancia. Como resultado, coincidendo con 
            la URL <methodname>http://domain.com/foo/bar/</methodname>, involucraría al 
            regex de <methodname>foo/bar</methodname>, y no a <methodname>/foo/bar</methodname>.
        </para>
    </note>

    <note>
        <para>
            Las anclas de comienzo y fin de línea ('^' y '$', respectivamente) 
            son automáticamente antepuestas y pospuestas a todas las expresiones. 
            Así, no debe usar éstas en sus expresiones regulares, y debe 
            coincidir con el string completo.
        </para>
    </note>

    <note>
        <para>
            Esta clase de ruta usa el carácter <methodname>#</methodname> como un delimitador. 
            Esto significa que necesitará caracteres hash ('#') para escapar    
            pero no barras ('/') en sus definiciones de ruta. 
            Dado que el carácter '#' (llamado ancla) es raramente pasado al 
            webserver, será muy rara la necesidad de utilizar ese carácter en su 
            regex.
        </para>
    </note>

    <para>
        Puede obtener el contenido de los sub-patrones definidos por la forma habitual:
    </para>

     <programlisting language="php"><![CDATA[
public function showAction()
{
    $request = $this->getRequest();
    $year    = $request->getParam(1); // $year = '2006';
}
]]></programlisting>

    <note>
        <para>
        Tenga en cuenta que la clave es un entero (1) en lugar de un string ('1').
        </para>
    </note>

    <para>
        Sin embargo, esta ruta no funciona exactamente igual que su contraparte 
        standard route dado que el valor por defecto para 'year' todavía no se 
        ha establecido. Y lo que puede ser no tan evidente es que tendremos un 
        problema con una barra final incluso si declaramos por defecto el año y 
        hacemos opcional al sub-patrón. 
        La solución es hacer que toda la parte del año sea opcional junto con la 
        barra pero capturar solo la parte numérica:
    </para>

     <programlisting language="php"><![CDATA[
$route = new Zend_Controller_Router_Route_Regex(
    'archive(?:/(\d+))?',
    array(
        1            => '2006',
        'controller' => 'archive',
        'action'     => 'show'
    )
);
$router->addRoute('archive', $route);
]]></programlisting>

    <para>
        Ahora, ocupemósnos del problema que probablemente haya notado. 
		Utilizar claves basadas en enteros para los parámetros 
        no es una solución fácilmente manejable y puede ser potencialmente 
        problemática a largo plazo. Y aquí es donde entra el tercer 
        parámetro. Este parámetro es un array asociativo que representa un 
        mapa de sub-patrones regex a nombres de clave de parámetros. Trabajemos 
        en nuestro ejemplo más fácil:
    </para>

     <programlisting language="php"><![CDATA[
$route = new Zend_Controller_Router_Route_Regex(
    'archive/(\d+)',
    array(
        'controller' => 'archive',
        'action' => 'show'
    ),
    array(
        1 => 'year'
    )
);
$router->addRoute('archive', $route);
]]></programlisting>

    <para>
        Esto resultaraá en los siguientes valores inyectados a la solicitud:
    </para>

     <programlisting language="php"><![CDATA[
$values = array(
    'year'       => '2006',
    'controller' => 'archive',
    'action'     => 'show'
);
]]></programlisting>

    <para>
        El mapa puede ser definido en cualquier dirección para hacer que 
        funcione en cualquier ambiente. Las claves pueden contener nombres de 
        variables o índices de sub-patrones:
    </para>


     <programlisting language="php"><![CDATA[
$route = new Zend_Controller_Router_Route_Regex(
    'archive/(\d+)',
    array( ... ),
    array(1 => 'year')
);

// O

$route = new Zend_Controller_Router_Route_Regex(
    'archive/(\d+)',
    array( ... ),
    array('year' => 1)
);
]]></programlisting>

    <note>
        <para>
            Las claves de los sub-patrones deben respresentarse por enteros.
        </para>
    </note>

    <para>
        Observe que el índice numérico en los valores del Request ahora han  
        desaparecido y en su lugar se muestra una variable nombrada. 
        Por supuesto que puede mezclar variables nombradas y numéricas si lo desea:
    </para>

     <programlisting language="php"><![CDATA[
$route = new Zend_Controller_Router_Route_Regex(
    'archive/(\d+)/page/(\d+)',
    array( ... ),
    array('year' => 1)
);
]]></programlisting>

    <para>
        Lo que resultará en una mezcla de valores disponibles en la solicitud. 
        Como ejemplo, la URL <methodname>http://domain.com/archive/2006/page/10</methodname>  
        resultará con los siguientes valores:
    </para>

     <programlisting language="php"><![CDATA[
$values = array(
    'year'       => '2006',
    2            => 10,
    'controller' => 'archive',
    'action'     => 'show'
);
]]></programlisting>

    <para>
        Dado que los patrones regex no pueden invertirse fácilmente, tendrá que 
        preparar una URL inversa si desea usar un ayudante de URL o incluso 
        un método de ensamble de esta clase. Este path inverso está representado 
        por un string parseable por sprintf() y se define como el cuarto 
        parámetro del constructor:
    </para>

     <programlisting language="php"><![CDATA[
$route = new Zend_Controller_Router_Route_Regex(
    'archive/(\d+)',
    array( ... ),
    array('year' => 1),
    'archive/%s'
);
]]></programlisting>

    <para>
        Todo esto es algo que ya fue posible de hacer por medio de un objeto 
        de ruta estandard, por lo tanto podría preguntarese: ¿cuál es la ventaja 
        de utilizar la ruta Regex?. 
        Principalmente, le permite describir cualquier tipo de URL sin 
        restricción alguna. Imagínese que tiene un blog y desea crear URLs 
        como: <methodname>http://domain.com/blog/archive/01-Using_the_Regex_Router.html</methodname>, 
        y que tiene que descomponer el último elemento del path 
        <methodname>01-Using_the_Regex_Router.html</methodname>, en un ID de artículo y 
        en el título/descripción del artículo; esto no es posible con el 
        standard route. Con la ruta Regex, puede hacer algo como la siguiente 
        solución:
    </para>

     <programlisting language="php"><![CDATA[
$route = new Zend_Controller_Router_Route_Regex(
    'blog/archive/(\d+)-(.+)\.html',
    array(
        'controller' => 'blog',
        'action'     => 'view'
    ),
    array(
        1 => 'id',
        2 => 'description'
    ),
    'blog/archive/%d-%s.html'
);
$router->addRoute('blogArchive', $route);
]]></programlisting>

    <para>
        Como puede ver, esto añade una enorme cantidad de flexibilidad por  
        encima del standard route.
    </para>
</sect3>
<!--
vim:se ts=4 sw=4 et:
-->
