Penanganan Kesalahan PHP: die () Vs trigger_error () Vs throw Exception

119

Berkenaan dengan penanganan Error di PHP - Sejauh yang saya tahu ada 3 gaya:

  1. die()atau exit()gaya:

    $con = mysql_connect("localhost","root","password");
    
    if (!$con) {
     die('Could not connect: ' . mysql_error());
    }
  2. throw Exception gaya:

     if (!function_exists('curl_init')) {
    
          throw new Exception('need the CURL PHP extension. 
                               Recomplie PHP with curl');
        }
  3. trigger_error() gaya:

    if(!is_array($config) && isset($config)) {
            trigger_error('Error: config is not an array or is not set', E_USER_ERROR);
        }

Sekarang, dalam manual PHP ketiga metode tersebut digunakan.

  • Yang ingin saya ketahui adalah gaya mana yang harus saya pilih & mengapa?

  • Apakah 3 penurunan ini menggantikan satu sama lain & oleh karena itu dapat digunakan secara bergantian?

Sedikit OT: Apakah hanya saya atau semua orang berpikir opsi penanganan kesalahan PHP terlalu banyak sehingga membingungkan pengembang php?

CuriousMind
sumber
4
Ini bukan "gaya". Mereka adalah fitur bahasa yang berbeda. Untuk tujuan yang berbeda.
mario
11
@ Mario: apa maksud indentasi yang berbeda ? Tolong beri saya pencerahan :)
CuriousMind
Anda mengajukan pertanyaan dengan cara yang bagus. terima kasih telah bertanya
Akuntan م

Jawaban:

86

Yang pertama tidak boleh digunakan dalam kode produksi, karena itu mengangkut informasi yang tidak relevan ke pengguna akhir (pengguna tidak dapat melakukan apa pun tentang "Tidak dapat terhubung ke database" ).

Anda melontarkan Pengecualian jika Anda tahu bahwa pada titik kode kritis tertentu, aplikasi Anda bisa gagal dan Anda ingin kode Anda pulih di beberapa tingkat panggilan.

trigger_error()memungkinkan Anda menyempurnakan pelaporan kesalahan (dengan menggunakan tingkat pesan kesalahan yang berbeda) dan Anda dapat menyembunyikan kesalahan tersebut dari pengguna akhir (menggunakan set_error_handler()) tetapi tetap menampilkannya kepada Anda selama pengujian.

Juga trigger_error()dapat menghasilkan pesan non-fatal penting selama pengembangan yang dapat disembunyikan dalam kode produksi menggunakan penangan kesalahan khusus. Anda juga bisa menghasilkan kesalahan fatal ( E_USER_ERROR) tetapi itu tidak dapat dipulihkan. Jika Anda memicu salah satunya, eksekusi program berhenti pada saat itu. Inilah sebabnya, untuk kesalahan fatal, Pengecualian harus digunakan. Dengan cara ini, Anda akan memiliki kontrol lebih besar atas aliran program Anda:

// Example (pseudo-code for db queries):

$db->query('START TRANSACTION');

try {
    while ($row = gather_data()) {
       $db->query('INSERT INTO `table` (`foo`,`bar`) VALUES(?,?)', ...);
    }
    $db->query('COMMIT');
} catch(Exception $e) {
    $db->query('ROLLBACK');
}

Di sini, jika gather_data()hanya serak (menggunakan E_USER_ERRORatau die()) ada kemungkinan, INSERTpernyataan sebelumnya akan berhasil masuk ke database Anda, bahkan jika tidak diinginkan dan Anda tidak memiliki kendali atas apa yang akan terjadi selanjutnya.

Linus Kleen
sumber
2
jadi keluar dari trigger_error()& membuang pengecualian: mana yang harus saya gunakan & kapan?
CuriousMind
@Gaurish Lihat contoh tambahan itu.
Linus Kleen
2
Setelah membaca contoh Anda, saya pikir sekarang saya lebih memahami tujuan di balik pengecualian lemparan. Terima kasih :)
CuriousMind
1
@Pacerier Itu tergantung pada konfigurasi server, sebenarnya. Sebuah sistem mungkin dikonfigurasi untuk melakukan autocommit secara default, karenanya eksplisit ROLLBACK. Contoh pseudo-code ini mencakup kedua kasus: server yang tidak dikonfigurasi ke autocommit ( COMMITpernyataan diperlukan) dan yang melakukannya.
Linus Kleen
1
@LinusKleen, bukankah komitmen otomatis dimatikan setelah kita menjalankan saluran query('START TRANSACTION');?
Pacerier
10

Saya biasanya menggunakan cara pertama untuk debugging sederhana dalam kode pengembangan. Tidak disarankan untuk produksi. Cara terbaik adalah dengan membuat pengecualian, yang dapat Anda tangkap di bagian lain dari program dan melakukan penanganan kesalahan.

Ketiga gaya tersebut bukanlah pengganti drop-in untuk satu sama lain. Yang pertama bukanlah kesalahan sama sekali, tetapi hanya cara untuk menghentikan skrip dan menampilkan beberapa info debugging untuk Anda parse secara manual. Yang kedua bukanlah kesalahan itu sendiri, tetapi akan diubah menjadi kesalahan jika Anda tidak menangkapnya. Yang terakhir adalah memicu kesalahan nyata di mesin PHP yang akan ditangani sesuai dengan konfigurasi lingkungan PHP Anda (dalam beberapa kasus ditunjukkan kepada pengguna, dalam kasus lain hanya masuk ke file atau tidak disimpan sama sekali).

Emil Vikström
sumber
1
Apa yang terjadi jika pengecualian dilempar tetapi tidak tertangkap? itu akan menyebabkan kesalahan fatal, saya kira. Dan dengan trigger_error()hal yang sama terjadi. jadi apa bedanya?
CuriousMind
4
Perbedaannya adalah Anda dapat menangkap pengecualian dan menanganinya dengan cara apa pun yang Anda inginkan.
Emil Vikström