PHP 包含、相对 src 属性和 Apache 错误页面

发布于 2024-11-28 03:56:09 字数 1331 浏览 1 评论 0原文

我正在使用位于以下位置的 404 错误页面:

/error_pages/404.php

我有一个常规页面模板,用于向用户显示各种消息:

/message.php

我的错误页面如下所示:

require_once("../includes/core.php");

$message = "Sorry but we could no longer find the item that you were looking for";
$messageStart = "Not Found";

require_once("../message.php");

我在以下位置找到一个管理页面:

/admin

现在我的问题是 CSS 文件和 JS 文件位于 message.php。如果 404 发生在文档根目录,则所有链接都会解析到正确的位置,并且所有文件都会包含在 HTML 中。如果 404 发生在 /admin,则所有链接都会被解析,就像在 /admin/message.php 中找到 message.php 一样!

我已经尝试使用像 PATH_TO_ROOT 这样的常量,该常量是按页面定义的,或者由 core.php 定义,具体取决于 $_SERVER["PHP_SELF"] 的值。

现在上述方法的问题是 $_SERVER["PHP_SELF"] 始终包含 /error_pages/404.php 因此 PATH_TO_ROOT 将始终包含 '../ ' 并且会搞乱文档根目录下发生的所有 404 错误。

如果我在 message.php 本身中定义 PATH_TO_ROOT,那么 /admin 中的所有 404 都会变得混乱。

我该如何解决这个问题?

编辑:

我尝试使用 $_SERVER["REQUEST_URI"]。 CSS 和 JS 文件现在已正确包含在内。问题是 PHP 包含。所有包含内容均从 404.php 所在的 /error_pages 解析。这些 PHP 包含确实使用 PATH_TO_ROOT,因此基于 REQUEST_URIPATH_TO_ROOT 确实不太好。

I am using a 404 error page found at:

/error_pages/404.php

I have a regular page template used for displaying all kinds of messages to the user at:

/message.php

My error page looks like this:

require_once("../includes/core.php");

$message = "Sorry but we could no longer find the item that you were looking for";
$messageStart = "Not Found";

require_once("../message.php");

I have an admin page found at:

/admin

Now my problem is the CSS files and JS files at message.php. If the 404 happened at document root, all links are resolved to their proper locations and all files are included in the HTML. If the 404 happened at /admin, all links are resolved as if message.php is found at /admin/message.php!

I already tried using a constant like PATH_TO_ROOT which is defined per page, or it is defined by core.php depending on the value of $_SERVER["PHP_SELF"].

Now the problem in the above approach is that $_SERVER["PHP_SELF"] always contains /error_pages/404.php thus PATH_TO_ROOT will always contain '../' and will mess-up all 404's happening at document root.

If I define PATH_TO_ROOT within message.php itself, then all 404's in /admin gets messed up.

How do I solve this?

EDIT:

I tried using $_SERVER["REQUEST_URI"]. The CSS and JS files are now properly included. The problem is the PHP includes. All includes are resolved from /error_pages where 404.php is located. These PHP includes do use PATH_TO_ROOT so a PATH_TO_ROOT based on REQUEST_URI is really not that good.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

王权女流氓 2024-12-05 03:56:09

使用相对于站点根目录的链接:

<link rel="stylesheet" href="/css/default.css" />

在路径开头使用正斜杠以“开始”站点的根文件夹。这样,路径始终相同。

Use links relative to the site root:

<link rel="stylesheet" href="/css/default.css" />

Use a forward slash at the beginning of the path to "start" at the site's root folder. This way, the path is always the same.

简美 2024-12-05 03:56:09

在我自己的框架中完成此操作后,解决方案可能会有点麻烦,而且网络上的许多其他人都没有很好地记录下来。您确实需要考虑 3 个问题:

  • WEB 根目录在哪里,您的引擎/框架代码相应地位于哪里
  • 您的引擎/框架的 PHP 文件根目录在哪里,以及相应的包含/需要
  • 计算 CSS/JS 的正确路径/图像/等...

假设一些小细节,这些都可以很容易地解决。首先要做的假设是,您的框架将位于一个已知的文件夹中(称为“framework”),并且它将具有一个已知的文件名(同样,framework.php)。然后,要在 index.php 处理程序中查找框架路径,您可以使用:

// in index.php
$frameworkPath = './';
while((is_dir($frameworkPath))&&(!file_exists($frameworkPath.'framework/framework.php'))){
  $frameworkPath = ($frameworkPath!='./')?'../'.$frameworkPath:'../';
}
if(!file_exists($frameworkPath.'framework/framework.php')){
// some type of error handler here
}else require_once($frameworkPath.'framework/framework.php');

// in framework.php
if(!defined('FRAMEWORK_PATH')){
  $frameworkpath = str_replace("\\", '/', dirname(__file__));
  if(substr($frameworkpath, -1)!='/') $frameworkpath .= '/';
  define('FRAMEWORK_PATH', $frameworkpath);
}
// now your requires become require_once(FRAMEWORK_PATH.'filename/relative/framework.php');

然后我们需要计算站点的安装路径。我们可以使用 DOCUMENT_ROOT 和“当前访问的文件”的路径来完成此操作。类似于以下内容:

$serverPath = $_SERVER['DOCUMENT_ROOT'];
$thisPath = @realpath(dirname('./'));
$thisPathLength = strlen($thisPath);
$SitePath = '/'.str_replace('\\','/', substr($thisPath, strlen($serverPath), $thisPathLength)).'/';

这还为我们提供了站点 PHP 文件的绝对路径,我们可以利用 PHP 包含系统让我们提供绝对文件路径而不仅仅是包含用户脚本的相对路径这一事实。 thisPath 用于用户脚本包含和要求的路径。例如,如果您想在 /path/to/site/user_script.php 中包含一个文件,您可以执行以下操作:

require_once($thisPath.'user_script.php');

SitePath 现在可用于设置与 CSS/JS/etc 文件相关的包含。因此,不要说

<img src="img.jpg" />

<img src="<?php echo $SitePath;?>img.jpg" />.

如果您感兴趣,我已经将当前的框架发展到了可共享的程度,最终我将把它发布为开源,但我还没有完成文档,所以您需要自行承担阅读的风险”类型的事情:)。我将其扩展为使用 SIMPLE_HTML_DOM_PARSER,以便它为设计者更新源 HTML 中的标签,并且他们不必担心标签上的 src、action、href 等属性。当然,它会稍微减慢渲染速度,但它使设计师的生活变得更加轻松:)

Having done this in my own framework the solution can be a bit aggravating to get to and not well documented by many others on the web. There are really 3 problems you have to account for:

  • Where is the WEB root and where is your engine/framework code located accordingly
  • Where is the PHP files root for your engine/framework and includes/requires accordingly
  • Calculation of proper pathing for CSS/JS/Images/etc...

Assuming a few minor details these can all be worked around easily enough. First assumption to make is that your framework will be in a known folder (call it framework) and that it will have a known file name (again, framework.php). Then to find the framework path in your index.php handler you can use:

// in index.php
$frameworkPath = './';
while((is_dir($frameworkPath))&&(!file_exists($frameworkPath.'framework/framework.php'))){
  $frameworkPath = ($frameworkPath!='./')?'../'.$frameworkPath:'../';
}
if(!file_exists($frameworkPath.'framework/framework.php')){
// some type of error handler here
}else require_once($frameworkPath.'framework/framework.php');

// in framework.php
if(!defined('FRAMEWORK_PATH')){
  $frameworkpath = str_replace("\\", '/', dirname(__file__));
  if(substr($frameworkpath, -1)!='/') $frameworkpath .= '/';
  define('FRAMEWORK_PATH', $frameworkpath);
}
// now your requires become require_once(FRAMEWORK_PATH.'filename/relative/framework.php');

Then we need to calculate the Site's installed path.We can do this using the DOCUMENT_ROOT and the path to the "currently accessed file". Something similar to the following:

$serverPath = $_SERVER['DOCUMENT_ROOT'];
$thisPath = @realpath(dirname('./'));
$thisPathLength = strlen($thisPath);
$SitePath = '/'.str_replace('\\','/', substr($thisPath, strlen($serverPath), $thisPathLength)).'/';

This also provides us the absolute path for the sites PHP files and we can take advantage of the fact that the PHP include system lets us give absolute file paths and not just relative ones for inclusion of user scripts. thisPath is what is used for user script includes and requires. If for example you want to include a file in /path/to/site/user_script.php you can do a:

require_once($thisPath.'user_script.php');

SitePath can now be used to setup includes related to CSS/JS/etc files. So instead of stating

<img src="img.jpg" />

you say

<img src="<?php echo $SitePath;?>img.jpg" />.

If your interested I've got my current framework to a point where its shareable, eventually I'm going to release it Open Source but I haven't done the documentation so its a read at your own risk type of thing :). I extended this to use SIMPLE_HTML_DOM_PARSER so it updates the tags in the source HTML for the designer and they don't have to worry about src, action, href, etc attributes on tags. Sure, it slows down rendering a bit, but it makes the designers lives so much easier :)

童话里做英雄 2024-12-05 03:56:09

好吧,如果我很好地理解你的问题,并且你真的想使用相对而不是绝对路径(如 /css/style.css),我会尝试使用以下内容来计算当前文档的深度:

$depth = substr_count($_SERVER["DOCUMENT_URI"], "/") - 1;

然后对于路径使用:

<link rel="stylesheet" type="text/css" href="<?=str_repeat("../", $depth)?>css/style.css" />

我没有测试代码,但它应该可以工作。尝试一下。
希望有帮助

Well, I if I understand well your question, and you really want to use relative not absolute paths (like /css/style.css) I would try to calculate the depth of the current document with something like:

$depth = substr_count($_SERVER["DOCUMENT_URI"], "/") - 1;

And then for the path use:

<link rel="stylesheet" type="text/css" href="<?=str_repeat("../", $depth)?>css/style.css" />

I didn't tested the code but it should work. Try it out.
Hope it helped

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文