设置include/require文件的路径

Mic*_*l_B 5 html php html5 path php-include

我所有的PHP包含文件都在一个目录中:

https://www.mywebsite.com/includes
Run Code Online (Sandbox Code Playgroud)

在顶级页面中插入这些文件非常简单:

<?php include 'includes/logo.php'; ?>
<?php include 'includes/main_nav.php'; ?>
<?php include 'includes/news.php'; ?>
etc.
Run Code Online (Sandbox Code Playgroud)

对于子目录页面,我一直这样做:

<?php include '../includes/logo.php'; ?>
<?php include '../includes/main_nav.php'; ?>
<?php include '../includes/news.php'; ?>
Run Code Online (Sandbox Code Playgroud)

还有这个:

<?php include '../../includes/logo.php'; ?>
<?php include '../../includes/main_nav.php'; ?>
<?php include '../../includes/news.php'; ?>
Run Code Online (Sandbox Code Playgroud)

到目前为止这么好,但我怀疑它不会继续这么容易.

现在我需要包含这个文件:

top_five_news_stories.php
Run Code Online (Sandbox Code Playgroud)

在这:

news.php
Run Code Online (Sandbox Code Playgroud)

此时,我的相对路径策略失败,因为include中的include只能有一个路径结构.

我已经阅读了几篇推荐使用绝对路径的帖子:

  • dirname(__FILE__)
  • realpath(dirname(__FILE__)
  • $_SERVER["DOCUMENT_ROOT"]

但是,它们都带有与PHP配置,服务器配置或操作系统相关的某种警告.换句话说,通常有人评论说它在他们的情况下不起作用,或者在IIS中不起作用,或者在UNIX中不起作用,或者其他东西.

我没有看到的解决方案是我认为最简单的解决方案:只需设置一个变量:

$base = "https://www.mywebsite.com/includes";
Run Code Online (Sandbox Code Playgroud)

然后:

<?php include $base . "logo.php" ?>
Run Code Online (Sandbox Code Playgroud)

考虑到我已经使用了以类似方式工作的HTML base元素,这种方法让我觉得简单而有效.

但是因为在我读过的任何帖子中没有提到它,我想知道我是否忽视了一个潜在的问题.

坦率地说,如果我今天必须去制作,我会用这个:

<?php include  $_SERVER['DOCUMENT_ROOT'] . '/logo.php" ?>
Run Code Online (Sandbox Code Playgroud)

这对我有用,通常被提及.

但我想知道使用变量是否是一种可靠,有效的方法?

Jas*_*wer 11

我建议不要使用任何需要PHP以外的东西,比如$ _SERVER变量.

$_SERVER['DOCUMENT_ROOT']通常由Web服务器设置,这使得从命令行运行的脚本无法使用.所以不要使用它.

也不要使用url.在一个URL路径的部分是不一样的磁盘上的文件的路径.实际上,该路径甚至不能存在于磁盘上(想想Apache重写).

包括url还需要你打开allow_url_include,如果使用不当会引入(严重)安全风险.

如果你支持的最小PHP版本是5.3(我希望它是!),你可以使用魔术常量 __DIR__.2个例子:

define(ROOT_DIR, __DIR__);
define(ROOT_DIR, realpath(__DIR__ . '/..'));
Run Code Online (Sandbox Code Playgroud)

如果您需要支持较低版本,请使用dirname(__FILE__).2个例子:

define(ROOT_DIR, dirname(__FILE__));
define(ROOT_DIR, realpath(dirname(__FILE__) . '/..'));
Run Code Online (Sandbox Code Playgroud)

确保ROOT_DIR指向项目的根目录,而不是指向其中的某个子目录.

然后,您可以安全地使用ROOT_DIR以包含其他文件:

include ROOT_DIR . '/some/other/file.php';
Run Code Online (Sandbox Code Playgroud)

请注意,我定义的是constant(ROOT_DIR),而不是变量.变量可以更改,但是项目的根目录不会更改,因此常量更适合.

真实路径()

realpath()将任何相对的部分和符号链接解析为规范化的绝对​​路径名.

所以给出以下文件和符号链接:

/path/to/some/file.php
/path/to/another/file.php
/path/to/symlink => /path/to/another
Run Code Online (Sandbox Code Playgroud)

/path/to/file.php包含:

define(ROOT_DIR, realpath(__DIR__ . '/../symlink'));
Run Code Online (Sandbox Code Playgroud)

然后ROOT_DIR会变成/path/to/another,因为:

  • __DIR__等于/path/to/some(所以我们得到/path/to/some/../symlink)
  • ..是1目录(所以我们得到/path/to/symlink)
  • symlink 指着 /path/to/another

你真的不需要使用realpath()它,但是如果你依赖于相关部分或符号链接,它确实可以整理路径.它也更容易调试.

自动加载

如果您需要包含包含类的文件,最好使用自动加载.这样你根本不需要include陈述.

使用框架

最后一点建议:这个问题已经解决了很多次.我建议你去研究像Symfony,Zend Framework,Laravel等框架.如果你不想要一个"全栈"解决方案,那么看看像Silex,Slim,Lumen等微框架.