PHP:当我从另一个目录中包含一个文件时,为什么会有这种奇怪的行为?

PHP:当我从另一个目录中包含一个文件时,为什么会有这种奇怪的行为?,php,include,nested,path,Php,Include,Nested,Path,我从没见过这样的事 文件结构: somefolder/base.php includes/stuff.php 包括/constants.php base.php: <?php require("../includes/stuff.php"); ?> <?php require("constants.php"); echo "Welcome to stuff.php"; ?> <?php echo "IMPORTANT CONSTANTS DE

我从没见过这样的事

文件结构:

  • somefolder/base.php
  • includes/stuff.php
  • 包括/constants.php
base.php:

<?php require("../includes/stuff.php"); ?>
<?php 
   require("constants.php"); 
   echo "Welcome to stuff.php";
?>
<?php echo "IMPORTANT CONSTANTS DEFINED HERE!";  ?>

stuff.php:

<?php require("../includes/stuff.php"); ?>
<?php 
   require("constants.php"); 
   echo "Welcome to stuff.php";
?>
<?php echo "IMPORTANT CONSTANTS DEFINED HERE!";  ?>

constants.php:

<?php require("../includes/stuff.php"); ?>
<?php 
   require("constants.php"); 
   echo "Welcome to stuff.php";
?>
<?php echo "IMPORTANT CONSTANTS DEFINED HERE!";  ?>

结果:

<?php require("../includes/stuff.php"); ?>
<?php 
   require("constants.php"); 
   echo "Welcome to stuff.php";
?>
<?php echo "IMPORTANT CONSTANTS DEFINED HERE!";  ?>
欢迎来到stuff.php

为什么它不显示constant.php消息?!我会告诉你什么不是问题:它不是php代码

我从一些复杂的文件开始,其中常量文件实际上定义了一些常量,出于某种原因,只有前几个常量起作用。我最终禁用了所有无关的代码,包括DEFINE(),并且只使用了echo语句,而这个问题仍然困扰着我。顺便问一下,不管代码的顺序如何,一些已定义的常量如何通过而不是任何echo

所以我最终意识到这是荒谬的,并决定创建一些新文件作为测试。那些是有效的。也许他们没有,我忘了。无论如何,通过创建新文件并尝试将它们四处移动以及将代码从一个文件复制到另一个文件,我已经取得了一定程度的成功,但似乎没有任何押韵或理由

哇,这是刚刚进来的:我让constants.php文件以不同的名称工作,但当我将其更改为constants.php时,它停止工作了!我尝试在不同的浏览器中清除缓存/打开并重新启动服务器,但没有任何帮助。我觉得不是我就是我的电脑在吸毒。哈哈哈


编辑 啊哈。我遗漏了一条看起来很重要的信息。一个我没提到的文件

  • somefolder/constants.php
正在包含该文件,而不是includes/constants.php。这就是为什么我没有收到任何丢失的文件错误。那完全是令人困惑的事情!我希望sub-include发生在更高级别的include之前,因此stuff.php会在它自己的目录中查找constants.php,但我猜base.php包含stuff.php,然后base.php执行stuff.php中指定的include,这意味着include是相对于base.php的。因此,绝对路径毕竟是解决方案

附加编辑:

<?php require("../includes/stuff.php"); ?>
<?php 
   require("constants.php"); 
   echo "Welcome to stuff.php";
?>
<?php echo "IMPORTANT CONSTANTS DEFINED HERE!";  ?>

非常有趣。我仍然感到困惑,为什么以前我只是简单地更改了includes/constants.php的名称(例如改为constanza.php)就可以工作。看起来文件包含不是那么简单。如果有两个文件具有相同的名称,则与执行包含操作的父文件相比,它更倾向于使用相对的文件。但是,如果它没有选择,它将相对于子对象进行操作。

包含中使用的路径与包含的文件无关:它们与子对象相关

这意味着将相对路径与include/requires一起使用通常不会达到您期望的效果


通常使用的解决方案是使用绝对路径;这样,您就可以确定包含哪些内容

当然,在代码中使用绝对路径是不好的(当您的应用程序部署到另一个路径时,它将在一台服务器上工作,而不是在另一台服务器上工作);因此,解决办法是:

  • 获取您所在文件的绝对路径
  • 除了到另一个文件的相对路径之外,还可以使用该路径来包含该文件

您所在文件的完整路径可以通过
\uuuuu file\uuuu
获得

这意味着可以使用
dirname(\uu file\uu)
获取当前文件(写入指令的文件)的目录

之后,只需写下正确的路径。
例如,在
stuff.php
中,您将使用:

require(dirname(__FILE__) . "/constants.php"); 
require(dirname(__FILE__) . "/../includes/stuff.php");
而在
base.php
中,您将使用:

require(dirname(__FILE__) . "/constants.php"); 
require(dirname(__FILE__) . "/../includes/stuff.php");

包含中使用的路径与包含的文件无关:它们是相对于文件的

这意味着将相对路径与include/requires一起使用通常不会达到您期望的效果


通常使用的解决方案是使用绝对路径;这样,您就可以确定包含哪些内容

当然,在代码中使用绝对路径是不好的(当您的应用程序部署到另一个路径时,它将在一台服务器上工作,而不是在另一台服务器上工作);因此,解决办法是:

  • 获取您所在文件的绝对路径
  • 除了到另一个文件的相对路径之外,还可以使用该路径来包含该文件

您所在文件的完整路径可以通过
\uuuuu file\uuuu
获得

这意味着可以使用
dirname(\uu file\uu)
获取当前文件(写入指令的文件)的目录

之后,只需写下正确的路径。
例如,在
stuff.php
中,您将使用:

require(dirname(__FILE__) . "/constants.php"); 
require(dirname(__FILE__) . "/../includes/stuff.php");
而在
base.php
中,您将使用:

require(dirname(__FILE__) . "/constants.php"); 
require(dirname(__FILE__) . "/../includes/stuff.php");

我发现一些有用的东西是检查
getcwd()
(获取当前工作目录),这将返回包含该文件的文件的文件夹路径。如果include文件是在我的顶级目录下(下一级)调用的,那么我可以计算并预先设置适当数量的
。/
s

也就是说,如果我知道我的include文件位于
topfolder/css/blah.css
中,那么我可以像这样检查我的include文件中
getcwd()
的值:

$leaveDirectoryIfNecessary = "";
// Grab the last 9 characters of the directory name
if (substr(getcwd(), -9) != "topfolder") {
    $leaveDirectoryIfNecessary = "../";
}
然后,我会在include文件中引用的每个文件之前
echo$leavedirectoryif needed
,如下所示:

<link rel="stylesheet" type="text/css" href="<?php echo $leaveDirectoryIfNecessary; ?>css/goodstuff.css">

我发现一些有用的东西是检查
getcwd()
(获取当前工作目录),这将返回包含该文件的文件的文件夹路径。如果include文件是在我的顶级目录下(下一级)调用的,那么我可以计算并预先编写