PHP प्रकार संकेत पर मैं "कैटलेबल घातक त्रुटि" कैसे पकड़ सकता हूं?


96

मैं अपने एक वर्ग पर PHP5 के टाइप हिंटिंग को लागू करने की कोशिश कर रहा हूं,

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

class ClassB {}
class ClassWrong{}

सही उपयोग:

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

उत्पादन त्रुटि:

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

बिल्ली के समान घातक त्रुटि: तर्क 1 कक्षा में पास किया गया :: method_a () ClassBrong का उदाहरण होना चाहिए, ClassWrong का उदाहरण दिया गया ...

क्या यह उस त्रुटि को पकड़ना संभव है (क्योंकि यह "catchable" कहता है)? और यदि हाँ, तो कैसे?


4
भविष्य के संदर्भ के लिए: इंजन में अपवाद (PHP 7 के लिए) - PHP 7 से शुरू करना संभव है कि घातक त्रुटियां हों। यह भी यहाँ चर्चा की गई है "कैटलेबल घातक त्रुटि" ( E_RECOVERABLE_ERROR) के रूप में इन PHP 7 के साथ शुरू किया जा ..
हैकर

जवाबों:


113

अद्यतन: यह php 7. में अब एक भीषण घातक त्रुटि नहीं है। इसके बजाय "अपवाद" को फेंक दिया गया है। एक "अपवाद" (डराने वाले उद्धरण में) जो अपवाद से नहीं बल्कि त्रुटि से निकला है ; यह अभी भी एक थ्रोबेबल है और इसे सामान्य ट्राइ -कैच ब्लॉक से नियंत्रित किया जा सकता है। देख https://wiki.php.net/rfc/throwable-interface

उदाहरण के लिए

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

प्रिंट

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.

पूर्व php7 संस्करणों के लिए पुराना उत्तर:
http://docs.php.net/errorfunc.constants कहते हैं:

E_RECOVERABLE_ERROR (पूर्णांक)
परिवर्तनशील घातक त्रुटि। यह इंगित करता है कि संभवतः खतरनाक त्रुटि हुई, लेकिन इंजन को अस्थिर स्थिति में नहीं छोड़ा। यदि उपयोगकर्ता द्वारा परिभाषित हैंडल में त्रुटि नहीं पकड़ी जाती है (यह भी देखें set_error_handler () ), तो यह एक E_ERROR के रूप में लागू होता है।

इसे भी देखें: http://derickrethans.nl/erecoverableerror.html

जैसे

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

प्रिंट

'catched' catchable fatal error
done.

संपादित करें: लेकिन आप इसे "अपवाद" बना सकते हैं, जिसे आप एक कोशिश-पकड़ ब्लॉक के साथ संभाल सकते हैं

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

देखें: http://docs.php.net/ErrorException


1
तो निश्चित रूप से यह एक बहुत ही घातक व्यवहार की तरह व्यवहार करता है, सिवाय जब आप अपने सर्वर लॉग में देखते हैं तो आपको यह नहीं मिलेगा। धन्यवाद php: /
जॉन हंट

3
तो दूसरे शब्दों में आप एक त्रुटि-रहित त्रुटि नहीं पकड़ सकते। आश्चर्यजनक!
पॉल डी'अवेस्ट

@Paul इस निष्कर्ष पर क्या लाता है?
वोल्कर

3
ओह, मेरा मतलब सिर्फ यह था कि यह पारंपरिक अर्थों में उपलब्ध नहीं था (कोशिश / कैच ब्लॉक का उपयोग करके)। मैं उस दिन केवल PHP के बारे में क्रोधी महसूस कर रहा था, इसलिए जब मुझे पता चला कि यह पूरी तरह से अलग अर्थों में 'catchable ’था, तो मुझे टिप्पणी करने के लिए मजबूर महसूस हुआ। आपके अद्भुत जवाब के खिलाफ कुछ भी नहीं (जो वास्तव में मैंने उखाड़ा है); मेरे सभी ire PHP के लिए ही था!
पॉल डीअवेट

और मैंने सोचा कि मैं कुछ ;-) अनदेखी की है blog.codinghorror.com/php-sucks-but-it-doesnt-matter : डी
VolkerK
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.