PHP को पकड़ने / पकड़ने की कोशिश करें अपवाद को नहीं पकड़ें


98

मैं इस पृष्ठ से इस उदाहरण # 1 को चलाने की कोशिश कर रहा हूं: http://php.net/manual/en/language.exception.pp

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}
try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
?>

हालांकि वांछित उत्पादन के बजाय मुझे मिलता है:

0.2
Fatal error: Uncaught exception 'Exception' with message 'Division by zero.' 
in xxx:
7 Stack trace: #0 xxx(14): inverse(0) #1 {main} thrown in xxx on line 7

मैं जिस डेवलपर वातावरण का उपयोग कर रहा हूं, वह UniServer 3.5हैPHP 5.2.3


1
क्या आप हमें अपना कोड दिखा सकते हैं? इस त्रुटि को प्राप्त करने के लिए केवल एक ही गलती आप गलत अपवाद (या कोई नहीं) को पकड़ रहे हैं।
ताम्मो

2
कोड बिल्कुल समान है (मैंने अभी-अभी कुछ नई कड़ियाँ जोड़ी हैं) ... वैसे भी, मैंने कोड को एक बार और परीक्षण फ़ाइल में कॉपी कर लिया है और यहाँ एक ही त्रुटि गड़बड़ है: 0.2 घातक त्रुटि: संदेश के साथ अपवाद 'अपवाद' शून्य द्वारा शून्य । ' W: \ www \ test.php में: 4 स्टैक ट्रेस: ​​# 0 W: \ www \ test.php (11): व्युत्क्रम (0) # 1 {मुख्य} W: \ www \ test.php में लाइन 4 पर फेंका गया मुझे वास्तव में पता नहीं है कि वहां क्या चल रहा है ... शायद दोषपूर्ण PHP कॉन्फ़िगरेशन?
१५:२५ बजे क्रिसी

1
कुछ पुराने एक्सटेंशन संस्करणों में अपवाद हैंडलिंग की समस्याएँ थीं। 5.2.3 पुराना है और त्रुटि के पीछे एक बग हो सकता है। क्या आप PHP को अपग्रेड कर सकते हैं? UniServer 3.5 भी काफी पुराना है, वर्तमान उत्पादन संस्करण 5.5 है। 3.5 एक टाइपो है?
प्रातः

1
UniServer रिलीज़ जानकारी ( wiki.uniformserver.com/index.php/… ) को देखते हुए, 3.5 स्पष्ट रूप से एक टाइपो नहीं है। UniServer 5.5 में अपग्रेड करें और फिर से सैंपल कोड आज़माएं।
outis

1
आउटिस, टिप के लिए धन्यवाद :)। यह वही है जो मैंने तब वापस किया - XAMPP पर स्विच किया गया (न ही UniServer के नए संस्करण की तरह)। 3.5 एक टाइपो नहीं है, लेकिन सर्वर ने मेरे लिए पूरी तरह से काम किया है इसलिए मैंने इसे अपग्रेड करने में कभी परेशान नहीं किया।
१५:०४ पर क्रिसी

जवाबों:


219

मेरे पास बस यह सटीक समस्या थी जहां ऐसा लग रहा था कि मैंने भी अपवाद के नाम की नकल की थी और फिर भी इसे नहीं पकड़ा। यह पता चला कि यह मेरी मूर्खतापूर्ण गलती थी, लेकिन मुझे लगा कि मुझे अपना मामला यहाँ पोस्ट करना चाहिए, अगर किसी की स्थिति में कोई और है।

मेरे नाम में मेरा अपवाद था और स्क्रिप्ट बी नाम के एक नामस्थान में थी । समस्या यह थी कि मेरे पास A \ MyException थी (PHP में) \ B \ A \ MyException के बराबर (क्योंकि मेरी स्क्रिप्ट B नामक नामस्थान में है !)। मुझे इसे ठीक करने के लिए केवल बैकस्लैश जोड़ना था (या इसे जो भी कहा जाता है) अपवाद नाम के साथ जोड़ना था ताकि यह इस तरह दिखाई दे: \ A \ MyException


7
इसे पोस्ट करने के लिए बहुत-बहुत धन्यवाद क्योंकि मैं अपनी गलती का एहसास किए बिना कई दिनों तक चला गया।
टिपू

79
इसने मेरी समस्या को हल कर दिया, नाम कोड में एक साधारण आलसी कैच ब्लॉक होना चाहिए catch (\Exception $e)। बिना बैकस्लैश Exceptionनाम स्थान के लिए विशिष्ट है और मिलान नहीं किया जाएगा (या पकड़ा गया)।
जोमलर

3
इसे पोस्ट करने के लिए धन्यवाद!
Keepkimi

2
इसे पोस्ट करने के लिए धन्यवाद, मैंने पिछले कुछ घंटों से अधिक समय बिताया है क्योंकि मेरा कैच ब्लॉक काम नहीं कर रहा था। प्रमुख चेहरा।
मिच

4
चीयर्स! मेरा दिन बचाया (और न्यूरॉन्स ...) :)
सब्जी

68

काफी पुराना सवाल, फिर भी ...

मुझे भी यह समस्या थी (और यह है कि मुझे यह पोस्ट कैसी लगी) लेकिन सरल प्रयोग ने मुझे इसका हल खोजने की अनुमति दी। बस बदलने का प्रयास Exceptionकरने के लिए \Exception। मेरे लिए काम किया!

संपादित करें:

जैसा कि सिवन ने टिप्पणियों में बताया है, नामस्थान का उपयोग करना चाहिए। तो बस use \Exception as Exception;अपने वर्ग की घोषणा से पहले डाल दिया ।


प्रतिभाशाली! :) शायद मुझे यह पता लगाने में घंटों लगेंगे, बस नाम बदलने के बारे में नहीं सोचा था। धन्यवाद!
अलेक्जेंडर गिलमनोव

हाँ! यह भी: "अपवाद के रूप में उपयोग करें;" सबसे ऊपर वही काम करता है।
सिवान

@ sii-aik नेमस्पेस का उपयोग करने की कोशिश करें जैसा कि सिवान ने लिखा है।
एनथियोन

बस use Exception;इसे करना चाहिए
डिएगो पोंचियानो

धन्यवाद! @ इनेथियन
नोमवे

32

के catch(\Exception $e)बजाय डालने की कोशिश करें catch(Exception $e)। यदि आप एक ऐसे कोड का उपयोग कर रहे हैं जिसे आप बहुत अच्छी तरह से नहीं जानते हैं, या - विशेष रूप से - यदि आप एक फ्रेमवर्क का उपयोग कर रहे हैं, तो यह अपने आप में से किसी एक के साथ डिफ़ॉल्ट PHP अपवाद को ओवरराइड कर सकता है, और इसलिए आप गलत रास्ते पर जा सकते हैं और प्राप्त कर सकते हैं अवांछित परिणाम। यदि आप अभी लगाते हैं \Exception, तो आप सुनिश्चित हैं कि आप आधार PHP अपवाद को पकड़ रहे हैं।


@ श्रीसी, क्या आपने मेरा सुझाव आज़माया?
व्लादिमीर डेस्पोटोविक

2
यह मेरे लिए किया था
cljk

20

आप PHP में ठेठ कोशिश {} कैच {} ब्लॉक का उपयोग नहीं कर सकते हैं जैसा कि आप C # (Csharp) जैसी किसी अन्य भाषा में कर सकते हैं।

अगर तुम यह करते हो:

try{
    //division by zero
    $number = 5/0;
}
catch(Exception $ex){
    echo 'Got it!';
}

आप 'यह समझे!' संदेश कभी नहीं। क्यों? यह सिर्फ इसलिए है क्योंकि PHP को हमेशा "Thrown" होने के लिए एक अपवाद की आवश्यकता होती है। आपको अपना स्वयं का त्रुटि हैंडलर सेट करना होगा और इसके साथ एक अपवाद फेंकना होगा।

Set_error_handler फ़ंक्शन देखें : http://php.net/manual/es/function.set-error-handler.pp


6
यह वही नहीं है;) आपको अपने द्वारा एक अपवाद फेंकने की आवश्यकता थी, और यही मैंने कहा था (<< यह सिर्फ इसलिए है क्योंकि PHP को हमेशा "Thrown" होने के लिए अपवाद की आवश्यकता होती है >>) @JaredFarrish
Rowinson Gallego

हाँ, लेकिन यह कैसे समान नहीं है?
जारेड फरिश

यही कारण है कि लिंक मर चुका है, लेकिन मैं इस उपयोगी पाया: w3schools.com/php/func_error_set_error_handler.asp
घृणा

PHP संस्करण 7.3.9 में, $number = 5/0;एक अपवाद नहीं बढ़ाता है। $numberहोना तय है INF
वर्चुअल

6

मेरा प्रारंभिक हालांकि आपके पास अपवाद के नाम पर एक टाइपो है जिसे आप पकड़ रहे हैं / फेंक रहे हैं, लेकिन यदि आपका कोड ठीक वैसा ही है तो मुझे यकीन नहीं है कि वास्तव में क्या चल रहा है।

मूल स्क्रिप्ट के निम्नलिखित संशोधन का प्रयास करें, और अपने परिणाम चिपकाएँ। यह आपके मुद्दे का थोड़ा बेहतर निदान करने में मदद करेगा।

<?php

//set up exception handler to report what we didn't catch
function exception_handler($exception) {

    if($exception instanceof MyException) {
        echo "you didn't catch a myexception instance\n";

    } else if($exception instanceof Exception) {
        echo "you didn't catch a exception instance\n";

    } else {
        echo "uncaught exception of type: ".gettype($exception)."\n";
    }

    echo "Uncaught exception: " , $exception->getMessage(), "\n";
}

//install the handler
set_exception_handler('exception_handler');

class MyException extends Exception {
}

function inverse($x) {
    if (!$x) {
        throw new MyException('Division by zero.');
    }
    else return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (MyException $e) {
    echo 'Caught myexception: ',  $e->getMessage(), "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
?>

4

निम्नलिखित विन्यास के साथ मुझे भी यही समस्या थी,

PHP 5.2.14 (cli) (निर्मित: अगस्त 12 2010 17:32:30) कॉपीराइट (c) 1997-2010 PHP समूह Zend इंजन v2.2.0, कॉपीराइट (c) 1998-2010 ZA टेक्नोलॉजीज के साथ eAccelerator v0.9.5। 1 , कॉपीराइट (c) 2004-2006 eAccelerator, eAccelerator द्वारा

समाधान या तो eAccelerator को अक्षम करना है या इसे अपडेट करना है। मैंने दोनों की कोशिश की और दोनों ने काम किया। बग की रिपोर्ट यहाँ दी गई है https://eaccelerator.net/ticket/242 (NB। फ़ायरफ़ॉक्स उनके एसएसएल प्रमाणपत्र के बारे में शिकायत करता है)।

अब मैं निम्नलिखित कॉन्फ़िगरेशन के साथ ठीक से पकड़ने की कोशिश कर रहा हूं,

PHP 5.2.4 (cli) (निर्मित: 16 अक्टूबर 2007 09:13:35) कॉपीराइट (c) 1997-2007 PHP Group Zend Engine v2.2.0, कॉपीराइट (c) 1998-2007 Zend Technologies के साथ eAccelerator v0.9.6। 1 , कॉपीराइट (c) 2004-2010 eAccelerator, eAccelerator द्वारा


4

\ अपवाद मेरे लिए काम नहीं करता है, लेकिन मुझे एक समाधान मिला।

मुझे {} कैच (अपवाद $ e) {} ट्राय {} कैच (थ्रोबेबल $ ई) {} द्वारा कोशिश करने की आवश्यकता है।

अधिक जानकारी के लिए: https://trowski.com/2015/06/24/throwable-exception-and-errors-in-ppp/


3

Xdebug में एक सेटिंग है:

xdebug.show_exception_trace = 1

यह php को आउटपुट अपवादों में भी आजमाएगा। इसे चालू करें0


2
मेरे मामले में मुझे xdebug मॉड्यूल को पूरी तरह से अक्षम करना पड़ा (बदलते हुए xdebug.show_exception_trace पर्याप्त नहीं था)।
थॉमस सहलिन

इस अनुस्मारक के लिए धन्यवाद। मैं थोड़ी देर के लिए उलझन में था।
ब्रायन लित्सिंगर

3

यदि आप PHP 7 का उपयोग कर रहे हैं, तो आपको अपवाद के बजाय Throwable की आवश्यकता हो सकती है


यह एक पुरानी पोस्ट है। उत्तर देने का निर्णय लेने से पहले विषय की तारीख पर एक नज़र डालें। इसके अलावा कि आपका उत्तर वास्तव में मददगार नहीं है क्योंकि यह है: - पूर्ण नहीं - कोई स्पष्टीकरण नहीं क्यों
मोनोफॉन

1
स्पष्टीकरण यह है कि PHP7 अपवाद के बजाय Throwable का उपयोग करता है। जब मैंने इस समस्या का सामना किया और मैंने अपना योगदान देना चाहा तो यह चर्चा पहली थी। इस तरह की टिप्पणियाँ स्टैक समुदाय के अनुकूल नहीं होने के कारण हैं।
user5528384

1
आपका अपमान करना मेरा उद्देश्य नहीं था। यह पोस्ट "पहली पोस्ट" समीक्षा कतार में दिखाई दी और मेरी राय में यह एक पुराने प्रश्न पर उत्तर पोस्ट करने के लिए उपयोगी नहीं था। और प्रश्न लिखने के समय PHP दुनिया में थ्रोबेबल का आविष्कार भी नहीं किया गया था। यह उपयोगी होगा यदि आप उत्तर में लिखते हैं कि थ्रोबेबल अपवाद (और त्रुटि) द्वारा लागू किया गया इंटरफ़ेस है और इस प्रकार इसे भी पकड़ा जा सकता है। लेकिन यह एक अपवाद के पूरक नहीं है।
मोनोफोन



0

मैं यह भी अनुभव कर रहा हूं। मैंने रोविंसन गैलेगो की टिप्पणी पढ़ी कि किस राज्य के अपवाद को फेंक दिया जाना चाहिए। इसलिए मैंने अपना कोड संशोधित किया:

try
{
  $number = 5/0; //or other exception
}
catch(Exception $e)
{
  throw $e;
}

में:

try
{
  $number = 5/0; //or other exception
}
catch(Exception $e)
{
  throw new Exception($e->getMessage(),$e->getCode());
}

यह काम करता हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.