背景
我有一个客户端站点,其中包括 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可以做