რა არის გამონაკლისი?

რედაქტირება

PHP 5-ში შემოვიდა ახალი შეცდომებთან გარიგებაზე ორიენტირებული ობიექტი. გამონაკლისის გამომტანი გამოიყენება კოდის ნორმალური მუშაობის შესაცვლელად, თუ გამოვა სპეციფიური შეცდომა. ამ პირობას ქვია გამონაკლისი.
ასე ხდება როდესაც გამონაკლისი გაეშვება:

  • მიმდინარე კოდი დამახსოვრდება
  • კოდის შესრულება შეუერთდება წინასწარ განსაზღვრულ გამონაკლისის გამომტან ფუნქციას.
  • სიტუაციაზე დამოკიდებულად, გამომტანი შესაძლოა ამუშავდეს დამახსოვრებული კოდიდან, შეაჩეროს სკრიპტის მუშაობა, ან გააგრძელოს იგი კოდის სხვა ადგილიდან.

ქვემოთ ნაჩვენებია შეცდომის გამოტანის სხვადასხვა მეთოდები:

  • ბაზური გამოყენების გამონაკლისები
  • ინდივიდუალური გამონაკლისების შექმნა
  • რამდენიმე გამონაკლისი
  • გამონაკლისის ასხლეტვა
  • ზე-დონის გამონაკლისის გამომტანის კონფიგურაციები

შენიშვნა: გამონაკლისების გამოყენება შესაძლოა მხოლოდ შეცდომისთვის და ის არ გამოიყენება კოდის სხვა წერტილში გადასახტომად. ბაზური გამოყენების გამონაკლისები
როდესაც გამონაკლისი გასროლილია, მასზე გაყოლილი კოდი არ იმუშავებს და PHP შეეცდება იპოვოს "დაჭერა" ბლოკის დამთხვევა.
თუ გამონაკლისი არ იქნება დაჭერილი, გამოვა გარდაუვალი შეცდომა "Uncaught Exception" შეტყობინებით.
მაგალითი:

<?php
//create function with an exception
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Value must be 1 or below");
  }
 return true;
 }

//trigger exception
checkNum(2);
?>

ზემოთ მოყვანილი კოდი მიიღებს მსგავს შეცდომას:

Fatal error: Uncaught exception 'Exception' 
with message 'Value must be 1 or below' in C:\webfolder\test.php:6 
Stack trace: #0 C:\webfolder\test.php(12): 
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6

ცდა, გასროლა და დაჭერა

რედაქტირება

ზემოთ მოყვანილ მაგალითში შეცდომისგან თავის ასარიდებლად, ჩვენ გვჭირდება შევქმნათ გამონაკლისის გამოტანის ჩვეული კოდი. გამონაკლისის ჩვეული კოდი შეიცავს:

  1. ცდა - ფუნქცია იყენებს გამონაკლისს, რომელიც იქნება "try" ბლოკში. თუ გამონაკლისი არ გაეშვება, კოდი გააგძელებს ნორმალურად მუშაობას. თუმცა, თუ გამონაკლისი გაეშვება, გამონაკლისი იქნება"გასროლილი".
  2. გასროლა - ეს არის, თუ როგორ ვუშვებთ გამონაკლისს. თითოეულ "გასროლას" უნდა ჰქონდეს სულ მცირე ერთი "დაჭერა".
  3. დაჭერა- "დაჭერა" ბლოკი იპოვის გამონაკლისს და შექმნის ობიექტს, რომელიც შეიცავს გამონაკლისის ინფორმაციას.

მაგალითი:

<?php
//create function with an exception
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("Value must be 1 or below");
  }
 return true;
 }

//trigger exception in a "try" block
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
catch(Exception $e)
 {
 echo 'Message: ' .$e->getMessage();
 }
?>

ზემოთ მოყვანილი კოდი მიიღებს შეცდომას:

Message: Value must be 1 or below

მაგალითის ახსნა:
ზემოთ მოყვანილი კოდი ისვრის და იჭერს გამონაკლისებს:

  1. checkNum() ფუნქცია შექმნილია. ის ამოწმებს, რიცხვი მეტია, თუ არა 1-ზე. თუ ის მეტია, გამონაკლისი გაისროლება.
  2. checkNum() ფუნქცია გამოძახებულია "try" ბლოკში
  3. გამონაკლისი checkNum() ფუნქციაში გასროლილია
  4. "catch" ბლოკი პოულობს გამონაკლისს და ქმნის ობიექტს($e) , რომელიც შეიცავს გამონაკლისის ინფორმაციას
  5. შეცდომის შეტყობინება გამონაკლისიდან დაბეჭდილია $e->getMessage()-ის გამოძახებით გამონაკლისი ობიექტიდან.

თუმცა, არსებობს ერთი გზა "ყველა გასროლა დაჭერილ უნდა იქნას" წესის თავიდან ასარიდებლად. ესაა შეცდომებზე ზე-დონის გამონაკლისების გამომტანის დანიშვნა, რომელიც გვერდს აუვლის მას.

ინდივიდუალური გამონალკისების კლასის შექმნა

რედაქტირება

ინდივიდუალური გამონაკლისების გამოტანის შექმნა საკმაოდ ადვილია. ჩვენ უბრალოდ ვქმნით სპეციუალურ კლასის ფუნქციებს, რომელთა გამოძახება შესაძლებელი იქნება, როდესაც PHP-ში გამოჩნდება გამონაკლისი. კლასი უნდა იყოს გამონაკლისის კლასის გაფართოება. გამონაკლისის ინდივიდუალური კლასი მემკვიდრეობით მიიღებს თვისებებს PHP-ს გამონაკლისების კლასიდან და ჩვენ შეგვეძლება დავამატოთ მას ინდივიდუალური ფუნქციები.
შევქმნათ გამონაკლისის კლასი:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
  .': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
  return $errorMsg;
  }
 }
$email = "someone@example...com";
try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

ახალი კლასი არის ძველი გამონაკლისის კლასის ასლი errorMessage() ფუნქციით. მას შემდეგ რაც ის გახდა ძველი კლასის ასლი და მას მემკვიდრეობით მიენიჭა ძველი კლასის თვისებები და მეთოდები, ჩვენ შეგვიძლია გამოვიყენოთ შემდეგი გამონაკლისების კლასის მეთოდები - getLine() და getFile() და getMessage().
მაგალითის ახსნა:
ზემოთ მოყვანილი კოდი გაისვრის გამონაკლისს და დაიჭერს მას ინდივიდუალური გამონაკლისის კლასით:

  1. customException() კლასი შექმნილია, როგორც ძველი გამონაკისის კლასის გაფართოება. ამ მეთოდით ის მემკვიდრეობით იღებს ძველი კლასის თვისებებს და მეთოდებს
  2. errorMessage() ფუნქცია შექმნილია. ფუნქცია დააბრუნებს შეცდომის შეტყობინებას, თუ ელ-ფოსტის მისამართი არასწორია
  3. "try" ბლოკი ამუშავდა და გამონაკლისი გაისროლა, მას შემდეგ რაც ელ-ფოსტის მისამართი არასწორი აღმოჩნდა
  4. "catch" ბლოკი იჭერს გამონაკლისს და გამოსახავს შეცდომის შეტყობინებას

რამდენიმე გამონაკლისი

რედაქტირება

სკრიპტს შეუძლია გამოიყენოს რამდენიმე გამონაკლისი, რამდენიმე პირობის შესამოწმებლად.
შესაძლებელია გამოვიყენოთ რამდენიმე if..else ბლოკი, გამანაწილებელი, ან რამდენიმე გამონაკლისის ბუდე. ამ გამონაკლისებს შეუძლიათ გამოიყენონ რამდენიმე სხვა გამონაკლისის კლასები და და დააბრუნონ სხვადასხვა შეცდომის შეტყობინებები:

<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> is not a valid E-Mail address';
return $errorMsg;
}
}

$email = "someone@example.com";

try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 //check for "example" in mail address
 if(strpos($email, "example") !== FALSE)
  {
  throw new Exception("$email is an example e-mail");
  }
 }

catch (customException $e)
 {
 echo $e->errorMessage();
 }
catch(Exception $e)
 {
 echo $e->getMessage();
 }
?>

მაგალითის ახსნა:
ზემოთ მოყვანილი კოდი ტესტირებას უკეთებს ორ პირობას და გაისვრის გამონაკლისს, თუ არ შეხვდა რომელიმე პირობა:

  1. customException() კლასი შექნილია როგორც ძველი გამონაკლისის გაფართოება.
  2. errorMessage() ფუნქცია შექმნილია. ფუნქცია დააბრუნებს შეცდომის შეტყობინებას, თუ ელ-ფოსტის მისამართი არასწორია
  3. "try" ბლოკი გაშვებულია და გამონაკლისი გასროლილია პირველ პირობაზე
  4. მეორე პირობა უშვებს გამონაკლისს მას მერე, რაც ელ-ფოსტა შეიცავს სტრინგს "example"
  5. "catch" ბლოკი იჭერს გამონაკლისს და გამოსახავს შეცდომის შეტყობინებას

თუ არ მოხდება ინდივიდუალური გამონაკლისის დაჭერა, დაიჭირება მხოლოდ ბაზური გამონაკლისი, გამონაკლისი გამოვა იქ. გამონაკლისების ასხლეტა
ზოგჯერ, როდესაც გამონაკლისი გაისროლება, ჩვენ შესაძლოა ვისურვოთ მისი გამოტანა სტანდარტული გზისგან განსხვავებულად. ეს შესაძლებელია გამონაკლისის მეორეჯერ გასროლით "catch" ბლოკში.
სკრიპტი დამალავს შეცდომას მომხმარებლებისაგან. სისტემური შეცდომები შესაძლებელია მნიშვნელოვანი იყოს პროგრამისტისათვის, მაგრამ ეს არ აინტერესებდეს მომხმარებელს. იმისათვის რომ გავაკეთოთ მსგავსი რამ მომხმარებლისათვის ჩვენ შეგვიძლია გავაკეთოთ გამონაკლისის ასხლეტა ”მეგობრული” შეტყობინებით:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
  return $errorMsg;
  }
 }
$email = "someone@example.com";
try
 {
 try
  {
  //check for "example" in mail address
  if(strpos($email, "example") !== FALSE)
   {
   //throw exception if email is not valid
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //re-throw exception
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

მაგალითის ახსნა:
ზემოთ მოყვანილი მაგალითი ტესტავს ელ-ფოსტის მისამართს, რომელიც შეიცავს სტრინგს "example", თუ არადა, გამონაკლისი აისხლიტება:

  1. customException()კლასი შექნილია როგორც ძველი გამონაკლისის გაფართოება
  2. errorMessage()ფუნქცია შექმნილია. ფუნქცია დააბრუნებს შეცდომის შეტყობინებას, თუ ელ-ფოსტის მისამართი არასწორია
  3. "try" ბლოკი შეიცავს სხვა "try" ბლოკს, რათა შესაძლებელი იყოს გამონაკლისის ასხლეტა
  4. გამონაკლისი გაშვებულია მას შემდეგ, რაც ელ ფოსტა შეიცავს სტრინგს "example"
  5. "catch" ბლოკი იჭერს გამონაკლისს და ისხლიტავს "customException"
  6. "customException" დაჭერილია და ის გამოსახავს შეცდომის შეტყობინებას

თუ გამონაკლისი არ არის დაჭერილი მიმდინარე "try" ბლოკში, ის მოიძებნება დაჭერის ბლოკში "უფრო მაღალი დონის" საშუალებით.

ზე-დონის გამონაკლისების გამოტანის დასმა

რედაქტირება
<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>

კოდი დაბეჭდავს შემდეგს:

Exception: Uncaught Exception occurred

ზემოთ მოყვანილი კოდი არ იყო "catch" ბლოკი. ეს ფუნქცია გამოიყენება დაუჭერელი გამონაკლისების დასაჭერად.

წესები გამონაკლისებისათვის

რედაქტირება
  • კოდი შესაძლოა მოექცეს ცდის ბლოკში, პოტენციალური გამონაკლისების დასაჭერად
  • თითოეული ცდის ბლოკს, ან "გასროლას" უნდა ქონდეს სულ მცირე ერთი შესაბამისი დაჭერის ბლოკი
  • რამდენიმე დაჭერის ბლოკი შესაძლებელია გამოყენებულ იქნას გამონაკლისების სხვადასხვა კლასებში
  • გამონაკლისები შესაძლოა გასროლილ(ასხლეტილ) იქნან ცდის ბლოკში არსებული დაჭერის ბლოკიდან

მარტივი წესი: თუკი ვისვრით რამეს, ჩვენ უნდა დავიჭიროთ ის.