我想使用在VirtualDocumentRoot
a 中设置的值RewriteRule
。
阿帕奇文档说:
另一件需要确定的事情是文档根目录(使用 DocumentRoot 配置,并通过 DOCUMENT_ROOT 环境变量提供给 CGI 脚本)。在正常配置中,核心模块在将 URI 映射到文件名时会使用它,但是当服务器配置为执行动态虚拟托管时,该工作必须由另一个模块(mod_vhost_alias 或 mod_rewrite)接管,该模块具有不同的映射方式。这两个模块都不负责设置 DOCUMENT_ROOT 环境变量,因此如果任何 CGI 或 SSI 文档使用它,它们将获得误导性值。
参照文档,似乎我无法使用%{DOCUMENT_ROOT}
。RewriteRule
但在寻找替代解决方案后,我发现了这个票(标题:DOCUMENT_ROOT 环境变量与 VirtualDocumentRoot 的设置不正确) 并表示该问题已“在 2.4.1 版中修复”。
我正在使用 Apache 的最新(稳定)版本:
$ httpd -v
Server version: Apache/2.4.9 (Unix)
Server built: Jun 18 2014 03:07:48
...但对我来说似乎不起作用。测试时,%{DOCUMENT_ROOT}
默认值由 httpd.conf 中的 DocumentRoot 设置。我希望%{DOCUMENT_ROOT}
(或我可以使用的其他任何变量)由 动态设置VirtualDocumentRoot
。
以下是我想要在 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>
有解决办法吗?
答案1
我使用 mod_proxy 和 mod_proxy_fcgi 实现了这一点,注意到“通过 Handler 进行代理“ 部分:https://httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html
我需要能够在我的本地开发站点上同时运行 PHP 5.6 和 PHP 7,因此我为 PHP 5.6 和 PHP 7 安装了 PHP-FPM,并按如下方式设置了我的 vhosts 配置:
<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>
正如“通过处理程序的代理”部分所解释的那样:
当 FastCGI 这样配置时,服务器可以计算出最准确的 PATH_INFO。
通过此配置我可以:
访问本地开发站点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
我还没有遇到任何问题。它很简单,而且很实用。
答案2
在从多方面进行研究之后@约翰·奥尔德(感谢您的时间和帮助),我终于找到了解决方案。正如我在先前的评论,它不是 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}
在子域为空时设置默认值。
VirtualDocumentRoot
%N.M
当某个部分 ( ) 不可用时,它有自己的默认值。正如在文档:
如果 N 或 M 大于可用部件的数量,则会插入一条下划线。
这就是为什么我必须使用一些小“技巧”来使其与可选子域名一起工作:
ln -sfv /path/to/the/project/www /path/to/the/project/_
如果你想办法做到这一点仅配置,留下评论,我会根据您的贡献编辑我的答案。
答案3
该变量在 apache 配置文件中不可用。
看一下 mod_macro,它允许在 conf 文件中使用变量。
答案4
对于我来说,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>
请注意,我正在映射到根文件夹中的公共文件夹