php .htaccess mod-rewrite relative-path absolute-path

php - URL absoluta desde la carpeta base con reescritura



.htaccess mod-rewrite (4)

Para responder tu pregunta:

  1. Depende de cómo se configurarán sus hosts virtuales.
  2. Simplemente puede generar su BASE_URL dinámicamente: $baseUrl = dirname($_SERVER[''SCRIPT_NAME'']); . De esta forma, no tendrá que cambiar ningún código si su carpeta o dominio cambia.
  3. No necesitas la parte de dominio.
  4. Los html src y href son interpretados por su navegador, que tiene en cuenta la etiqueta <base> la página. Todas las rutas en una página con una etiqueta <base> se cambian según su navegador.

Los encabezados HTTP que envía desde su servidor (para redirección) no tienen nada que ver con la página html que envía y, por lo tanto, no se actualizan.

Tengo un proyecto ejecutándose localmente en WampServer. Es una estructura similar a MVC; reescribe la URL a index.php?url=$1 . Completo .htaccess :

RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

Cuando deseo enviar al usuario a otra página usando la location: <location> PHP location: <location> no hace esto correctamente debido a la reescritura (aunque técnicamente siempre estoy en index.php ).

Por ejemplo, si estoy en http://localhost/project_name/controller/method/ y el constructor o método de este controlador intenta enviarme a:

  • header(''location: another_controller/method''); me envía a http://localhost/project_name/controller/method/another_controller/method/
  • header(''location: /another_controller/method''); me envía a http://localhost/another_controller/method/

Pero quiero que me envíe así:

  • header(''location: /another_controller/method''); me envía a http://localhost/project_name/another_controller/method/

Ahora la única solución que he encontrado es:

define(''BASE_URL'',''http://localhost/project_name''); header(''location: ''.BASE_URL.''/another_controller/method/'');

Pero esto tampoco es perfecto porque me obliga a tener que cambiar esta constante definida BASE_URL siempre que BASE_URL el nombre del dominio o de la carpeta. También podría crear un método en mi BaseController que crea direcciones URL absolutas, pero este método básicamente también precedería a BASE_URL también.

Nota: El mismo problema no surge con los atributos src y href HTML, que pueden usar rutas relativas (sin la carpeta project_name en la ruta). No entiendo por qué sin embargo. Porque si la location del encabezado hace que el navegador anexe la URL relativa a la ubicación actual, ¿por qué no tiene el mismo comportamiento cuando busca archivos .css o .js ?

Entonces ... esto plantea un par de preguntas para mí:

  1. ¿Tendría este problema si tuviera hosts virtuales?
  2. ¿Cuál es la mejor manera de resolver este problema?
  3. ¿Es mejor simplemente tener la URL absoluta completa?
  4. ¿Por qué los atributos src y href HTML no comparten este comportamiento?

Ahora la única solución que he encontrado es:

define(''BASE_URL'',''http://localhost/project_name''); header(''location: ''.BASE_URL.''/another_controller/method/'');

Pero esto tampoco es perfecto porque me obliga a tener que cambiar esta constante definida BASE_URL siempre que cambie el nombre del dominio o de la carpeta.

No debería necesitar cambiar la constante definida. Estos valores se pueden encontrar dinámicamente.

Ejemplo:

if ($_SERVER[''DOCUMENT_ROOT''] == dirname($_SERVER[''SCRIPT_FILENAME''])) { define(''BASE_PATH'', ''/''); } else { define(''BASE_PATH'', dirname($_SERVER[''SCRIPT_NAME'']) . ''/''); } $protocol = isset($_SERVER[''HTTPS'']) ? ''https://'' : ''http://''; define(''BASE_URL'', $protocol . $_SERVER[''SERVER_NAME''] . BASE_PATH);

Además, en lugar de preocuparse por especificar una URL absoluta o una ruta, puede ajustar la redirección en una función que pueda manejar ambos:

function redirect($path = null) { if (isset($path)) { if (filter_var($path, FILTER_VALIDATE_URL)) { header(''Location: '' . $path); } else { header(''Location: '' . BASE_URL . $path); } } else { header(''Location: '' . BASE_URL); } exit; }

Finalmente, como @HarshSanghani mencionó en los comentarios, la ruta base en su archivo .htaccess debe coincidir con la ruta base en su código. Entonces, si BASE_PATH (basado en el ejemplo anterior) genera /project_name/ , su .htaccess debe acomodarlo:

RewriteBase /project_name/


  1. Tendrá este problema si tiene su proyecto configurado en un subdirectorio. El uso de servidores virtuales sería una forma de evitar el problema si desea configurarlos en say, project_name.localhost.
  2. En mis proyectos, utilizo una variable de entorno para cargar un archivo de configuración diferente para desarrollo, montaje o producción. En esto establecí un $baseUri alguna manera.
  3. Es una buena práctica usar las URL absolutas (incluido el dominio) tanto para la solución de este problema como para el SEO. En términos de funcionalidad, no necesita la parte del dominio.
  4. Las etiquetas src y href generalmente funcionan de la misma manera, pero como Andreas mencionó, podrían verse afectadas por la etiqueta base.

Debe especificar RewriteBase en su archivo htaccess. Use rutas relativas en sus enlaces y no necesita nada más.

RewriteBase /project_name/ RewriteEngine on RewriteCond $1 !/.(gif|jpe?g|png)$ [NC] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]