我发布了解决方案作为答案
我在将一些PHP代码迁移到新服务器时遇到了一个奇怪的问题。旧服务器运行PHP 5.3(x86),新服务器运行PHP 7.0(x64)。两者都在IIS 7.5上运行。
导致问题的代码已经生产了近三年没有问题。它在当前的生产服务器以及两个开发系统上运行良好。这三个都运行PHP 5.3(x86)。
当我在新服务器上使用PHP 5.3(x86)时,不会发生这些错误。
共享文件(名为_common_funcs.php)包含从许多脚本调用的常用函数。由于其中一些脚本可以交互,因此我使用require_once(' _common_funcs.php')来包含该文件。这是非常基本的方法。
在新服务器上,第一次一个脚本运行它会生成一个'无法重新声明'错误。刷新页面不会显示错误 - 它会按预期显示页面。例如:
重新启动IIS服务器会导致在第一次运行时再次生成错误。
现在是奇怪的部分。请注意以下错误中驱动器号的大小写:
Cannot redeclare acct_has_graduated() (previously declared in D:\app_directory\includes\_common_funcs.php:2061) in d:\app_directory\includes\_common_funcs.php on line 2061
如果我在一个require_once()行中硬编码完整路径,并使用小写' d',则日志中的错误将交换大小写。结果是&#d; \ app ...'和' D:\ app ...'。
如果我对这个脚本运行时遇到调用的两个调用进行硬编码,那么无论我使用何种大小写混合都不会生成错误。
为了使这更有趣,acct_has_graduated()函数是_common_funcs.php文件中的最后一个函数。但如果我在php.ini中禁用OpCache,我会收到以下错误:
Cannot redeclare update_ledger() (previously declared in D:\app_directory\includes\_common_funcs.php:7) in d:\app_directory\includes\_common_funcs.php on line 42
需要注意两点:update_ledger()是_common_funcs.php文件中的第一个函数,"第42行"是update_ledger()函数的结束括号(第7行是声明)。
如果有人能指出我正确的方向,我会非常感激。
答案 0 :(得分:2)
我发现了问题,文件绝对被包含两次。这是在特定情况下发生的。它会影响PHP 7.0,但不会影响PHP 5.3。我没有测试任何其他版本的PHP。
这种情况肯定是一个异常值,但现在是:
使用上面的配置,应用程序日志文件中的所有条目(跟踪,审核,错误和回溯)都会将 D:\ app_location 显示为所有文件的基本位置。
多次调用文件require_once(),同时允许include_path解析一个或两个调用中文件的位置,生成'无法重新声明&#39 ;错误。该错误报告了“D:”的相反大写字母:'驱动器号(请参阅上面帖子中的错误文本)。
将include_path(上面的#3)的基础更改为d:\ app_location解决了此问题。
答案 1 :(得分:-1)
问题很简单。
require_once('D:\file.php');
require_once('file.php');
会运行两次,因为你包含了绝对路径!
解 使用相对路径
require_once('../core/file.php');