Eliminar ‘index.php’ de Laravel 4.1 en Apache 2 con mod_rewrite

Una vez que hayamos instalado Laravel, el acceso a los recursos precisa que las URLs queden como http://localhost/index.php/resource/. Sería más bonito poder quitar ese ‘index.php’, ¿verdad? Laravel incluye un archivo .htaccess en el directorio ‘public’ que sirve para reescribir las URLs internamente y que éstas sean como http://localhost/resource/.

Este archivo ‘.htacces’ contiene lo siguiente:

<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>

RewriteEngine On

# Redirect Trailing Slashes…
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Handle Front Controller…
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

Como podemos ver, este archivo habilita el RewriteEngine, pero para ello necesita el módulo mod_rewrite habilitado en Apache. Usaremos el siguiente comando para habilitarlo:

$ sudo a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
service apache2 restart

Es posible que con esto no sea suficiente, ya que la configuración del VirtualHost default contiene una directiva AllowOverride None que impide que .htaccess funcione. Así que tendremos que editar el archivo de configuración del VirtualHost (/etc/apache2/sites-available/default) y cambiar ‘AllowOverride None’ por ‘AllowOverride All’.

Una vez tengamos habilitado el módulo mod_rewrite y configurada la directiva AllowOverride All, reiniciamos Apache:

$ sudo service apache2 restart
* Restarting web server apache2                                                                                                                                                 apache2: Could not reliably determine the server’s fully qualified domain name, using 127.0.1.1 for ServerName
… waiting apache2: Could not reliably determine the server’s fully qualified domain name, using 127.0.1.1 for ServerName
[ OK ]

Ya podremos navegar por nuestra aplicación web sin tener que usar ‘index.php’.

Anuncios

short_open_tag, .htaccess y AllowOverride

El otro día me dieron el CD de una aplicación realizada en PHP y que había que instalarla en uno de nuestros servidores. Copiar y pegar. La página de inicio se veía bien, pero cuando entré en una página con contenido PHP, como un formulario, se veía código PHP en el navegador. ¡WoW! Me quedé algo sorprendido.

Lo primero que hice fue buscar el archivo .php correspondiente a esa página y ver su contenido. Aparentemente todo estaba bien. Modifiqué allá y acá, y seguía viéndose el código. Entonces vi que la etiqueta para el código php era “<? … ?>” en vez de “<?php … ?>“. Misterio resuelto y solución fácil. Sólo habría que habilitar la directiva short_open_tag (etiqueta de apertura corta) en el archivo /etc/php5/apache2/php.ini. Esta modificación afecta a todas las aplicaciones, ya que se configura a nivel del servidor Apache2-PHP, lo que supone un problema con otras aplicaciones que usan etiquetas xml, las cuales también comienzan por “<?” y se confunden con las etiquetas de php. El ejemplo más claro es éste:

<?xml version=”1.0″ encoding=”UTF-8″?

Para solucionar este problemilla hay varias opciones. La primera de ellas y que me parece más chupucera es reescribir la línea anterior en todos los archivos donde aparezca y dejarla así:

<? echo ‘<‘.’?xml version=”1.0″ encoding=”UTF-8″?’.’>’; ?>

Esto hace que PHP la reescriba igual que la línea original: <?xml version=”1.0″ encoding=”UTF-8″?>

La segunda opción es la más correcta, pero también la más tediosa y sería usar la etiqueta de apertura correcta “<?php” para todo nuestro código PHP. Esto supone revisar la aplicación entera y cambiar todas las etiquetas de apertura de php. No era mi intención reescribir el código, ni siquiera usando comandos tan útiles como sed o similares.

Y la tercera opción, que es un caso intermedio y por lo que he optado yo, sería habilitar short_open_tag sólo para la aplicación o directorio que deseemos. Esto es posible gracias al archivo .htaccess. Para ello, creamos dicho archivo en el directorio de nuestra aplicación (también se puede hacer a nivel de subdirectorio) y añadimos la siguiente línea:

php_flag short_open_tag on

Con esto lo que hacemos es habilitar la directiva short_open_tag de PHP sólo en el directorio donde tengamos el .htacces y en todos sus subdirectorios. Por tanto, de esta manera tendremos deshabilitadas las etiquetas cortas en el archivo php.ini pero habilitadas en archivo .htaccess del directorio deseado.

Como anécdota, voy a comentar otro problema que he tenido con este archivo .htaccess, ya que inicialmente no me funcionaba. La razón era que en la configuración de Apache2 tengo la opción AllowOverride None, por lo que se ignoran completamente los archivos .htaccess. Por tanto había que reconfigurar esta directiva de Apache2. Esto se puede hacer a nivel global o sólo para un directorio particular. Obviamente opté por lo segundo, para tener lo más seguro posible el servidor. Así pues, añadí la siguiente configuración a Apache2:

<Directory /var/www/miAplicacion/>
AllowOverride Options
</Directory>

Podéis leer más opciones para AllowOverride en la documentación de Apache: Apache Core Features.

Por último comentaros que una forma sencilla de probar si nuestro archivo .htaccess está funcionando es escribiendo cualquier texto en él, por ejemplo:

test

Si Apache no está leyendo el archivo .htaccess, la página se mostrará y Apache no dará ningún error. La causa más frecuente de esto es que tengamos la directiva “AllowOverride None“.

Sin embargo, si el archivo sí está siendo leído por Apache, éste nos dará un error “500 Internal Server Error” y en el archivo error.log de Apache nos aparecerá el siguiente mensaje de error:

[Fri Oct 23 18:22:15 2009] [alert] [client 192.168.0.10] /var/www/miAplicacion/.htaccess: Invalid command ‘test’, perhaps misspelled or defined by a module not included in the server configuration