1

最近、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 クラスの 1 つで、次のようなコードを使用してコンストラクターで 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 クラスをインスタンス化する関数を作成し、別のデータベースに接続できるようにします。この 2 番目の要件がエラーの原因であり、その理由がわかりません。show_text から require を削除するか、require_once に変更すると、正常に動作します。

このコードが失敗する原因となる、これら 2 つのバージョン間の変更点を誰か知っていますか? $db2 が require なしでどのように適切に初期化されているかさえわかりません。クラスコンストラクターを要求すると、ファイル内でグローバルに表示されますか?

編集: これはログの問題ではなく、アップグレード前にエラーは発生していませんでした。アプリはアップグレードまで正常に動作していました。これは、エラーログでエラーを有効にした方法です。

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();
  }
}

ファイルの先頭に属している必要があり、遅くなりますがrequire_once、ファイルが2回必要になるのを防ぎ、そのエラーが発生します

あなたが何をしようとしているのかを知っていると本当に仮定することはできません。しかし、グローバルを取り除き、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

以前のPHPバージョンでもこれらのエラーが発生しました。エラーが有効になっているのは、これだけです(これは、開発環境で常に実行する必要があります)。クラスを「ロード」できるのは1回だけです。製品環境にデプロイする場合でも、エラーを有効にする必要がありますが、エラーを表示するのではなく、ログに記録するだけです。

エラー報告を有効にするには、次のようにします。

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 に答える
2

あなたのクラスでは、に変更requirerequire_onceます。これにより、ファイルが最大 1 回ロードされることが保証されます。

于 2012-12-20T18:32:36.503 に答える