代码之家  ›  专栏  ›  技术社区  ›  Mr Glass

PHP要求一次或多次调用

  •  0
  • Mr Glass  · 技术社区  · 7 年前

    我把解决方案贴出来作为答案

    我在将一些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(“u common_funcs.php”)来包含该文件。这是非常基本的方法。

    在新服务器上 第一次 a脚本运行时会生成“无法重新声明”错误。刷新页面不会显示错误-它按预期显示页面。例如:

    • //localhost/app/display_account.html?account=123456生成错误。
    • //localhost/app/display_account.html?account=123456再次不显示错误。

    重新启动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
    

    如果我将完整路径硬编码为一行,并使用小写'd',则日志中的错误将交换大小写。此结果为“d:\app…”和“d:\app…”。

    如果我硬编码两个调用,当这个脚本运行时,不管我使用什么大小写组合,都不会生成错误。

    为了更有趣一点,acct_has_graduated()函数是\u common_funcs.php文件中的最后一个函数。但是如果我在php.in i中禁用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文件中的第一个函数,“line 42”是update_ledger()函数的右括号(第7行是声明)。

    如果有人能给我指明正确的方向,我会非常感激的。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Mr Glass    7 年前

    解决方案

    我发现了这个问题,文件肯定被包括了两次。这是在特定的情况下发生的。它影响php 7.0,但不影响php 5.3。我没有测试任何其他版本的PHP。

    这种情况当然是一种异常情况,但这里是:

    1. 我有一个从c:\inetpub\wwwroot\app_location到d:\app_location的目录符号链接。
    2. 此网站的IIS配置指向C:\inetpub\wwwroot\app_位置。
    3. 应用程序的配置文件使用C:\inetpub\wwwroot\app_位置作为基础定义include_路径。
    4. 此站点的所有文件都位于d:\app\u位置。

    使用以上配置,应用程序日志文件中的所有条目(跟踪、审核、错误和回溯)显示 D:\应用程序位置 作为所有文件的基本位置。

    在允许include路径解析文件在 一个或两个电话 ,生成“无法重新声明”错误。错误报告“d:”驱动器号的大小写相反(请参阅上面文章中的错误文本)。

    将include_路径的基础(3)更改为d:\app_位置解决了这个问题。

        2
  •  -1
  •   Wils    7 年前

    问题很简单。

    require_once('D:\file.php');
    require_once('file.php');
    

    将运行两次,因为您包括绝对路径!

    解决方案 使用相对路径

    require_once('../core/file.php');