Apache 配置根据请求的资源是否存在于第一个文档根目录中来使用两个文档根目录

Apache 配置根据请求的资源是否存在于第一个文档根目录中来使用两个文档根目录

背景

我有一个客户端站点,其中包括 CakePHP 安装和 Magento 安装:

/web/example.com/
/web/example.com/app/ <== CakePHP
/web/example.com/app/webroot/ <== DocumentRoot
/web/example.com/app/webroot/store/ <== Magento
/web/example.com/config/ <== Site-wide config
/web/example.com/vendors/ <== Site-wide libraries

该服务器运行 Apache 2.2.3。

问题

整个公司都有 FTP 访问权限,并习惯于用自己的文件堵塞/web/example.com//web/example.com/app/webroot//web/example.com/app/webroot/store/目录。有时这些文件需要 HTTP 访问权限,有时则不需要。

无论如何,这种混乱让我在维护网站时的工作变得更加困难。代码合并、对实时代码进行 tarring 等非常复杂,通常需要一堆过滤器。

被遗弃的解决方案

起初,我以为我会在同一台服务器上设置一个新的子域,将所有文件移到那里,并更改其 FTP chroot。但由于以下原因,这种方法行不通:

首先,我不知道(他们也不记得)他们发送了哪些营销材料,其中包含他们上传到服务器的某些资源的 URL,使用主域,还使用抽象子域,这些子域使用主虚拟主机,因为它有ServerAlias *.example.com。因此突然让他们只使用static.example.com是不可行的。

其次,他们项目中的 PHP 脚本可能非常不可移植。我希望他们的文件尽可能保持在与构建时相似的环境中。另外,我不想调试他们的代码以使其可移植。

不成熟的解决方案

经过一番思考,我决定找到一种方法,将实际的网站文件隔离到另一个他们不会触碰的目录中。公司上传的文件将保留在原处。这将确保我不会破坏任何需要 HTTP 访问的项目。它看起来像这样:

/web/example.com/ <== A bunch of their files are in here
/web/example.com/app/webroot/ <== 1st DocumentRoot; A bunch of their files are in here
/web/example.com/app/webroot/store/ <== Some more are in here
/web/example.com/site/ <== New dir; Contains only site files
/web/example.com/site/app/ <== CakePHP
/web/example.com/site/app/webroot/ <== 2nd DocumentRoot
/web/example.com/site/app/webroot/store/ <== Magento
/web/example.com/site/config/ <== Site-wide config
/web/example.com/site/vendors/ <== Site-wide libraries

在我做出这个改变之后,我不需要关注任何东西,除了里面的东西/web/example.com/site/,我的工作将是很多更容易。我将会是唯一一个在那里改变东西的人。

这就是 Apache 魔法发生的地方:我需要一个 HTTP 请求来http://www.example.com/首先用作/web/example.com/app/webroot/文档根目录。如果未找到任何内容(未找到其他已上传的公司项目),请尝试在 内查找内容/web/example.com/site/app/webroot/

另外要记住的是,如果变量$_SERVER['DOCUMENT_ROOT']读取/web/example.com/app/webroot/但实际文件在内,则站点可能会出现一些问题。如果 DOCUMENT_ROOT 环境变量可以用于目录内的任何内容,/web/example.com/site/app/webroot/那就更好了。/web/example.com/site/app/webroot//web/example.com/site/app/webroot/

结论

我的不成熟的解决方案是否可以使用 Apache 2.2.3?

有没有更好的方法来解决此问题?

答案1

我相信mod_rewrite就可以了。在 www.example.com 的虚拟主机中,您可以执行以下操作:

RewriteEngine On                                                                                                                                  
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /site/app/webroot/$1 [R=301,L] 

这应该会使用 301 请求重写对 site/app/webroot/* 的任何不存在的文件/目录请求。这应该会更新 DOCUMENT_ROOT 以匹配目录。您可以删除该R=301标志以仅进行内部重写(用户看不到更改),但我不能 100% 确定这会更新 DOCUMENT_ROOT...也许会。

注意,这个例子来自记忆,没有经过测试,但它给出了一个大概的概念。mod_rewrite可以做

相关内容