2010-03-18 8 views
86

Sto cercando di implementare Tipo Hinting di PHP5 su uno della mia classe,Come posso rilevare un "errore irreversibile abbinabile" su hint di tipo PHP?

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

class ClassB {} 
class ClassWrong{} 

Utilizzo corretto:

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

produzione di errore:

$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...

Posso sapere se è possibile rilevare quell'errore (poiché si dice "catchable")? e se si, come?

Grazie.

+2

per futuro riferimento: [Eccezioni nel motore (per PHP 7)] (https://wiki.php.net/rfc/engine_exceptions_for_php7) - A partire da PHP 7 è possibile catture errori fatali. Questo è anche per il qui discusso * "Catchable fatal error" * ('E_RECOVERABLE_ERROR') come questi vengono rilevati a partire da PHP 7 .. – hakre

risposta

98

Aggiornamento: non si tratta più di un errore irreversibile catapulibile in php 7. Invece viene generata un'eccezione. Un'eccezione (in virgolette) non derivata da Exception ma Error; è ancora un Throwable e può essere gestito con un normale blocco try-catch. vedi 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.'; 

stampe

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. 

Vecchio risposta per le versioni pre-php7:
http://docs.php.net/errorfunc.constants dice:

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.

vedi anche: http://derickrethans.nl/erecoverableerror.html

ad es.

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.'; 

stampe

'catched' catchable fatal error 
done. 

edit: Ma si può "fare" è un'eccezione è possibile gestire con un blocco try-catch

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.'; 

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

+10

Grazie! Imparo una cosa nuova! – hoball

+18

php è semplicemente stupido a volte – Peter

+0

Quindi questo comportamento si comporta molto come un errore fatale, tranne quando si guarda nei registri del server che non lo troverete. Grazie php:/ –

Problemi correlati