我很难决定如何管理这些错误(404、500、...),当我最终决定时,我遇到了问题。这是一个很长的问题,我感谢任何人的帮助!
让我先描述一下我是如何决定设置它的。我有几个站点托管在一个共享的 Dreamhost 帐户上。在我看到的文件夹结构中,我在服务器上的所有内容都在 /home/username 下,例如,site1.com 的 Web 根目录在
/home/用户名/site1.com
我正在为 404 not found、500 等错误创建一个通用错误处理程序(php 脚本),我想将这些错误存储在我的网站的 Web 根目录之上
/home/用户名/error_handler/index.php这样我就可以在 /home/username/.htaccess 中使用 .htaccess 文件,其中包括以下内容:
错误文档 404 /error_handler/index.php 错误文档 500 /error_handler/index.php
...还有很多
当我的任何网站上发生这些错误时,我希望将其定向到
/home/用户名/error_handler/index.php这是我很难弄清楚的问题。上面的 ErrorDocument 指令实际上会导致 Apache 寻找
/home/username/site1.com/error_handler/index.php
无论如何,错误应该被重定向到我的错误处理 php 脚本。该脚本将使用 $_SERVER['REDIRECT_STATUS'] 来获取错误代码,然后使用 $_SERVER['REDIRECT_URL'] 和 $_SERVER['HTTP_HOST'] 来决定要做什么。它将检查是否存在特定于该站点的错误处理程序(例如:site1.com/errors/404.php)。如果此自定义页面不存在,它将输出一条更人性化和样式化的通用消息,并且可能会包含一些我的联系信息,具体取决于错误。
这样做可以让我通过这个 1 php 脚本汇集所有这些错误。我可以根据自己的喜好记录错误,或者根据需要发送电子邮件通知。它还允许我为我的所有站点设置一次 ErrorDocument Apache 指令,而不必为每个站点都设置。当我移动站点时,它也将继续工作而无需修改,因为我已经有一个系统可以扫描文件夹结构,以找出我的站点根目录在技术上真正不在网络根目录的位置。这对于其他解决方案可能是不可能的,例如对所有 404 问题使用 mod_rewrite,我知道这很常见。或者,如果可能的话,它可能很难做到。另外,我已经完成了这项工作,所以我很容易适应。
当我在我还没有域名的网站上工作时(或者域名目前已经在使用的网站),我将它们临时存储在 site1.com/dev/site3.com 中。将站点移动到 site3.com 最终将导致我必须更新 htaccess 文件,如果我为每个站点都有一个。更改域名也会这样做。
例如:存储在 site1.com/dev/site3.com 的站点将在其 htaccess 文件中包含以下内容:
错误文档 404 /site1.com/dev/site3.com/error/404.php
它必须改为:
错误文档 404 /site3.com/error/404.php
显然,这不是一项巨大的工作,但我已经管理了很多网站,而且我可能每年都会赚更多,其中 95% 将托管在我共享的 DreamHost 帐户上。他们中的大多数人至少会被移动一次。因此,从长远来看,设置自动功能将为我节省一些精力。
我已经设置了一个系统来管理我所有站点上的站点相关链接。无论该站点存在于现有站点的子目录中,还是存在于它们自己的域中,这些链接都将起作用。尽管 Web 根位置不同,它们也可以在不更改本地开发服务器的情况下工作。例如,在实时服务器上,与站点相关的 http 链接 /img/1.jpg 将解析为文件 /home/username/site1.com/img/1.jpg 而在我的本地开发服务器上,它将解析为 C :\xampp\htdocs\img\1.jpg,尽管我认为逻辑站点根目录位于 C:\xampp\htdocs\site1.com。我喜欢这个系统,正是它让我想到了根据我使用的文件结构设置一些可以自动运行的东西,就像我期望的那样。
所以,如果我能让它工作,我认为这似乎是一个非常好的系统。但我对 apache 配置、mod_rewrite 等仍然很陌生。可能有一种更简单、更好的方法来做到这一点。如果你知道一个,请告诉我。
无论如何,除了所有这些,我无法让它工作。最简单的事情是如果我可以让 ErrorDocument 指令将请求发送到 Web 根目录上方的文件夹。但路径是相对于文档根目录的 URL 路径。在 /home/username/.htaccess 中使用以下内容,
错误文档 404 /error_handler/index.php
对不存在资源的请求会导致 Apache 在以下位置查找文件
site1.com/error_handler/index.php
所以我想我应该设置一个重定向(在我所有的网站上),将这些 URL 重定向到 /home/username/error_handler。我尝试了一些东西,但无法让它们中的任何一个工作。
别名似乎是最简单的解决方案,但它必须在服务器运行时设置(不确定这是否是正确的术语 - 当服务器启动时)。在我的本地服务器上,它使用以下方法运行良好:
别名 /error_handler C:\xampp\htdocs\error_handler2
我更改了本地文件夹以测试 Alias 是否正常运行。(在本地服务器上,由 ErrorDocument 指令指定的 URL 路径实际上指向正确的文件夹,因为在我的本地服务器中,Web 根在技术上是 C:\xampp\htdocs 并且我存储了我想要使用的错误处理程序本地 C:\xampp\htdocs\error_handler\index.php)
Dreamhost 有一个网络客户端,可以创建我猜想的别名。当我尝试将 site1.com 上的文件夹 error_handler 重定向到 /home/username/error_handler 时,如果我在浏览器中键入 site1.com/error_handler,它似乎可以正常工作。但是如果我输入 site1.com/test1234(不存在),它会说尝试使用错误处理程序时出现 404 错误。此外,每次我想为新站点设置它时,我都必须通过 Web 客户端登录并点击(并等待几分钟让服务器重新启动),即使我可以让它工作。
所以我尝试让它与 mod_rewrite 一起工作,这似乎是最灵活的解决方案。我的第一次尝试看起来像这样(现在存储在 /home/username/site1.com/.htaccess 中,尽管它最终会在 /home/username/.htaccess 中:
重写引擎开启 RewriteRule ^error_handler/index.php$ /home/username/error_handler/index.php
我在上面尝试做的简单英文版本是在我的任何站点上将 error_handler/index.php 请求发送到 /home/username/error_handler/index.php。我的误解是,如果存在,替换将被视为文件路径。但是我错过了文档中说的“(或者,在 .htaccess 文件中使用重写的情况下,相对于您的文档根目录)”。所以不是重写到/home/username/error_handler/index.php,它实际上是在尝试重写到/home/username/site1.com/home/username/error_handler/index.php。
我尝试包括 Options +FollowSymLinks 因为在 Apache 文档中它说:
要在此上下文中启用重写引擎 [per-directory re-writes in htaccess],您需要设置“RewriteEngine On”并且必须启用“Options FollowSymLinks”。如果您的管理员已禁用用户目录的 FollowSymLinks 覆盖,则您无法使用重写引擎。出于安全原因,需要此限制。
我四处搜索了一段时间,但找不到有关 Dreamhost 如何处理此问题的任何信息(可能是因为我不知道在哪里寻找)。
我尝试了 RewriteBase,因为在 Apache 文档中它是这样说的:
“当您在每个目录 (htaccess) 上下文中的替换中使用相对路径时,需要此指令,除非以下任一条件为真:
原始请求和替换位于 DocumentRoot 下(而不是通过其他方式(例如别名)可访问)。”
因为这应该是一个 URL 路径,所以在我的情况下它应该是 RewriteBase /,因为我所有的重定向都来自 site1.com/error_handler。我还尝试了 Rewrite Base /home/username 和 RewriteRule ^error_handler/index.php$ error_handler/index.php。但是,Rewrite Base 是相对于文档根目录的 URL 路径。所以我仍然需要使用别名之类的东西。上述文档中引用的含义是可以使用 mod_rewrite 将内容发送到 Web 根目录之上。我不知道的许多事情之一是除了 Alias 之外的“其他含义”可能是什么。我相信 Alias 可能不是 Dreamhost 的一个选项。至少我无法理解它。