Pengelolaan Eksepsi PHP

Eksepsi (Exception) digunakan untuk mengubah alur normal skrip saat terjadi kesalahan yang ditentukan.

Apa eksepsi?

PHP 5 menyediakan metode penangan kesalahan baru yang berorientasi objek.

Penangan eksepsi digunakan untuk mengubah alur normal skrip saat terjadi kesalahan (eksepsi). Situasi ini disebut eksepsi.

Ketika eksepsi diaktifkan, biasanya terjadi:

  • Status kode saat ini disimpan
  • Eksekusi kode diubah ke fungsi penangan eksepsi yang diatur sebelumnya
  • Berdasarkan situasi, penangan dapat memulai kembali eksekusi kode dari status kode yang disimpan, menghentikan eksekusi skrip, atau melanjutkan eksekusi kode dari tempat lain

Kami akan menunjukkan berbagai metode penangan kesalahan:

  • Penggunaan dasar eksepsi
  • Buat penangan eksepsi khusus
  • Banyak exception
  • Semprotkan gangguan kembali
  • Setel penangan eksepsi tingkat tinggi

Penggunaan dasar eksepsi

Ketika eksepsi di lempar, kode setelahnya tidak akan terus berlanjut, PHP akan mencoba mencari blok kode "catch" yang cocok.

Jika eksepsi belum diambil dan tidak digunakan set_exception_handler() untuk menanggapi, maka akan terjadi kesalahan yang serius (kesalahan fatal), dan pesan kesalahan "Uncaught Exception" (eksepsi yang belum diambil) akan ditampilkan.

Biarkan kita coba melempar eksepsi, tanpa menangkapnya:

<?php
//buat fungsi dengan eksepsi
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Value must be 1 or below");
  }
 return true;
 }
//trigger exception
checkNum(2);
?>

Kode di atas akan mendapatkan kesalahan seperti ini:

Error fatal: Eksepsi yang belum diambil 'Exception' 
dengan pesan 'Nilai harus 1 atau di bawah' di C:\webfolder\test.php:6 
Stack trace: #0 C:\webfolder\test.php(12): 
checkNum(28) #1 {main} dihujani di C:\webfolder\test.php baris 6

Try, throw dan catch

Untuk menghindari kesalahan seperti di contoh di atas, kita perlu membuat kode yang sesuai untuk menangani eksepsi.

Program yang benar harus termasuk:

  1. Cuba - Fungsi yang mengalami eksepsi harus berada di dalam blok kode "try". Jika tidak terjadi eksepsi, kode akan terus berlanjut seperti biasa. Tetapi jika eksepsi diaktifkan, akan terjadi eksepsi.
  2. Throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"
  3. Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象

让我们触发一个异常:

<?php
//创建可抛出一个异常的函数
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Value must be 1 or below");
  }
 return true;
 }
//在 "try" 代码块中触发异常
try
 {
 checkNum(2);
 //If the exception is thrown, this text will not be shown
 echo 'If you see this, the number is 1 or below';
 }
//捕获异常
catch(Exception $e)
 {
 echo 'Message: ' .$e->getMessage();
 }
?>

上面代码将获得类似这样一个错误:

Message: Value must be 1 or below

Pengertian contoh:

上面的代码抛出了一个异常,并捕获了它:

  1. 创建 checkNum() 函数。它检测数字是否大于 1。如果是,则抛出一个异常。
  2. 在 "try" 代码块中调用 checkNum() 函数。
  3. checkNum() 函数中的异常被抛出
  4. "catch" 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)
  5. 通过从这个 exception 对象调用 $e->getMessage(),输出来自该异常的错误消息

不过,为了遵循“每个 throw 必须对应一个 catch”的原则,可以设置一个顶层的异常处理器来处理漏掉的错误。

创建一个自定义的 Exception 类

创建自定义的异常处理程序非常简单。我们简单地创建了一个专门的类,当 PHP 中发生异常时,可调用其函数。该类必须是 exception 类的一个扩展。

这个自定义的 exception 类继承了 PHP 的 exception 类的所有属性,您可向其添加自定义的函数。

我们开始创建 exception 类:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //mesej ralat
  $errorMsg = 'Kesalahan di baris '.$this->getLine().' di '.$this->getFile()
  ': <b>'.$this->getMessage().'</b> bukan alamat e-mail yang sah';
  return $errorMsg;
  }
 }
$email = "someone@example...com";
try
 {
 //cek jika 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //lemparkan eksepsi jika e-mail tidak sah
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //pamerkan mesej khas
 echo $e->errorMessage();
 }
?>

Kelas baru ini adalah salinan kelas exception yang lama, ditambahkan dengan fungsi errorMessage(). Karena ia adalah salinan kelas yang lama, ia mewarisi atribut dan metode dari kelas yang lama, kita dapat menggunakan metode kelas exception, seperti getLine(), getFile() dan getMessage().

Pengertian contoh:

Kode di atas menyemprotkan gangguan dan menangkapnya melalui kelas exception yang disesuaikan:

  1. Kelas customException() dicipta sebagai ekspansi kelas exception lama. Dengan itu, ia mewarisi semua properti dan metod kelas lama.
  2. Buat fungsi errorMessage(). Jika alamat e-mail tidak sah, fungsi ini mengembalikan pesan kesalahan
  3. Tetapkan variabel $email menjadi string alamat e-mail yang tidak sah
  4. Melaksanakan blok kode "try", karena alamat e-mail tidak sah, gangguan disemprotkan
  5. Blok kode "catch" menangkap gangguan dan menampilkan pesan kesalahan

Banyak exception

Bisa digunakan beberapa exception untuk skrip untuk mengecek berbagai situasi.

Bisa digunakan beberapa blok kode if..else, atau blok kode switch, atau nested beberapa gangguan. Gangguan-gangguan ini dapat menggunakan kelas exception yang berbeda dan mengembalikan pesan kesalahan yang berbeda:

<?php
class customException extends Exception
{
public function errorMessage()
{
//mesej ralat
$errorMsg = 'Kesalahan di baris '.$this->getLine().' di '.$this->getFile()
': <b>'.$this->getMessage().'</b> bukan alamat e-mail yang sah';
return $errorMsg;
}
}
$email = "someone@example.com";
try
 {
 //cek jika 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //lemparkan eksepsi jika e-mail tidak sah
  throw new customException($email);
  }
 //cek untuk "example" di alamat e-mail
 if(strpos($email, "example") !== FALSE)
  {
  throw new Exception("$email adalah e-mail contoh");
  }
 }
catch (customException $e)
 {
 echo $e->errorMessage();
 }
catch(Exception $e)
 {
 echo $e->getMessage();
 }
?>

Pengertian contoh:

Kode di atas menguji dua kondisi, jika tidak ada kondisi yang berlaku, gangguan disemprotkan:

  1. Kelas customException() dicipta sebagai ekspansi kelas exception lama. Dengan itu, ia mewarisi semua properti dan metod kelas lama.
  2. Cipta fungsi errorMessage(). Jika alamat e-mail tidak sah, fungsi ini akan mengembalikan mesej ralat.
  3. Melaksanakan blok kode "try", di bawah kondisi pertama, gangguan tidak disemprotkan.
  4. Karena e-mail mengandung string "example", kondisi kedua akan menyemprotkan gangguan.
  5. Blok kode "catch" akan menangkap gangguan dan menampilkan pesan kesalahan yang sesuai

Jika customException tidak didapat, hanya base exception yang didapat, gangguan disediakan di sana.

Semprotkan gangguan kembali

Kadang, apabila gangguan disemprotkan, anda mungkin ingin mengatasi nya dengan cara yang berbeda daripada standar. Gangguan dapat disemprotkan sekali lagi di dalam blok kode "catch".

Skrip sepatutnya menyembunyikan ralat sistem kepada pengguna. Ralat sistem mungkin penting bagi para pemprogram, tetapi pengguna tidak minat dengan mereka. Supaya pengguna lebih mudah menggunakan, anda boleh melemparkan semula eksepsi dengan mesej yang ramah kepada pengguna:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //mesej ralat
  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
  return $errorMsg;
  }
 }
$email = "someone@example.com";
try
 {
 try
  {
  //cek untuk "example" di alamat e-mail
  if(strpos($email, "example") !== FALSE)
   {
   //lemparkan eksepsi jika e-mail tidak sah
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //lemparkan semula eksepsi
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //pamerkan mesej khas
 echo $e->errorMessage();
 }
?>

Pengertian contoh:

Kod di atas mengesan sama ada string "example" terdapat di alamat e-mail. Jika ada, eksepsi akan dilemparkan semula:

  1. Kelas customException() dicipta sebagai ekspansi kelas exception lama. Dengan itu, ia mewarisi semua properti dan metod kelas lama.
  2. Cipta fungsi errorMessage(). Jika alamat e-mail tidak sah, fungsi ini akan mengembalikan mesej ralat.
  3. Tetapkan pemboleh ubah $email kepada alamat e-mail yang sah, tetapi mengandungi string "example".
  4. Blok kod "try" mengandungi blok kod "try" lain, supaya eksepsi dapat dilemparkan semula.
  5. Kerana e-mail mengandungi string "example", eksepsi diaktifkan.
  6. "catch" menangkap eksepsi ini dan melemparkan semula "customException".
  7. Mengesan "customException" dan tunjukkan mesej ralat.

Jika pengecualian di blok kod 'try' semasa ini belum ditangkap, ia akan mencari blok kod 'catch' di tingkat yang lebih tinggi.

Pengaturan Penanganan Pengecualian Tingkat Tinggi

Fungsi set_exception_handler() boleh menetapkan fungsi pengguna yang ditakrifkan untuk menguruskan semua pengecualian yang belum ditangkap.

<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Pengecualian yang belum ditangkap terjadi');
?>

Output kod di atas sepatutnya seperti ini:

Exception: Pengecualian yang belum ditangkap terjadi

Dalam kod di atas, tiada blok kod 'catch', malah program penanganan pengecualian tingkat tinggi diaktifkan. Seharusnya digunakan fungsi ini untuk menangkap semua pengecualian yang belum ditangkap.

Peraturan pengecualian

  • Kod yang perlu untuk pengendalian pengecualian patut diletakkan di dalam blok kod try, supaya pengecualian yang potensial dapat ditangkap.
  • Setiap blok kod try atau throw mesti mempunyai sekurang-kurangnya satu blok kod catch yang sesuai.
  • Penggunaan beberapa blok kod catch boleh mengambil tangkap jenis pengecualian yang berbeza.
  • Pengecualian boleh dihujungkan sekali lagi (re-thrown) di dalam blok kod catch dalam blok kod try.

Dalam kata sederhana: Jika terjadi pengecualian, mesti diambil tangkapnya.