PHP 7.4 では __toString() の例外が許可されます
はじめに
現在禁止されている __toString() は例外をスローし、致命的な問題を引き起こしますエラー。これにより、任意のコードを呼び出すことが危険になり、問題のある汎用 API になります。この RFC は、この制限を取り除くことを目的としています。
現在の動作の理論的根拠は、文字列変換はエンジンと標準ライブラリのさまざまな場所で実行され、例外を「正しく」、つまりできるだけ早く処理する準備がすべての場所で行われているわけではないということです。
技術的な観点から見ると、文字列変換中の例外は、回復可能なエラーを例外に変換するエラー ハンドラーによって引き続きトリガーされる可能性があるため、この制限は最終的には効果がありません。
set_error_handler(function() { throw new Exception(); }); try { (string) new stdClass; } catch (Exception $e) { echo "(string) threw an exception...\n"; }
実際、Symfony はこの脆弱性を悪用します。現在の制限を回避するため。残念ながら、これは PHP 8 で廃止された $errcontext パラメータに依存しています。
ただし、このコード ベースでの文字列変換の完全なレビューを行うまで、このトピックに関する過去の記事では緩和についての議論はありませんでした。この制限。これは、添付の実装リクエストで行われています。
推奨事項
__toString() から例外をスローできるようにすると、通常どおりに動作します。致命的なエラーは発生しなくなりました。
また、「文字列に変換できません」および「__toString() は文字列値を返さなければなりません」という回復可能な致命的なエラーを、PHP 7 で確立されたエラー ポリシーに従って、正しいエラー例外に変換します。
拡張ガイドライン
文字列変換による例外を適切に処理したい拡張機能の作成者は、次のガイドラインを考慮する必要があります。
● If zval_get_string( ), Convert_to_string () とその友人は例外を生成しますが、それでも文字列を生成します。この文字列は一時的なものであることが保証されています。つまり、解放する必要はありませんが、解放することは可能です。状況に応じて、より便利なオプションを選択できます。
# オブジェクトから文字列への変換が失敗した場合、文字列変換の結果は空の文字列になるか、配列が文字列に変換され、エラー ハンドラーによって結果通知が例外に送られる場合があります。配列"。 (動作は以前と同じです。)
# 通常は、通常の if (EG(例外)) check:
zend_string *str = zval_get_string(val); if (EG(exception)) { // Possibly free other resources here. return; }
Except を使用して例外がスローされたかどうかを確認するだけで十分です。 、エラーが発生しやすい操作として変換をモデル化するいくつかのヘルパー API が提供されています。
// Like zval_get_string() but returns NULL on conversion failure. zend_string *str = zval_try_get_string(val); if (!str) { // Possibly free other resources here. return; } // Main code. zend_string_release(str); // Like zval_get_tmp_string() but returns NULL on conversion failure. zend_string *tmp, *str = zval_try_get_tmp_string(val, &tmp); if (!str) { // Possibly free other resources here. return; } // Main code. zend_tmp_string_release(tmp); // Like convert_to_string() but returns a boolean indicating conversion success/failure. if (!try_convert_to_string(val)) { // Possibly free other resources here. return; } // Main code.
try_convert_to_string() は、変換が失敗した場合でも元の値を変更しません。したがって、これを使用することは、convert_to_string() と例外チェックを使用するよりも安全です。
すべての文字列変換をチェックすれば確実に安全になりますが、これらのチェックを無視すると、通常は不必要な計算がいくつか発生し、場合によっては冗長な警告が表示されるだけです。注意すべき主な点は、永続的な構造 (データベースなど) を変更する操作です。
下位互換性のない変更
回復可能な致命的エラーからエラー例外への移行は、技術的には BC ブレークです。
翻訳: https://wiki.php.net/rfc/tostring_Exceptions
以上がPHP 7.4 では __toString() から例外をスローできますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。