当前PHP脚本相对于文档根目录的路径

10

TL;DR: 当使用PHP的include命令包含页面时,如果想要使用相对链接,有哪些替代方案?


我正在尝试include()一个链接到.css文档的文件,问题是我需要从多个(不同的)目录包含此文件。我的目录结构看起来有点像这样:

www
├── (getpath.php)
│
├── css
│   └── style.css
├── php
│   └── header.php
└── content
    ├── index.php
    └── posts
        └── index.php

(我在两个index.php文件中都包含了header.phpheader.php是引用style.css的文件(浏览器需要能够找到它)。例如:当使用../css/style.css时,CSS将显示在我的content/index.php中,但不会显示在我的content/posts/index.php中,因为浏览器正在寻找content/css/index.php。)

当网站放置在文档根目录的子目录中时,网站也应该正常工作,而不是在文档根目录中。因此,我不能仅使用/css/style.css(相对于服务器根目录)来链接我的CSS样式表。

我认为(如果我错了,请纠正我!)告诉浏览器在哪里找到CSS文档的最简单方法可能是指定相对于文档根目录的路径。由于我希望我的网站位于文档根目录的子目录中(并且想避免使用config文件存储子目录),我需要找出网站所在子目录的相对路径。 我的想法是将一个名为getpath.php的文件放在我的网站根目录中(而不是文档根目录)。在那个文件中,我写了以下内容:

<?php
  define('PROJECT_SUBDIRECTORY', $_SERVER['PHP_SELF']);
?>

然而,我注意到这给了我用户在浏览器中请求的PHP文件的相对目录(例如content/index.php),而不是包含的文件(getpath.php)。我也读到过PHP_SELF基于REQUEST_URI,这不安全。我在这里找到了解决方案:

define('PROJECT_DIR', preg_replace('/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', '', __DIR__));

这种方法是完全可行的,但我想知道是否有更好的方法。我没有找到相应的变量来解决这个问题——上面的解决方案是唯一的方法吗?

我应该使用之前的代码示例还是有更好的方法?
我应该更改目录结构吗?其他人是如何解决这个问题的?


编辑: 我的 web 服务器上有多个(完全独立的)网站,它们都在文档根目录的子目录中(如 /documentroot/project1//documentroot/project2/ 等)。 我正在尝试让这些网站在子目录中运行。显然,我可以通过 /css/style.css 将 CSS 发送到浏览器,但如果网站在子目录中,则无法正常工作。我还想避免使用配置文件来指定与文档根目录相关的项目路径。


另一个编辑: 问题在于我的项目 /documentroot/project1 中的每个 PHP 文件都使用 PHP 的 include 函数包含导航栏。导航栏保存在 /documentroot/project1/php/header.php,导航栏的 CSS 保存在 /documentroot/project1/css/style.css。当使用相对链接(告诉浏览器 style.css 的位置)时,浏览器仍然认为路径是相对于 index.php 而不是 header.php,因此它在与 index.php 相同的目录中搜索 CSS。
问题: 不同目录中有多个 index.php 文件,我不想在每个包含 index.php 文件的目录中复制并粘贴我的 CSS 文件夹。


跟进问题:所有网站都有自己的CSS文件吗?(我认为是这样的)。如果是这样,为什么不在每个站点的子目录中放置一个CSS目录+文件呢? - Wes H
@WesH 我更新了原始问题。 :) - Abandoned account
4个回答

6

我过去使用的设置如下:

define('DIR_BASE',     dirname( __FILE__ ).'/'); 
define('DIR_SYSTEM',   DIR_BASE.'app/');
etc.

这段代码需要放在您的项目根目录下,它将让您可以相对于根目录访问文件结构中的其他区域。

对于您的情况,代码应该是这样的:

define('DIR_BASE',     dirname( __FILE__ ).'/');
define('DIR_CSS',      DIR_BASE.'css/');
define('DIR_PHP',      DIR_BASE.'php/');
define('DIR_CONTENT'   DIR_BASE.'content/');

这段代码应该放在你的根目录下的getpath.php文件中,这样就可以引用任何文件或目录而无需考虑它们在目录结构中的位置(请确保将其包含在你将要使用它们的任何地方)。你不需要更改你的目录结构或其他任何内容,也不必担心像这样的漏洞,因为它是内部的。 编辑 我一直在关注系统的结构。这是一个使用相同CSS的多站点系统吗?如果不是,那么为什么要按照这样的目录结构布局?能否提供更多细节?

谢谢您的回答!不幸的是,这给了我绝对路径,有没有办法将其转换为相对于文档根目录的路径,以便我可以将该链接发送到浏览器? - Abandoned account
哦,我明白了,我误解了你在这里的问题。我会更新我的答案。 - Wes H
谢谢,我也是。希望我理解了你的问题。 - Abandoned account

2

看起来最好的方法是从__DIR__中移除$_SERVER['DOCUMENT_ROOT'],就像我在原始问题中提到的那样。

define('PROJECT_DIR', preg_replace('/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', '', __DIR__));

我想我会像那样做。

(这句话与IT技术相关性不强,但我已经按照您的要求进行了翻译。)

0
我在项目根目录下有一个config/文件夹,里面有一个名为main.php的文件,我使用它:
$root = $_SERVER['DOCUMENT_ROOT'];
$dir = dirname(__DIR__);
$root = str_replace("\\","/",$root);
$dir = str_replace("\\","/",$dir);
$web_dir = str_replace($root,'',$dir);
if ($web_dir!=='') { $web_dir = '/'.$web_dir; }
define('DIR',$web_dir);

这将从我的配置文件的完整目录路径中删除文档根,从而为我提供相对于Web根目录的实际路径。如果您的配置文件位于项目根目录中,则应删除此行:

$dir = dirname(__DIR__);

0

相对URL,或者你的脚本位于文档根目录的位置

preg_replace('/[\\\\\\/]+/', '/', '/' . substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT'])) . '/' )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接