Я хотел бы использовать значение, установленное VirtualDocumentRoot
в RewriteRule
.
Апач документация говорит:
Еще одна вещь, которую необходимо определить, - это корень документа (настроенный с помощью DocumentRoot и доступный для сценариев CGI через переменную среды DOCUMENT_ROOT). В нормальной конфигурации это используется основным модулем при сопоставлении 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}
имеет значение по умолчанию, установленное DocumentRoot в httpd.conf. Я хотел бы %{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>
Есть решение?
Я сделал это с помощью mod_proxy и mod_proxy_fcgi, отметив "Прокси через обработчик" раздел: https://httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html
Мне нужно было запускать PHP 5.6 и PHP 7 на моих локальных сайтах разработчиков, поэтому я установил PHP-FPM как для PHP 5.6, так и для PHP 7 и настроил конфигурацию 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
У меня с этим пока не было проблем. Все просто и работает.
Посмотрев во многих направлениях с @ Джон Олд (спасибо за ваше время и помощь), я наконец нашел решение. Как я сказал в предыдущий комментарий, он не идеален на 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/_
Если вы думаете, как это сделать только конфигурация, оставьте комментарий, и я отредактирую свой ответ с вашим вкладом.
Следующее сработало для меня для 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>
Обратите внимание, что я подключаюсь к общей папке в корневой папке.
Переменная недоступна в файлах конфигурации apache.
Взгляните на mod_macro, который позволяет использовать переменные в файлах conf.