14

「Behat」ステップを実行しているとき、Behatエラーハンドラーは「非オブジェクトのプロパティを取得しようとしています」エラーを例外に変えます。

これにより、ステップが失敗としてマークされ、次のシナリオでテスト実行を続行できるため、非常に役立ちます。

ただし、「非オブジェクトでのメンバー関数の呼び出し」エラーは致命的であり、テストの実行をすぐに停止します(結果のxmlへの書き込みの中止を含む)。これは役に立ちません。

私の質問は次のとおりです。

  1. これら2つのエラーの違いは何ですか?それらは異なる「エラーレベル」ですか?それはどこに文書化されていますか?PHPサイトとGoogleを検索しましたが、正規のリファレンスが見つかりません。各エラーの特定のインスタンスのデバッグに関する質問がたくさんあります。

  2. スクリプトを完全に停止する代わりに、後者のエラーを例外に変換する方法はありますか?null「 」を「」で逆参照->することは、「メモリ割り当ての問題など、「回復できない」というエラーになるとは思えません。

アップデート:

これはPHPの既知の問題のようです。見る:

  • #51882非オブジェクトのメンバー関数への呼び出しは例外をスローする必要があります
  • #46601「非オブジェクトのメンバー関数の呼び出し」のE_RECOVERABLE_ERROR
  • #51848非オブジェクトメソッド呼び出しエラーはset_error_handler()でキャッチ可能である必要があります
  • #63538「未定義の関数の呼び出し」はキャッチ可能である必要があります

これは「設計による」と言う人もいますが、これは、オブジェクトがPHPに追加される前に定義されたエラーレベルのアーティファクトにすぎないと思います。非OO言語では、存在しない関数を呼び出すことは重大なエラーであり、「致命的」または「回復不能」としてどのように記述されるかを確認できます(ただし、関数を定義できる非OO言語では-その場で、それでも過度に悲観的に見える)。最近では、$a->f()古いものに対して ""を実行できるようになったため、 $a""が存在しない可能性がはるかに高くf、致命的なエラーではないようです(Javaを参照してください。これはNullPointerExceptionになります)。

私はそれが私を新しい質問に導くと思います:

_ 3.下位互換性を大幅に損なうことなく、「非オブジェクトでのメンバー関数の呼び出し」エラーを致命的ではないものにするためにPHPにパッチを適用するにはどうすればよいですか。また、そのパッチがPHPに受け入れられる可能性を最大化するためにどのような手順を実行できますか。 ?

PHPにパッチを適用するアップデート2 :

この修正を行うためのPHP内部メーリングリストのサポートには制限があります。これを修正してRFCを作成するためのパッチを作成する必要があります。

4

3 に答える 3

4

問題は、オブジェクトのプロパティを動的に宣言することはできますが、メソッドを動的に宣言することはできないということです。したがって、非オブジェクトでメソッドを呼び出そうとすると、PHPが関数が存在することを判別できなかったため、致命的なエラーが発生します。

このコードパッドで、エラー番号を含む簡単な出力を確認してください。

ここで、「未設定のプロパティの設定とアクセス」に関する部分をよく見てください。PHPが「空の値からデフォルトオブジェクトを作成しています」というメッセージを表示していることがわかります。したがって、クラスが存在しない場合は、PHPがクラスを作成します。型キャストを使用する場合も同じことが起こります。オブジェクトの型キャストを参照してください。

したがって、動的に作成されたデフォルトオブジェクトでそのプロパティをチェックするため、非オブジェクトのプロパティにアクセスできます。ただし、メソッドにアクセスする場合、そのデフォルトオブジェクトにはまだそのメソッドがありません。

そのため、プロパティはレベル8のエラーを返し、メソッドはレベル1のエラーを返します(エラーレベルを参照)。また、レベル1の致命的なエラーが返されるため、このプロセスの後で続行することはできません。

于 2013-03-19T15:15:57.053 に答える
3

これはPHP7で修正されました。

PHP 7以降では、このコードは、回復不能な致命的なエラーを引き起こす代わりにスローするようになりました。

于 2017-01-31T21:35:17.417 に答える
0

良いニュースがあります。すべてのPHPエラーをキャッチ可能な例外に変換するErrorExceptionsと呼ばれるPHPライブラリが利用可能です。

これは物事の仕組みにかなり劇的な変化をもたらしますが、これをやりたいと思っているのは明らかにあなただけではありません。

libは、PHPのコア開発者の1人であるAnthony Ferraraによって作成されているため、彼が何をしているかをかなり確実に理解できますが、自分で実行したい場合は、set_error_handler()関数を使用してPHPにプラグインします。PHPのエラーをトラップしたい場合は、これがその方法です。

お役に立てば幸いです。

于 2013-03-19T16:59:25.550 に答える