Saya ingin cara yang lebih bersih untuk mendapatkan fungsionalitas berikut, untuk menangkap AError
dan BError
dalam satu blok:
try
{
/* something */
}
catch( AError, BError $e )
{
handler1( $e )
}
catch( Exception $e )
{
handler2( $e )
}
Apakah ada cara untuk melakukan ini? Atau apakah saya harus menangkapnya secara terpisah?
AError
dan Berror
memiliki kelas dasar bersama, tetapi mereka juga berbagi dengan tipe lain yang ingin saya ikuti handler2
, jadi saya tidak bisa hanya menangkap kelas dasar.
php
exception-handling
Dominic Gurto
sumber
sumber
Jawaban:
Memperbarui:
Pada PHP 7.1, ini tersedia.
Sintaksnya adalah:
Documents: https://www.php.net/manual/en/language.exceptions.php#example-287
RFC: https://wiki.php.net/rfc/multiple-catch
Komit: https://github.com/php/php-src/commit/0aed2cc2a440e7be17552cc669d71fdd24d1204a
Untuk PHP sebelum 7.1:
Terlepas dari apa yang dikatakan jawaban-jawaban lain ini, Anda dapat menangkap
AError
danBError
di blok yang sama (agak lebih mudah jika Anda yang menentukan pengecualian). Bahkan mengingat bahwa ada pengecualian yang ingin Anda "gagal", Anda masih harus dapat mendefinisikan hierarki yang sesuai dengan kebutuhan Anda.Kemudian:
Seperti yang dapat Anda lihat di sini dan di sini , bahkan
SPL
pengecualian standar memiliki hierarki yang dapat Anda manfaatkan. Selain itu, sebagaimana dinyatakan dalam Manual PHP :Ini berarti Anda juga bisa memilikinya
yang perlu Anda tangani secara berbeda dari
AError
atauBError
, sehingga pernyataan tangkapan Anda akan terlihat seperti ini:Jika Anda memiliki kasus di mana ada dua puluh atau lebih pengecualian yang secara sah berada di bawah superclass yang sama, dan Anda perlu menangani lima (atau kelompok besar apa pun) dari mereka satu arah dan sisanya dengan cara lain, Anda MASIH dapat melakukan ini.
Lalu:
Menggunakan OOP dalam hal pengecualian sangat kuat. Menggunakan hal-hal seperti
get_class
atauinstanceof
merupakan peretasan, dan harus dihindari jika memungkinkan.Solusi lain yang ingin saya tambahkan adalah menempatkan fungsi penanganan pengecualian dalam metodenya sendiri.
Kamu bisa saja
Dengan asumsi sekali tidak ada cara Anda dapat mengontrol hierarki kelas pengecualian atau interface (dan ada hampir selalu akan menjadi cara), Anda dapat melakukan hal berikut:
Dengan cara ini, Anda masih memiliki satu-satunya lokasi kode yang harus Anda modifikasi jika mekanisme penanganan pengecualian Anda perlu diubah, dan Anda bekerja dalam konstruksi umum OOP.
sumber
AError
dapat diimplementasikan di perpustakaan / file yang diperbarui oleh pihak ketiga.Dalam PHP> = 7.1 ini dimungkinkan. Lihat jawabannya di bawah.
Jika Anda dapat memodifikasi pengecualian, gunakan jawaban ini .
Jika tidak bisa, Anda bisa mencoba menangkap semua dengan
Exception
dan kemudian memeriksa pengecualian yang dilemparkan denganinstanceof
.Tetapi mungkin akan lebih baik untuk menggunakan beberapa blok penangkap seperti dijelaskan dalam jawaban yang disebutkan di atas .
sumber
finally
pernyataan. ;)... } else { throw($e); }
jika tidak cocok dengan keduanya. Maaf untuk sintaks yang mungkin salah, tidak melihat php sebentar.Datang dalam PHP 7.1 adalah kemampuan untuk menangkap beberapa tipe.
Jadi ini:
dan
secara fungsional setara.
sumber
Pada PHP 7.1,
Menariknya, Anda juga dapat:
dan dalam versi PHP sebelumnya:
sumber
Artikel ini membahas pertanyaan electrictoolbox.com/php-catch-multiple-exception-types . Konten tulisan disalin langsung dari artikel:
Pengecualian contoh
Berikut beberapa contoh pengecualian yang telah ditentukan untuk keperluan contoh ini:
Menangani banyak pengecualian
Ini sangat sederhana - bisa ada catch block untuk setiap jenis pengecualian yang dapat dilemparkan:
Jika pengecualian dilemparkan yang tidak ditangani oleh salah satu pernyataan tangkapan lainnya, maka akan ditangani oleh blok tangkapan (Pengecualian $ e). Itu tidak harus menjadi yang terakhir.
sumber
catch (Throwable $e)
menangkap semua pengecualian. Lihat juga: php.net/manual/en/class.throwable.phpSebagai ekstensi untuk jawaban yang diterima, Anda bisa mengganti tipe Pengecualian yang menghasilkan pola yang agak seperti contoh aslinya:
sumber
Berikut adalah alternatif yang masuk akal jika Anda tidak memiliki kendali untuk mendefinisikan pengecualian. Gunakan nama variabel pengecualian untuk mengkategorikan pengecualian ketika mereka ditangkap. Kemudian periksa variabel pengecualian setelah blok coba / tangkap.
Pendekatan yang tampak aneh ini mungkin hanya layak jika ada banyak duplikasi antara implementasi catch block.
sumber
Selain gagal, mungkin juga untuk melangkah dengan menggunakan goto . Ini sangat berguna jika Anda ingin melihat dunia terbakar.
3v4l.org
sumber
Cara terbaik adalah menggunakan
set_exception_handler
.Peringatan!!! dengan PHP 7, Anda mungkin mendapatkan layar putih kematian karena kesalahan fatal. Misalnya, jika Anda memanggil metode pada non-objek yang biasanya Anda dapatkan
Fatal error: Call to a member function your_method() on null
dan Anda akan melihat ini jika pelaporan kesalahan aktif.Kesalahan di atas TIDAK akan tertangkap
catch(Exception $e)
. Kesalahan di atas TIDAK akan memicu penangan kesalahan kustom yang ditetapkan olehset_error_handler
.Anda harus menggunakan
catch(Error $e){ }
untuk menangkap kesalahan dalam PHP7. . Ini bisa membantu:sumber
catch (Throwable $e) { ... }
dan selesai dengan itu. Lihat juga: php.net/manual/en/class.throwable.phpOpsi lain yang tidak tercantum di sini adalah menggunakan
code
atribut pengecualian, sehingga Anda dapat melakukan sesuatu seperti ini:sumber
extends \Exception
?Hmm, ada banyak solusi yang ditulis untuk versi php lebih rendah dari 7.1.
Ini adalah salah satu yang sederhana bagi mereka yang tidak ingin menangkap semua pengecualian dan tidak dapat membuat antarmuka umum:
sumber