从PHP 5.3.8升级到5.3.20后,开始接收无法重新声明类错误

时间:2012-12-20 18:27:01

标签: php

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

  

[20-Dec-2012 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,则可以正常工作。

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

修改 这不是日志记录问题,并且在升级之前没有发生错误。应用程序正常运行,直到升级。这就是我在错误记录中启用错误的方法:

error_reporting  = E_ALL & ~E_NOTICE

3 个答案:

答案 0 :(得分: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();
  }
}

需要属于文件的顶部,虽然速度较慢,但​​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
  }
}

答案 1 :(得分:2)

在课堂上,将require更改为require_once。这可确保文件最多加载一次。

答案 2 :(得分: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)。虽然默认情况下它们是公开的,但添加它总是更好,所以人们不会认为这是一个错误。

您可能还想阅读autoloading your classes /这会阻止您执行require_*include_*和朋友,这样可以帮助您保持代码清洁,防止在忘记加载类时出错也可以防止你现在遇到的错误。