我在各种包含文件的顶部有这段代码:
require_once("functions.php");
有时我需要包含我的几个包含文件来生成一个页面,并且在我的本地服务器上这工作正常,因为上面的代码告诉它只包含 functions.php 一次(因此它不会尝试两次声明函数)。
当我上传到我的生产服务器时,它突然尝试第二次包含 functions.php,导致第二次尝试重新声明函数时出现致命错误。
我的生产服务器上的 php 配置中有什么东西会导致 require_once 的行为不同吗?
我在各种包含文件的顶部有这段代码:
require_once("functions.php");
有时我需要包含我的几个包含文件来生成一个页面,并且在我的本地服务器上这工作正常,因为上面的代码告诉它只包含 functions.php 一次(因此它不会尝试两次声明函数)。
当我上传到我的生产服务器时,它突然尝试第二次包含 functions.php,导致第二次尝试重新声明函数时出现致命错误。
我的生产服务器上的 php 配置中有什么东西会导致 require_once 的行为不同吗?
您是否有可能有名为functions.php 的重复文件?您的示例代表一个相对位置,您是否可以加载它两次?
也许
echo __FILE__要从函数文件中调试它。
您可以使用以下代码:
require_once(realpath(dirname(__FILE__) . '/functions.php'));
并修改之前的路径位置functions.phpiffunctions.php位于 root 中的另一个目录中。函数 realpath(dirname( FILE ) 获取根文件夹的路径。因此,您应该在 index.php 中包含您的函数,并修改您的 function.php 是否在任何目录中,例如:
require_once (realpath(dirname(__FILE__) . '/your_directory_name/functions.php'));
享受!!
检查您的路径设置,如果函数名称是通用的,则很可能正在加载另一个同名文件。除了回显提到的__FILE__值之外,只需尝试将其命名为您知道的唯一名称和/或使用绝对路径,例如
require_once dirname(__FILE__).'/functions.php';
也许两台服务器上的错误处理级别设置不同?
如果我没记错的话,require_once 会在多次调用时简单地返回 true。
这种构造可能会产生一些奇怪的结果:
使用 include_once 加载(甚至是伪造的)文件两次,返回值将是 true。
例子:
<?php
var_dump(include_once 'fakefile.ext'); // bool(false)
var_dump(include_once 'fakefile.ext'); // bool(true)
?>
这是因为根据 php,该文件已经包含一次(即使它不存在)。
不确定这是否与 require_once 相同,但很可能是因为文档引用了 include_once 以了解此构造的预期行为。
在不区分大小写的文件系统中,require_once语言结构将指向同一个文件,而不管路径中的任何大小写。然而,这就是问题所在,尽管不同的大小写变体指向同一个文件,但在检查文件是否已被包含时,它们不会被视为同一个文件。
require_once __DIR__.'/address/src/Coordinates.php';
require_once __DIR__.'/Address/src/Coordinates.php';
在上面的示例中,在不区分大小写的文件系统中,两行都将尝试要求同一个文件。第二个文件会成功,因为路径的大小写不同。
如果您在所需文件中有更多的 require_once 语言结构,情况会变得更糟,即您正在执行多级requires,并结合相对路径。在这种情况下,嵌套的相对路径将使用更高级别requires中使用的大小写解析为完整路径。如果在这个嵌套结构的任何地方使用不同的大小写,您将遇到同样的问题。
var_dump(get_included_files());
这将为您提供包含文件的列表,其中包含您使用的完整路径和确切的大小写。这将帮助您快速找到 colprit。
老实说,我想不出任何会导致这种行为的事情,如果我对您的网站的结构有所了解,我可以就如何以不同的方式构建它提供一些建议,这样就不会发生这种情况。
我在我的网站上做的事情是有这种设置:
global.php <- 诸如配置数据库之类的东西,包括带有随机函数的文件
header.php <- 基本的 html 头文件,这里需要 global.php_once。
然后在所有其他文件中,只需要头文件,你应该没有冲突。如果您使用的是特定框架(CakePHP、Kohana),那么这肯定会改变一些事情......就像我说的那样,没有足够的信息可以立即进行。
如果您包含包含类的文件,您可能希望尝试使用__autoload,它应该可以防止多个包含/要求运行,并防止您列出一堆包含/要求。