Rumah > Soal Jawab > teks badan
Saya ingin cara yang lebih bersih untuk mendapatkan fungsi berikut untuk ditangkap dalam blok AError
和 BError
:
try { /* something */ } catch( AError, BError $e ) { handler1( $e ) } catch( Exception $e ) { handler2( $e ) }
Adakah ada cara untuk melakukan ini? Atau adakah saya perlu menangkap mereka secara individu?
AError
和 Berror
有一个共享基类,但它们也与我想落入 handler2
dikongsi oleh jenis lain, jadi saya tidak boleh menangkap kelas asas sahaja.
P粉7774587872023-10-15 15:07:15
Ini mungkin dalam PHP >= 7.1. Lihat ini jawapan.
Jika anda boleh mengubah suai pengecualian, sila gunakan jawapan ini.
Kalau belum boleh cuba guna Exception
捕获所有异常,然后使用 instanceof
.
try { /* something */ } catch( Exception $e ) { if ($e instanceof AError OR $e instanceof BError) { // It's either an A or B exception. } else { // Keep throwing it. throw $e; } }
Tetapi adalah lebih baik menggunakan berbilang blok tangkapan seperti yang dinyatakan dalam jawapan di atas .
try { /* something */ } catch( AError $e ) { handler1( $e ); } catch ( BError $b ) { handler2( $e ); }
P粉6114563092023-10-15 00:46:51
Ciri ini tersedia bermula dari PHP 7.1.
Sintaksnya ialah:
try { // Some code... } catch(AError | BError $e) { // Handle exceptions } catch(Exception $e) { // Handle the general case }
Dokumentasi: https://www.php.net/manual/en/language.exceptions.php#example-334
RFC: https://wiki.php.net/rfc/multiple-catch
Komit: https://github.com/php/php-src/commit/ 0aed2cc2a440e7be17552cc669d71fdd24d1204a
Walaupun jawapan yang lain ini katakan, anda boleh menangkap AError
和 BError
dalam blok yang sama (lebih mudah jika anda yang menentukan pengecualian). Walaupun terdapat pengecualian yang ingin anda "kecualikan", anda masih boleh menentukan hierarki untuk memenuhi keperluan anda.
abstract class MyExceptions extends Exception {} abstract class LetterError extends MyExceptions {} class AError extends LetterError {} class BError extends LetterError {}
Kemudian:
catch(LetterError $e){ //voodoo }
Seperti yang anda boleh lihat di sinidan di sini, walaupun SPL
pengecualian lalai mempunyai hierarki yang boleh dieksploitasi. Selain itu, seperti yang dinyatakan dalam Manual PHP:
Maknanya anda juga boleh memilikinya
class CError extends LetterError {}
Anda perlu mengendalikannya secara berbeza daripada AError
或 BError
jadi kenyataan tangkapan anda akan kelihatan seperti ini:
catch(CError $e){ //voodoo } catch(LetterError $e){ //voodoo }
Jika anda mempunyai situasi di mana terdapat dua puluh atau lebih pengecualian yang secara sah tergolong dalam kelas super yang sama, dan anda perlu mengendalikan lima daripadanya (atau mana-mana kumpulan besar) sehala dan selebihnya dengan cara lain, anda masih boleh melakukannya.
interface Group1 {} class AError extends LetterError implements Group1 {} class BError extends LetterError implements Group1 {}
Kemudian:
catch (Group1 $e) {}
Menggunakan OOP apabila mengendalikan pengecualian adalah sangat berkuasa. Menggunakan perkara seperti get_class
或 instanceof
adalah penggodaman dan harus dielakkan jika boleh.
Satu lagi penyelesaian yang saya ingin tambahkan ialah meletakkan fungsi pengendalian pengecualian ke dalam kaedahnya sendiri.
Anda boleh memilikinya
function handleExceptionMethod1(Exception $e) { //voodoo } function handleExceptionMethod2(Exception $e) { //voodoo }
Dengan mengandaikan bahawa anda sama sekali tidak mempunyai cara untuk mengawal hierarki atau antara muka kelas pengecualian (dan hampir selalu akan ada cara), anda boleh melakukan perkara berikut:
try { stuff() } catch(ExceptionA $e) { $this->handleExceptionMethod1($e); } catch(ExceptionB $e) { $this->handleExceptionMethod1($e); } catch(ExceptionC $e) { $this->handleExceptionMethod1($e); } catch(Exception $e) { $this->handleExceptionMethod2($e); }
Dengan cara ini, jika mekanisme pengendalian pengecualian anda perlu diubah, anda masih mempunyai satu lokasi kod yang perlu diubah suai dan anda bekerja dalam binaan umum OOP.