2016-05-02 8 views
11

У меня есть проект, работающий локально на WampServer. Это MVC-подобная структура; он переписывает URL-адрес index.php?url=$1. Полный .htaccess:Абсолютный URL-адрес из базовой папки с rewrite

RewriteEngine On 

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

Когда я хочу, чтобы отправить пользователя на другую страницу с помощью PHP location: <location> он не делает это должным образом из-за переписывания (все, хотя я технически всегда в index.php).

Например, если я на http://localhost/project_name/controller/method/ и конструктор этого контроллера или метод пытается отправить меня:

  • header('location: another_controller/method'); посылает мне http://localhost/project_name/controller/method/another_controller/method/
  • header('location: /another_controller/method'); посылает мне http://localhost/another_controller/method/

Но я хочу, чтобы это послало мне вот так:

  • header('location: /another_controller/method'); посылает мне http://localhost/project_name/another_controller/method/

Теперь единственное решение, которое я нашел это:

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

Но это не идеален, потому что это заставляет меня должны изменить это определяется константой BASE_URL при изменении имени домена или папки. Я мог бы также создать метод в моем BaseController, который создает абсолютные URL-адреса, но этот метод в основном просто добавит BASE_URL.

Примечание: Та же проблема не возникает с src и href атрибутов языка HTML, которые можно использовать относительные пути (без project_name папки в пути). Однако я не понимаю, почему. Потому что, если заголовок location заставляет браузер добавлять относительный URL-адрес к текущему местоположению, почему он не имеет такого же поведения при поискеили .js файлов.

Итак ... это поднимает несколько вопросов для меня:

  1. ли я эту проблему, если бы я имел виртуальные хосты?
  2. Каков наилучший способ решить эту проблему?
  3. Лучше всего иметь полный абсолютный URL-адрес?
  4. Почему атрибуты HTML src и href не разделяют это поведение?
+0

Вы можете добавить код вашего файла htaccess с начала? –

+0

@HarshSanghani Добавлено. – kgongonowdoe

+2

не могли бы вы добавить RewriteBase/project_name/after RewriteEngine на –

ответ

4

Теперь единственное решение, которое я нашел это:

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

Но это не идеально, потому что это заставляет меня должен изменить этой определенной постоянной base_url всякий раз, когда имя домена или папок изменений ,

Вам не нужно менять определенную константу. Эти значения можно найти динамически.

Пример:

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); 

Кроме того, вместо того, чтобы беспокоиться о том, чтобы указать абсолютный URL или путь, вы можете обернуть редирект в функцию, которая может работать как:

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; 
} 

Наконец, как упоминалось в комментариях @HarshSanghani, базовый путь в вашем .htaccess файле должен соответствовать базовому пути в вашем коде. Так что, если BASE_PATH (основано на приведенном выше примере) выводит /project_name/, то ваш .htaccess должен приспособить его:

RewriteBase /project_name/ 
2

Чтобы ответить на ваши вопросы:

  1. Это зависит от того, как ваши виртуальные хосты будут настроены.
  2. Вы можете просто генерировать свой BASE_URL динамически: $baseUrl = dirname($_SERVER['SCRIPT_NAME']);. Таким образом, вам не придется менять код, если ваша папка или домен меняются.
  3. Вам не нужна доменная часть.
  4. html src и href интерпретируются вашим браузером, который учитывает тег <base> страницы. Все пути на странице с тегом <base> будут соответствующим образом изменены вашим браузером.

HTTP-заголовки, отправляемые с вашего сервера (для перенаправления), не имеют ничего общего с отправляемой вами страницей html и поэтому не обновляются.

2
  1. Вы будете иметь эту проблему, если у вас есть проект, созданный в подкаталоге. Использование виртуальных хостов было бы способом обойти проблему, если бы вы захотели установить их по имени, project_name.localhost.
  2. В моих проектах я использую переменную окружения для загрузки другого конфигурационного файла для разработки, постановки или производства. В этом я установил $baseUri как-то.
  3. Лучше всего использовать абсолютные URL (включая домен) как для решения этой проблемы, так и для SEO. Что касается функциональности, вам не нужна часть домена.
  4. Теги src и href обычно работают одинаково, но, как сказал Андреас, на них может повлиять базовый тег.
2

Необходимо указать RewriteBase в файле htaccess. Используйте относительные пути в своих ссылках, и вам больше ничего не нужно.

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] 

 Смежные вопросы

  • Нет связанных вопросов^_^