Чистые 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>

Этот код не является тестовым, потому что структура моей файловой системы полностью отличается от исходного примера. Таким образом, я преобразовал свою конфигурацию на лету, чтобы соответствовать этой примерной структуре.

Обратите внимание, что конфигурация не завершена. Вы должны настроить его для своих нужд.

Другие вопросы по тегам