我想在RewriteRule使用VirtualDocumentRoot设置的值。
Apache 文档说:
另外要确定的是文档根目录(使用DocumentRootconfiguration,并通过DOCUMENT_ROOT环境variables可用于CGI脚本)。 在一个正常的configuration中,核心模块在将URI映射到文件名时被这个模块使用,但是当服务器被configuration做dynamic虚拟主机时,这个作业必须被另一个模块(mod_vhost_alias或者mod_rewrite)接pipe,做映射的方法。 这两个模块都不负责设置DOCUMENT_ROOT环境variables,所以如果有任何CGI或SSI文档使用它,它们将会产生一个误导性的值。
参考文档,似乎我将无法在RewriteRule使用%{DOCUMENT_ROOT} 。 但是在寻找替代解决scheme后,我发现这个票据 (标题: DOCUMENT_ROOT环境variables用VirtualDocumentRoot设置不正确 )说它已经被“2.4.1修复”了。
我正在使用最新(稳定)版本的Apache:
$ httpd -v Server version: Apache/2.4.9 (Unix) Server built: Jun 18 2014 03:07:48
…但似乎并不适合我。 testing时, %{DOCUMENT_ROOT}具有httpd.conf中由DocumentRoot设置的默认值。 我想通过VirtualDocumentRootdynamic设置%{DOCUMENT_ROOT} (或任何其他我可以使用的variables)。
这里是我想在httpd-vhosts.conf中使用的:
<VirtualHost *:8080> ServerName dev ServerAlias *.dev VirtualDocumentRoot "/usr/local/var/www/.dev/%-2+" RewriteRule ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/$1" [P] </VirtualHost>
有解决scheme吗?
在与@John Auld (感谢您的时间和帮助)看了很多方向后,我终于find了一个解决scheme。 正如我在之前的评论中所说,这不是100%完美,但对我来说已经够好了。
为了清楚起见,这里是我想在httpd-vhosts.conf中拥有的:
<VirtualHost *:8080> ServerName dev ServerAlias *.dev VirtualDocumentRoot "/usr/local/var/www/.dev/%-2+" RewriteRule ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/$1" [P] </VirtualHost>
这就是我所想到的:
<VirtualHost *:8080> ServerName dev ServerAlias *.dev VirtualDocumentRoot "/usr/local/var/www/.dev/%-2/%-3" RewriteCond %{SERVER_NAME} (?:([^.]+)\.)?([^.]+)\.dev RewriteRule ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/usr/local/var/www/.dev/%2/${:%1|www}/$1" [P] </VirtualHost>
我使用RewriteCond来捕获%{SERVER_NAME}部分内容,并在RewriteRule重用它们。
有两个捕获组:子域( %1 )和域( %2 )。 该子域是可选的,所以我使用语法${map:value|default}来设置子域的默认值为空。
当零件( %NM )不可用时, VirtualDocumentRoot具有自己的默认值。 正如文件中所说:
如果N或M大于可用部件的数量,则插入单个下划线。
这就是为什么我不得不使用一个小小的“技巧”,使其与一个可选的子域一起工作:
ln -sfv /path/to/the/project/www /path/to/the/project/_
如果你想要一个configuration的方式,留下一个评论,我会编辑我的答案与你的贡献。
我使用mod_proxy和mod_proxy_fcgi完成了这个工作,注意到“ Proxy via Handler ”部分: https : //httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html
我需要能够在我的本地开发网站上同时运行PHP 5.6和PHP 7,所以我为PHP 5.6和PHP 7安装了PHP-FPM,并设置了我的vhostsconfiguration,如下所示:
<Virtualhost *:80> VirtualDocumentRoot "/Volumes/CODE/projects/%1" ServerName sites.hack ServerAlias *.hack UseCanonicalName Off <FilesMatch "\.php$"> Require all granted SetHandler proxy:fcgi://127.0.0.1:9056 </FilesMatch> </Virtualhost> <Virtualhost *:80> VirtualDocumentRoot "/Volumes/CODE/projects/%1" ServerName php7.php Serveralias *.php UseCanonicalName off <FilesMatch "\.php$"> Require all granted SetHandler proxy:fcgi://127.0.0.1:9070 </FilesMatch> </Virtualhost>
正如“代理通过处理程序”部分所述:
当以这种方式configurationFastCGI时,服务器可以计算出最准确的PATH_INFO。
有了这个configuration,我可以:
访问本地开发站点http://example.hack ,它将从文档根目录/Volumes/CODE/projects/example提取,然后传递给我的PHP 5.6 PHP-FPM服务SetHandler proxy:fcgi://127.0.0.1:9056 。
访问本地开发站点http://example.php ,它将从相同的文档根目录/Volumes/CODE/projects/example提取,但会传递到我的PHP 7 PHP-FPM服务SetHandler proxy:fcgi://127.0.0.1:9070
我还没有任何问题呢。 这很简单,工作。
该variables在apacheconfiguration文件中不可用。
看看mod_macro,它允许在conf文件中使用variables。
以下2.4为我工作得很好
UseCanonicalName Off <VirtualHost *:80> ServerName auto.dev ServerAlias *.dev VirtualDocumentRoot /Users/yourusername/Sites/auto/%1/public <Directory ~ "/Users/yourusername/Sites/auto/.*/public"> Options Indexes FollowSymlinks MultiViews AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost>
请注意,我正在映射到根文件夹中的公用文件夹