Exceptions are a special condition that usually occurs in the event of an error, upon occurrence of which we can understand that something in the process differs from the intended course of events.
For example:
public function delete($id) { //imagine a static method that checks whether we have such a category $category = Category::find($id); // If the category is not found - we throw an exception creating an instance of the built-in class Exception if (!$category) throw new Exception('Error text!'); } //in controller public function deleteAction($id) { try { //a special block in which we can get exeptions // If the delete() method from the model returns true $model->delete($id); } catch (Exception $e) {//another special block cath exeptions and you can perform some actions on them // If the delete() method from the model returns false echo $e->getMessage();//виведе "Error text!" on display // Or, for example, output to a notification through the session // Session::set('error', $e->getMessage()); } }
Comfortable. Instead of just returning false when the if (count(!$category) condition is met. It’s better to throw an exception and somehow notify the user of any exceptions that have occurred.
The Exception class constructor can take two optional parameters – a string containing the error message and its code. The Exception class also contains methods that help determine the cause of an error:
getMessage() – returns the string that was passed to the constructor and contains the error message
getCode() – returns the error code (type int) that was passed to the constructor
getFile() – returns the name of the file in which the exception was thrown
getLine() – returns the line number on which the exception was thrown
getTrace() – returns a multidimensional array containing a sequence of methods whose invocation resulted in the exception being thrown. It also contains the parameters that were passed to these methods and the line numbers where the calls were made
getTraceAsString() – returns a string version of the data returned by the getTrace() method
__toString() – magic method that is called when an instance of the Exception class is cast to a string
Throw try catch
To throw an exception, use the throw keyword and an instance of the Exception class.
It generates (throws) an exception in some method (in which a non-standard, exceptional situation may occur) and stops further execution of the code, thereby providing the opportunity to handle this exception in a method (anywhere in the application) that will call this method with the thrown exception.
Exception Handling
Exception handling is done using try,catch statements.
The block of code that can catch the exception is located after the try
The block of code that handles the exception is located after the catch statement
On example:
try { $user = new User(); $user->setName('John'); //InvalidArgumentException exception will happen $user->setName(''); // LengthException exception will happen $user->setName('Jo'); echo $user->getName(); } catch (Exception $e) { echo "Message: {$e->getMessage()}<br> Code: {$e->getCode()}<br> File: {$e->getFile()}<br> Line: {$e->getLine()}"; }
Another
try { // ... $config = "config.php"; if (!file_exists($config)) { throw new Exception("Configuration file not found."); } // ... } catch (Exception $e) { //output the text of our error echo $e->getMessage(); die(); }
Create your own exception
//Сreate our own exception class by inheriting the built-in Exception class class MyException extends Exception { //Redefine the exception so that the message parameter is required public function __construct($message, $code = 0, Exception $previous = null) { //our code parent::__construct($message, $code, $previous); } //Redefining the string representation of the object. public function __toString() { return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; } //We can define new methods in the inherited class public function customFunction() { echo ""; } }
Classes inherited from Exception
The Exception class implements other classes that are specifically designed to throw certain types of exceptions.
Let’s look at an example:
class Example { protected $author; protected $month; protected $goals = []; public function exceptions(int $a, int $b): int { $valid_a = [7, 8, 9]; if (!is_int($a)) { ////InvalidArgumentException - Thrown when the expected arguments in the function/method are malformed. throw new InvalidArgumentException("must be an integer!"); } if ($a > 5 || !in_array($a, $valid_a, true)) { //DomainException - If the code implies some restrictions on values, then this exception can be thrown when the value goes beyond these restrictions. throw new DomainException("a cannot be greater than 5"); } $c = $this->getByIndex($a); if (!is_int($c)) { //RangeException - thrown when the value is out of range. Similar to DomainException, but used when returning from a function, not when entering. throw new RangeException("c counted wrong"); } else { return $c; } } private function getByIndex($a) { return ($a < 100) ? $a + 1 : null; } public function deleteNextGoal() { if (empty($this->goals)) { //UnderflowException - the container class does not have enough elements to complete the operation. For example, when it is empty and you are trying to remove an element. throw new UnderflowException("No target to delete!"); } elseif (count($this->goals) > 100000) { //OverflowException An exception is thrown when there is an overflow. For example, there is a certain container class that can only take 5 elements, and we are trying to write the sixth one there. throw new OverflowException("The system cannot operate more than 100,000 targets at the same time!"); } else { array_pop($this->goals); } } public function getGoalByIndex($i) { if (!isset ($this->goals[$i])) { //OutOfBoundsException - Called when an attempt to use the wrong key is detected, for example, in an associative array or when implementing ArrayAccess. Used when the error cannot be detected before the code is run. That is, for example, which keys will be legitimate, is determined dynamically already at runtime. throw new OutOfBoundsException("No target at index $i"); // легитимные значения известны только во время выполнения } else { return $this->goals[$i]; } } public function setPublicationMonth(int $month) { if ($month < 1 || $month > 12) { //OutOfRangeException - Used when an invalid index is encountered, but this time the error should be caught before the code runs, for example if we are trying to address an array element that is basically not supported. That is, if a function that returns the day of the week at its index from 1 to 7 suddenly receives 9, then this DomainException is a logic error, and if we have an array with days of the week with indices from 1 to 7, and we are trying to access an element with index 9, then this is an OutOfRangeException. throw new OutOfRangeException("Month must be between 1 and 12!"); } $this->month = $month; } public function setAuthor($author) { if (mb_convert_case($author, MB_CASE_UPPER) !== $author) { throw new InvalidArgumentException("All letters of the author's name must be in uppercase"); } else { if (mb_strlen($author) > 255) { //LengthException - Thrown if the length of something is too large or too small. For example, the file name is too short or the line length is too long. throw new LengthException("The author field must not exceed 255 characters!"); } else { $this->author = $author; } } } public function __call(string $name, array $args) { //BadMethodCallException - Subclass of BadFunctionCallException. Similarly, it is used for methods that do not exist or that have been passed the wrong number of parameters. Always use __call() inside, that's basically what it's used for. throw new BadMethodCallException("Method Example>$name() does not exist"); } }