Чистые URL-адреса Apache с поддержкой MultiViews
Я пытаюсь разрешить чистые URL-адреса, включив MultiViews.
Все страницы, которые у меня есть, находятся в самой корневой папке.
Я пытаюсь добиться следующего:
(current-status -> what I am trying to achieve)
1. foo.com/services.php -> foo.com/services
2. foo.com/services == foo.com/services/
3. foo.com/services.php/second-level/ == foo.com/services/second-level
services
это не папка, я взрываюсь $_SERVER['PATH_INFO']
и получить данные пути второго уровня.
Я уже достиг первого, но он не работает, когда я включаю MultiViews
, используя .htaccess
файл и запись переписать.
Options +Indexes +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
(Который, очевидно, потерпит неудачу, поскольку он изменит запрос на services/second-level.php). Я знаю, что могу написать несколько переписываний в .htaccess
и условно перенаправить.
Но странный факт заключается в том, что в живом окружении (виртуальный хостинг) он работает без каких-либо .htaccess
файл в корневой папке. Поскольку это общий хостинг, я не могу прочитать файл конфигурации.
Любые идеи о том, какую конфигурацию я должен изменить (в apache.conf
или же *.conf
) чтобы достичь вышеуказанного?
Если это имеет значение, я использую Apache/2.2.22
и эта проблема начала происходить после обновления.
3 ответа
Я наконец-то понял, как это решить.
Это работает, удаляя .htaccess
файл в целом, и изменение Virtual Directory
сохранить следующие настройки:
<VirtualHost *:80>
ServerAdmin my-email-id
ServerName foo.bar
DocumentRoot /var/www/sites/foo/
<Directory /var/www/sites/foo/>
Options +FollowSymLinks +MultiViews +Indexes
DirectoryIndex index.php
AddType application/x-httpd-php .php
</Directory>
</VirtualHost>
Это помогает мне заставить все страницы работать точно так же, как они работали на сервере, без каких-либо условий перезаписи.
Хотя для этого можно использовать MultiViews, не добавляйте произвольный тип MIME к файлам PHP, чтобы их обслуживали MultiView, как это принято в ответе и во многих других источниках в Интернете:
# Bad code - don't do this!
Options +MultiViews
AddType application/x-httpd-php .php
Этот хак, который я подробно объясняю на /questions/575929/net-priemlemogo-varianta-iz-multiviews-v-apache/575938#575938, похоже, работает, но на самом деле не работает; он не будет работать всякий раз, когда сервер получает запрос с Accept
заголовок, который не включает */*
,
Вместо этого чистое решение заключается в использовании MultiviewsMatch
директива, чтобы сказать Apache, что это действительно, чтобы служить .php
файлы независимо от Accept
а также Accept-Language
Заголовки запроса:
# Good code - use this instead!
Options +MultiViews
<Files "*.php">
MultiviewsMatch Any
</Files>
Чистые URL-адреса без расширений.php и без использования MultiViews.
Гибкая веб-среда с поддержкой виртуальных поддоменов с использованием mod_userdir и mod_rewrite.
Позволяет следовать раскладке URL
- /var/www/sites/www/services.php
http://foo.bar/services.php/second-level/
http://foo.bar/services/second-level/
http://www.foo.bar/services/second-level/
http://127.0.0.1/services/second-level/
- /var/www/sites/www/admin/login.php
http://foo.bar/admin/login.php/foo
http://foo.bar/admin/login/foo
http://www.foo.bar/admin/login/foo
Примечание с или без предварительного www. равен, потому что www. устарел сегодня... Но теперь вы можете размещать виртуальные субдомены слишком просто, добавив папку в /var/www/sites/
(помните DNS)
- /var/www/sites/images/imgpass.php
http://images.foo.bar/imgpass.php/photo.jpg
http://images.foo.bar/imgpass/photo.jpg
http://www.images.foo.bar/imgpass/photo.jpg
http://127.0.0.1/~images/imgpass/photo.jpg
... и так далее, но пропускает, если существует / var / www / sites / images / imgpass.
Я использую многопользовательскую среду, где у каждого пользователя есть свой собственный rootroot и поддомен.
/etc/apache2/sites-enabled/foo.bar.conf:
<VirtualHost *:80>
ServerAdmin my-email-id
ServerName foo.bar
ServerAlias 127.0.0.1 *.foo.bar
# The default web-root if no subdomain is given
DocumentRoot /var/www/sites/www/
UserDir /var/www/sites/*
<Directory /var/www/sites/*>
Order allow,deny
Allow from all
DirectoryIndex index.php index.html
Options -MultiViews -Indexes
# MultiViews workaround with 1 level subdir support
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} ^(\/var\/www\/sites\/.+(\/[^\/]+){2}).*
RewriteCond %1.php -f
RewriteRule ^\/var\/www\/sites\/(.+)((?:\/[^\/]+){2})(.*) /~$1$2.php$3 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} ^(\/var\/www\/sites\/.+(\/[^\/]+){1}).*
RewriteCond %1.php -f
RewriteRule ^\/var\/www\/sites\/(.+)((?:\/[^\/]+){1})(.*) /~$1$2.php$3 [L]
</Directory>
# Force all requests in background to UserDir compatible requests
RewriteEngine on
RewriteMap lc int:tolower
RewriteCond %{REQUEST_FILENAME} !^/~
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)\.foo\.bar$
RewriteRule /(.*) /~${lc:%2}/$1 [PT,L]
</VirtualHost>
Этот код не является тестовым, потому что структура моей файловой системы полностью отличается от исходного примера. Таким образом, я преобразовал свою конфигурацию на лету, чтобы соответствовать этой примерной структуре.
Обратите внимание, что конфигурация не завершена. Вы должны настроить его для своих нужд.