Saya dapat menggunakan set_error_handler()
untuk menangkap sebagian besar kesalahan PHP, tetapi tidak berfungsi untuk E_ERROR
kesalahan fatal ( ), seperti memanggil fungsi yang tidak ada. Apakah ada cara lain untuk menangkap kesalahan ini?
Saya mencoba memanggil mail()
semua kesalahan dan menjalankan PHP 5.2.3.
php
fatal-error
terlalu banyak php
sumber
sumber
Jawaban:
Catat kesalahan fatal menggunakan
register_shutdown_function
, yang membutuhkan PHP 5.2+:Anda harus mendefinisikan
error_mail
danformat_error
fungsinya. Sebagai contoh:Gunakan Swift Mailer untuk menulis
error_mail
fungsinya.Lihat juga:
sumber
mail("[email protected]", "My Site: FATAL ERROR", "Details: " . $errno . ' ' . $errstr . ' ' . $errfile . ' ' . $errline);
Saya baru saja menemukan solusi ini (PHP 5.2.0+):
Jenis kesalahan yang berbeda didefinisikan di Konstanta yang Ditentukan sebelumnya .
sumber
If an error handler (see set_error_handler ) successfully handles an error then that error will not be reported by this function.
"register_shutdown_function()
harus lebih awal dari kesalahan fatal.use_1T_memory(); /* memory exhausted error here! */ register_shutdown_function('shutDownFunction');
tidak akan berfungsi seperti yang diharapkan.PHP tidak menyediakan cara konvensional untuk menangkap dan memulihkan dari kesalahan fatal. Ini karena pemrosesan biasanya tidak dapat dipulihkan setelah kesalahan fatal. String yang cocok dengan buffer output (seperti yang disarankan oleh posting asli teknik yang dijelaskan di PHP.net) jelas-jelas keliru. Itu tidak bisa diandalkan.
Memanggil fungsi mail () dari dalam metode penangan kesalahan juga terbukti bermasalah. Jika Anda memiliki banyak kesalahan, server email Anda akan dimuat dengan pekerjaan, dan Anda bisa menemukan diri Anda dengan kotak masuk gnarly. Untuk menghindari hal ini, Anda dapat mempertimbangkan menjalankan cron untuk memindai log kesalahan secara berkala dan mengirimkan pemberitahuan yang sesuai. Anda mungkin juga ingin melihat ke dalam perangkat lunak pemantauan sistem, seperti Nagios .
Untuk berbicara sedikit tentang mendaftarkan fungsi shutdown:
Memang benar bahwa Anda dapat mendaftarkan fungsi shutdown, dan itu jawaban yang bagus.
Intinya di sini adalah bahwa kita biasanya tidak mencoba untuk memulihkan dari kesalahan fatal, terutama tidak dengan menggunakan ekspresi reguler terhadap buffer output Anda. Saya merespons jawaban yang diterima , yang tertaut ke saran di php.net yang sejak itu telah diubah atau dihapus.
Saran itu adalah untuk menggunakan regex terhadap buffer output selama penanganan pengecualian, dan dalam kasus kesalahan fatal (terdeteksi oleh pencocokan terhadap teks kesalahan yang dikonfigurasi apa pun yang mungkin Anda harapkan), cobalah untuk melakukan semacam pemulihan atau pemrosesan lanjutan. Itu tidak akan menjadi praktik yang disarankan (saya percaya itu sebabnya saya tidak dapat menemukan saran asli juga. Saya baik mengabaikannya, atau komunitas php menghapusnya).
Mungkin perlu dicatat bahwa versi PHP yang lebih baru (sekitar 5.1) tampaknya memanggil fungsi shutdown lebih awal, sebelum panggilan balik buffering output diaktifkan. Dalam versi 5 dan sebelumnya, urutan itu adalah kebalikannya (panggilan balik buffering output diikuti oleh fungsi shutdown). Juga, karena sekitar 5.0.5 (yang jauh lebih awal dari versi 5.2.3 si penanya), objek dibongkar dengan baik sebelum fungsi shutdown terdaftar dipanggil, jadi Anda tidak akan dapat mengandalkan objek di dalam memori untuk melakukan banyak hal.
Jadi mendaftarkan fungsi shutdown tidak apa-apa, tetapi jenis tugas yang seharusnya dilakukan oleh fungsi shutdown mungkin terbatas pada beberapa prosedur shutdown yang lembut.
Kuncinya dibawa pulang di sini adalah hanya beberapa kata-kata bijak bagi siapa saja yang tersandung pada pertanyaan ini dan melihat saran dalam jawaban yang awalnya diterima. Jangan regex buffer output Anda.
sumber
Yah, sepertinya mungkin untuk menangkap kesalahan fatal dengan cara lain :)
sumber
Kesalahan fatal atau kesalahan fatal yang dapat dipulihkan sekarang melempar instance
Error
dalam PHP 7 atau versi yang lebih tinggi . Seperti pengecualian lainnya,Error
objek dapat ditangkap menggunakantry/catch
blok.Contoh:
https://3v4l.org/67vbk
Atau Anda dapat menggunakan
Throwable
antarmuka untuk menangkap semua pengecualian.Contoh:
https://3v4l.org/Br0MG
Untuk informasi lebih lanjut: http://php.net/manual/en/language.errors.php7.php
sumber
Fatal error: Trait 'FailedTrait' not found in
saat menggunakanReflectionClass
?include "filename.php"
sebagai gantinya ditry
blok, laluThrowable
tangkap blok yang paling tidak berfungsiParseError
.Saya mengembangkan cara untuk menangkap semua jenis kesalahan di PHP (hampir semua)! Saya tidak yakin tentang E_CORE_ERROR (saya pikir tidak akan berfungsi hanya untuk kesalahan itu)! Tetapi, untuk kesalahan fatal lainnya (E_ERROR, E_PARSE, E_COMPILE ...) berfungsi dengan baik hanya menggunakan satu fungsi penangan kesalahan! Ada solusi saya:
Letakkan kode berikut ini di file utama Anda (index.php):
sumber
Anda tidak dapat menangkap / menangani kesalahan fatal, tetapi Anda dapat mencatat / melaporkannya. Untuk debugging cepat, saya memodifikasi satu jawaban untuk kode sederhana ini
sumber
Anda tidak bisa melempar pengecualian di dalam fungsi shutdown terdaftar seperti itu:
Tetapi Anda dapat menangkap dan mengarahkan permintaan ke halaman lain.
sumber
Jika Anda menggunakan PHP> = 5.1.0 Lakukan saja hal seperti ini dengan kelas ErrorException:
sumber
Solusi bagus ditemukan di Zend Framework 2:
Kelas ini memungkinkan Anda untuk memulai spesifik
ErrorHandler
sesekali jika Anda membutuhkannya. Dan kemudian Anda juga bisa menghentikan Handler.Gunakan kelas ini misalnya seperti ini:
Tautan ke kode kelas lengkap:
https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/ErrorHandler.php
Solusi yang mungkin lebih baik adalah yang dari Monolog :
Tautan ke kode kelas lengkap:https://github.com/Seldaek/monolog/blob/master/src/Monolog/ErrorHandler.php
Itu juga dapat menangani FATAL_ERRORS menggunakan
register_shutdown_function
fungsi. Menurut kelas ini FATAL_ERROR adalah salah satu dari yang berikutarray(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR)
.sumber
Saya perlu menangani kesalahan fatal untuk produksi sebagai gantinya menunjukkan 503 Layanan statis tidak tersedia keluaran HTML. Ini tentunya merupakan pendekatan yang masuk akal untuk "menangkap kesalahan fatal". Inilah yang telah saya lakukan:
Saya memiliki fungsi penanganan kesalahan khusus "error_handler" yang akan menampilkan halaman HTML "503 tidak tersedia" pada setiap E_ERROR, E_USER_ERROR, dll. Sekarang ini akan dipanggil pada fungsi shutdown, menangkap kesalahan fatal saya,
dalam fungsi error_handler kustom saya, jika kesalahannya adalah E_ERROR, E_USER_ERROR, dll. Saya juga memanggil
@ob_end_clean();
untuk mengosongkan buffer, sehingga menghapus pesan "kesalahan fatal" PHP.Perhatikan
@
fungsi-fungsi ketat pemeriksaan dan pembungkaman isset () karena kami tidak ingin skrip error_handler kami menghasilkan kesalahan.Masih setuju dengan keparo, menangkap kesalahan fatal tidak mengalahkan tujuan "kesalahan FATAL" sehingga tidak benar-benar ditujukan bagi Anda untuk melakukan pemrosesan lebih lanjut. Jangan menjalankan fungsi mail () apa pun dalam proses pematian ini karena Anda pasti akan mencadangkan server email atau kotak masuk Anda. Alih-alih mencatat kejadian ini untuk mengajukan dan menjadwalkan pekerjaan cron untuk menemukan file error.log ini dan mengirimkannya ke administrator.
sumber
PHP memiliki kesalahan fatal yang bisa ditangkap. Mereka didefinisikan sebagai E_RECOVERABLE_ERROR. Manual PHP menggambarkan E_RECOVERABLE_ERROR sebagai:
Anda dapat "menangkap" kesalahan "fatal" ini dengan menggunakan set_error_handler () dan memeriksa E_RECOVERABLE_ERROR. Saya merasa berguna untuk membuang Exception ketika kesalahan ini tertangkap, maka Anda dapat menggunakan try / catch.
Pertanyaan dan jawaban ini memberikan contoh yang bermanfaat: Bagaimana saya bisa menangkap "kesalahan fatal yang bisa ditangkap" pada petunjuk jenis PHP?
Namun, kesalahan E_ERROR dapat diatasi, tetapi tidak dapat dipulihkan kembali karena mesin dalam keadaan tidak stabil.
sumber
Ini hanyalah trik yang bagus untuk mendapatkan metode error_handler saat ini =)
Saya juga ingin mencatat bahwa jika Anda menelepon
PHP berhenti menampilkan kesalahan. Jika tidak, teks kesalahan akan dikirim ke klien sebelum penangan kesalahan Anda.
sumber
Karena sebagian besar jawaban di sini adalah verbose yang tidak perlu, inilah versi non-jelek dari jawaban pilihan utama saya:
sumber
Tidak juga. Kesalahan fatal disebut demikian, karena kesalahan fatal. Anda tidak dapat pulih dari mereka.
sumber
Saya mengembangkan fungsi ini untuk memungkinkan kode "kotak pasir" yang dapat menyebabkan kesalahan fatal. Karena pengecualian yang dilemparkan dari penutupan
register_shutdown_function
tidak dipancarkan dari tumpukan panggilan kesalahan pra-fatal, saya terpaksa keluar setelah fungsi ini untuk menyediakan cara yang seragam untuk menggunakannya.sumber
Ada beberapa kondisi tertentu di mana kesalahan fatal harus ditangkap (Anda mungkin perlu melakukan pembersihan sebelum keluar dengan anggun dan tidak hanya mati ..).
Saya telah menerapkan kait pre_system di aplikasi CodeIgniter saya sehingga saya bisa mendapatkan kesalahan fatal melalui email, dan ini membantu saya menemukan bug yang tidak dilaporkan (atau dilaporkan setelah diperbaiki, seperti yang sudah saya ketahui tentang mereka :)).
Sendemail memeriksa apakah kesalahan telah dilaporkan sehingga tidak mengirimkan spam kepada Anda dengan kesalahan yang diketahui beberapa kali.
sumber