Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I catch a "catchable fatal error" on PHP type hinting?

I am trying to implement Type Hinting of PHP5 on one of my class,

class ClassA {     public function method_a (ClassB $b)     {} }  class ClassB {} class ClassWrong{} 

Correct usage:

$a = new ClassA; $a->method_a(new ClassB); 

producing error:

$a = new ClassA; $a->method_a(new ClassWrong); 

Catchable fatal error: Argument 1 passed to ClassA::method_a() must be an instance of ClassB, instance of ClassWrong given...

Is it possible to catch that error(since it says "catchable")? and if yes, how?

like image 533
hoball Avatar asked Mar 18 '10 08:03

hoball


People also ask

Can I catch fatal error PHP?

You can "catch" these "fatal" errors by using set_error_handler() and checking for E_RECOVERABLE_ERROR. I find it useful to throw an Exception when this error is caught, then you can use try/catch.

What would occur if a fatal error was thrown in your PHP program?

It's an error that caused the script to abort and exit immediately. All statements after the fatal error are never executed. I strongly recommend you use an editor that will alert you to errors as you code. It will safe you a lot of time.

Which function gives fatal error if file is not included?

You need to use include(). Require(), when used on non-existent file, produces a fatal error and exits the script, so your die() won't happen.


1 Answers

Update: This is not a catchable fatal error anymore in php 7. Instead an "exception" is thrown. An "exception" (in scare quotes) that is not derived from Exception but Error; it's still a Throwable and can be handled with a normal try-catch block. see https://wiki.php.net/rfc/throwable-interface

E.g.

<?php class ClassA {   public function method_a (ClassB $b) { echo 'method_a: ', get_class($b), PHP_EOL; } } class ClassWrong{} class ClassB{} class ClassC extends ClassB {}   foreach( array('ClassA', 'ClassWrong', 'ClassB', 'ClassC') as $cn ) {     try{       $a = new ClassA;       $a->method_a(new $cn);     }     catch(Error $err) {       echo "catched: ", $err->getMessage(), PHP_EOL;     } } echo 'done.'; 

prints

catched: Argument 1 passed to ClassA::method_a() must be an instance of ClassB, instance of ClassA given, called in [...] catched: Argument 1 passed to ClassA::method_a() must be an instance of ClassB, instance of ClassWrong given, called in [...] method_a: ClassB method_a: ClassC done. 

Old answer for pre-php7 versions:
http://docs.php.net/errorfunc.constants says:

E_RECOVERABLE_ERROR ( integer )
Catchable fatal error. It indicates that a probably dangerous error occured, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR.

see also: http://derickrethans.nl/erecoverableerror.html

e.g.

function myErrorHandler($errno, $errstr, $errfile, $errline) {   if ( E_RECOVERABLE_ERROR===$errno ) {     echo "'catched' catchable fatal error\n";     return true;   }   return false; } set_error_handler('myErrorHandler');  class ClassA {   public function method_a (ClassB $b) {} }  class ClassWrong{}  $a = new ClassA; $a->method_a(new ClassWrong); echo 'done.'; 

prints

'catched' catchable fatal error done. 

edit: But you can "make" it an exception you can handle with a try-catch block

function myErrorHandler($errno, $errstr, $errfile, $errline) {   if ( E_RECOVERABLE_ERROR===$errno ) {     echo "'catched' catchable fatal error\n";     throw new ErrorException($errstr, $errno, 0, $errfile, $errline);     // return true;   }   return false; } set_error_handler('myErrorHandler');  class ClassA {   public function method_a (ClassB $b) {} }  class ClassWrong{}  try{   $a = new ClassA;   $a->method_a(new ClassWrong); } catch(Exception $ex) {   echo "catched\n"; } echo 'done.'; 

see: http://docs.php.net/ErrorException

like image 75
VolkerK Avatar answered Oct 07 '22 06:10

VolkerK