8

我正在尝试允许 Clean-Urls,启用 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,并且这个问题在更新后开始发生。

4

3 回答 3

12

我终于想出了如何解决它。

这可行,完全删除.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>

这有助于我让所有页面正常工作,就像它们在服务器上工作一样,没有任何重写条件。

于 2013-01-13T18:38:26.277 回答
0

不使用 .php 扩展名且不使用MultiViews的清理 URL 。

一个灵活的 Web 环境,使用mod_userdirmod_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 本身存在则跳过。

我正在使用一个多用户环境,其中每个用户都有自己的 webroot 和子域。

/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>

此代码不是 testet,因为我的文件系统结构与最初的示例完全不同。所以我即时转换了我的配置以适应这个示例结构。

注意配置不完整。您需要根据自己的需要自行调整。

于 2014-12-29T23:51:22.390 回答
0

虽然 MultiViews 可以用于此目的,但不要向 PHP 文件添加任意 MIME 类型以让 MultiViews 为它们提供服务,就像接受的答案和互联网上的许多其他来源所建议的那样:

# Bad code - don't do this!
Options +MultiViews
AddType application/x-httpd-php .php

我在https://stackoverflow.com/a/24598848/1709587详细解释的这个 hack似乎有效,但实际上已损坏;Accept每当服务器接收到带有不包含的标头的请求时,它将失败*/*

相反,干净的解决方案是使用该MultiviewsMatch指令告诉 Apache 提供.php文件是有效的,而不管请求的Accept和标头如何:Accept-Language

# Good code - use this instead!
Options +MultiViews
<Files "*.php">
    MultiviewsMatch Any
</Files>
于 2017-01-22T16:40:19.707 回答