1

我最近将 PHP 5.3.8 升级到 5.3.20。升级完成后,我开始收到大量无法重新声明的错误:

[2012 年 12 月 20 日 11:15:00 America/New_York] PHP 致命错误:无法在第 3 行的 /var/www/htdocs/includes/mysql.php 中重新声明类用户

在我的一个 PHP 类中,我使用如下代码在构造函数中实例化一个 mysql 类:

class foo {
  function foo() {  
    global $db;

    require '/var/www/htdocs/includes/mySQL.php';
    $db = new mydb_driver();
  }

  function show_text() {
    require '/var/www/htdocs/includes/mySQL.php';
    $db2 = new mydb_driver();
  }
}

在同一个类中,我创建了一个函数,该函数使用不同的变量实例化同一个 mysql 类,以便我可以连接到不同的数据库。第二个要求是触发错误的原因,我不确定为什么。如果我从 show_text 中删除 require 或将其更改为 require_once 它工作正常。

有谁知道这两个版本之间发生了什么变化会导致此代码失败?我什至不确定 $db2 是如何在没有要求的情况下正确初始化的。是否需要类构造函数使其在文件中全局可见?

编辑: 这不是日志记录问题,并且在升级之前没有发生错误。在升级之前,这些应用程序运行良好。这就是我在错误日志中启用错误的方式:

error_reporting  = E_ALL & ~E_NOTICE
4

3 回答 3

4

试试这个

require_once '/var/www/htdocs/includes/mySQL.php';

class foo {
  function foo() {  
    global $db;

    $db = new mydb_driver();
  }

  function show_text() {
    $db2 = new mydb_driver();
  }
}

Requires 属于文件的顶部,虽然速度较慢,但require_once​​会阻止文件被要求两次,给你那个错误

不能真正假设知道您要做什么。但是您也可以将其切换为类似的东西,以摆脱全局变量并将更多内容限制为 PSR 标准

require_once '/var/www/htdocs/includes/mySQL.php';

class foo {
  private $db;

  public function __construct( )
  {
      $this->db = new mydb_driver();
  }
  public function bar() {  
      // Do bar stuff with $this->db
  }

  public function show_text() {
      // Doo show_text stuff with $this->db
  }
}
于 2012-12-20T18:28:44.013 回答
2

在您的班级中,更改requirerequire_once. 这可确保文件最多加载一次。

于 2012-12-20T18:32:36.503 回答
2

您在以前的 PHP 版本中也遇到了这些错误。只是您现在才启用错误(这是您在开发环境中应该始终做的事情)。您只能“加载”一次课程。当您要将它部署到产品环境时,您应该仍然启用错误,但只记录它们而不是显示它们。

要启用错误报告,您可以执行以下操作:

error_reporting(-1); // or you could do `E_ALL` in PHP 5.4
ini_set("display_errors", 1);

此外,您应该停止使用global关键字。这是不好的做法,因为您无法测试代码,引入紧密耦合并可能引入不可预测的结果。

class foo {
    private $db;

    public function __construct($db) {
        $this->db = $db;
    }

    public function foo() {  
        $this->db->doSomething();
    }

    public function show_text() {
        $this->db->doSomething();
    }
}

require '/var/www/htdocs/includes/mySQL.php';
$db = new Mydb_driver();
$foo = new Foo($db);

注意:我还为您的方法添加了可见性(public)。尽管默认情况下它们是公开的,但添加它总是更好,这样人们就不会认为这是一个错误。

您可能还想阅读自动加载类/这会阻止您和朋友这样做require_*include_*因此它有助于保持代码清洁,在忘记加载类时防止错误,并且还可以防止像现在这样的错误。

于 2012-12-20T18:35:23.880 回答