10

質問

PHPに致命的なエラーを発生させるのではなく、クラスの再宣言を無視させる方法はありますか?または、少なくとも例外をスローしますか?(私はそれを簡単にキャッチして続行することができました(また、試行された自動ロードのログも記録します)。)

私はノーだと思います、そして致命的なエラーは致命的なエラーです-結局のところ、100のケースのうち99で、それは合理的に賢明な振る舞いです-そして私はおそらくそれがケースでトリガーされるインスタンスを修正する必要があります-ケースバイケース。しかし、多分私より賢い誰かがこれを理解しました。


「いったいなぜそんなことをしたいのか」と自問しているのなら、読み続けてください。

バックグラウンド

私は、Reflectionを使用して、使用されている関数とクラスに関する特定の情報を集約するツールに取り組んでいます。スクリプトの引数の1つは、自動ロードでReflectionの信頼性を高めるためのオプションのブートストラップファイルです(ReflectionExceptions特定のファイルではクラスが不明であるため、キャッチされてフォールバックヒューリスティックがトリガーされることはありません)。

これで、ブートストラップはオートローダーを正常にロードし、スクリプトは意図したとおりに実行され、問題が発生するまで、何百ものファイルを文句なしに移動します。

PHPの致命的なエラー:62行目の/usr/share/php/PHPUnit/Framework/Constraint.phpでクラスPHPUnit_Framework_Constraintを再宣言できません

私には2つの問題があります:

1つは、何がこれを引き起こしているのかわかりません。使用するブートストラップを調整しましたが、使用するインクルードパスに応じて、「再宣言できません」と「ファイルを開けませんでした」が交互に表示されます。妥協点はありません。つまり、エラーが発生しないポイントはありません。それでも、私はまだ調査中です。(ただし、この問題は質問の内容ではありません。)

2つ、さらに重要なことに、この質問の主題につながるので、私はそれを捕まえる方法が必要です。カスタムエラーハンドラを作成しようとしましたが、sに対しては機能したくないようですFatal error(ある程度賢明なことに、議論の余地があるかもしれません)。

私はこのツールをいつかオープンソースの世界にリリースするつもりですが、これは非常に容認できない振る舞いとして私を襲います。存在しないクラスのフォールバックヒューリスティックがあります-ヒューリスティックを過度に使用せずに、一度はあまり頻繁に宣言されるのではなく、一度宣言されることをお勧めします。つまり、ブートストラッパーを使用する機能。スクリプトを壊すことなく。これまで。オートローダーの歴史の中で最悪のオートローダーだとしても。

(強調するために:オートローダーの助けは必要ありません。それはこの質問の内容ではありません。

4

3 に答える 3

8

避けるべき最良のオプションの1つはCannot redeclare関数class_existsです。クラスの再宣言を防ぐために、オートローダーで使用できます。エラーをキャッチするclass_exists必要はなく、それを防ぐだけです。

実際には、キャッチ可能なエラーとキャッチできないエラーの2種類の致命的なエラーがあります。クラスの再宣言はE_RECOVERABLE_ERROR(キャッチ可能なもの)を起動せず、あなたはそれを処理することができません。

したがって、あなたの質問に対する答えは、「できません」です。

于 2010-07-14T13:46:56.783 に答える
3

あなたがまだ答えに興味があるかどうかはわかりませんが、自動読み込みとリフレクションを混合したときに発生したのと同じ問題が発生した可能性があります。自動読み込みが失敗する理由に関する私の仮説は次のとおりです。

spl_autoload_register完全に指定された名前空間のクラス識別子を使用して自動ロードされたクラスと、名前空間を含まないクラス識別子を使用して名前空間内からロードされたクラスを区別します。私の知る限り、これはバグです。

私の解決策:クラス識別子が完全に名前空間になっている場合は、リフレクションクラスインスタンスを作成する前にテストします。そうでない場合は、リフレクションを使用しません。一部のクラスがロードされなくてもかまわないので、これも問題の解決策になる可能性があります。

于 2013-04-12T19:58:03.160 に答える
2

Autoloadは、すでにロードされているクラスを自動的にロードしようとはしません。同じ名前のクラスが1つ以上ある場合は、おそらく間違っています。

「安全でない」コードを解析する場合は、ロードする前にファイルでクラス名を検索することをお勧めしますが、これはCPUの大きな浪費であり、おそらく有効なバグを隠すだけなので、最後の手段としてのみ使用してください。

require構造と自動ロードシステムがある場合は、ファイルを一度自動ロードに含めてから、もう一度requireに含めることができます。クラスをでラップすることで修正をハックできますif( class_exists( <class_name_string> ) { ... <class declaration in here> ... }

于 2010-07-14T14:01:36.023 に答える