PHPのTry / Catchブロックが例外をキャッチしない


97

私はこのページからこの例1を実行しようとしています:http : //php.net/manual/en/language.exceptions.php

<?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.5PHP 5.2.3


1
コードを見せていただけますか?このエラーを取得するためにできる唯一の間違いは、間違った例外(またはなし)をキャッチすることです。
Tammo

2
コードはまったく同じです(改行を追加しました)...とにかく、もう一度コードをテストファイルにコピーしました。同じエラーメッセージは次のとおりです:0.2致命的なエラー:キャッチされない例外 'Exception'とメッセージ 'Division by zero' 」W:\ www \ test.php:4スタックトレース:#0 W:\ www \ test.php(11):reverse(0)#1 {main}がW:\ www \ test.phpの4行目にスローされました私はそこで何が起こっているのか本当にわかりません...おそらくPHPの設定に欠陥がありますか?
Krassi、2010年

1
一部の古い拡張バージョンでは、例外処理で問題が発生しました。5.2.3は古く、バグがエラーの背後にある可能性があります。PHPをアップグレードできますか?現在の製品バージョンが5.5であることを考えると、UniServer 3.5もかなり古いものです。3.5はタイプミスですか?
10

1
UniServerのリリース情報(wiki.uniformserver.com/index.php/…)を見ると、3.5はタイプミスではないようです。UniServer 5.5にアップグレードして、サンプルコードを再試行してください。
outis

1
outis、ヒントをありがとう:) これは当時私がやったことです-XAMPPに切り替えました(UniServerの新しいバージョンは好きではありません)。3.5はタイプミスではありませんが、サーバーは私にとって完璧に機能したので、アップグレードする必要はありませんでした。
Krassi

回答:


217

私はこの正確な問題を抱えていて、例外の名前をコピーしたように見えましたが、それをキャッチできませんでした。それは私の愚かな間違いだったことが判明しましたが、同じ状況に他の誰かがいる場合に備えて、ここに私のケースを投稿するべきだと思いました。

Aという名前空間に例外があり、スクリプトはBという名前空間にありました。問題は、(PHPでは)\ B \ A \ MyExceptionに等しいA \ MyExceptionがあったことです(スクリプトがBと呼ばれる名前空間にあるためです)。すべての私はそれはそれは次のようになりますので、例外名にバックスラッシュ(または何でもそれが呼ばれています)を追加した修正しなければなりませんでした:\ A \ MyException


7
私が私の間違いに気付かずに数日を過ごしていたので、これを投稿していただきありがとうございます。
tipu

79
これで私の問題は解決しましたcatch (\Exception $e)。名前空間付きコードの単純な遅延キャッチブロックはになるはずです。バックスラッシュExceptionがないと、名前空間に固有であり、マッチング(またはキャッチ)されません。
joemaller 2013年

3
これを投稿してくれてありがとう!
keepkimi 2013

2
これを投稿していただきありがとうございます。私は、最近数時間を費やして、私のcatchブロックが機能しなかった理由に夢中になりました。主要な顔面掌。
ミッチ

4
乾杯!私の日を救った(そしてニューロン...):)
野菜

67

かなり古い質問ですが...

私もこの問題を抱えていました(そしてそれが私がこの投稿を見つけた方法です)が、単純な実験で解決策を見つけることができました。に変更Exceptionしてみてください\Exception。私のために働いた!

編集:

sivannがコメントで指摘したように、名前空間を使用しても同じことができます。したがって、単にuse \Exception as Exception;クラス宣言の前に置きます。


鮮やかさ!:)たぶん私が理解するのに何時間もかかるだろう、ただ名前空間について考えなかっただけだ。ありがとう!
Alexander Gilmanov 2016年

はい!また:「\ ExceptionをExceptionとして使用してください。」上部の同じことを行います。
sivann

@ sii-anik sivannが書いたように名前空間を使用してみてください。
Enethion 2016年

ちょうどそれuse Exception;を行う必要があります
ディエゴポンチャーノ

ありがとうございました!@エネシオン
ノームウェイ

32

catch(\Exception $e)代わりに入れてみてくださいcatch(Exception $e)。よく知らないコードを使用している場合、または-特に-フレームワークを使用している場合は、デフォルトのPHP例外を独自のコードでオーバーライドする可能性があるため、間違ったパスに移動して取得する可能性があります望ましくない結果。を置くだけで\Exception、基本的なPHP例外を確実にキャッチしています。


@crassi、私の提案を試してみましたか?
Vladimir Despotovic 2017年

2
それは私のためにそれをしました
cljk

20

C#(Csharp)のような他の言語でできるように、PHPで典型的なtry {} catch {}ブロックを使用することはできません。

これを行う場合:

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

「Got it!」は表示されません。メッセージはありません。どうして?これは、PHPが「スロー」されるためには常に例外が必要だからです。独自のエラーハンドラーを設定し、それを使用して例外をスローする必要があります。

set_error_handler関数を参照してください:http : //php.net/manual/es/function.set-error-handler.php


6
それは同じではありません;)あなたは自分で例外をスローする必要があり、それが私が言ったことでした(<< PHPは常に「スローされるためには例外が必要だから」>>)@JaredFarrish
Rowinson Gallego

はい、でもどうして同じではないのですか?
Jared Farrish、2011年

そのリンクは死んでいますが、私はこれが便利であると思いました:w3schools.com/php/func_error_set_error_handler.asp
嫌悪

PHPバージョン7.3.9では$number = 5/0;、例外は発生しません。$numberに設定されていますINF
virtualmic

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)(ビルド:2010年8月12日17:32:30)Copyright(c)1997-2010 PHP Group Zend Engine v2.2.0、Copyright(c)1998-2010 Zend Technologies with eAccelerator v0.9.5。 1、Copyright(c)2004-2006 eAccelerator、by eAccelerator

解決策は、eAcceleratorを無効にするか、更新することです。私は両方を試しましたが、両方の修正が機能しました。バグはこちらで報告されていますhttps://eaccelerator.net/ticket/242 SSL証明書について不平を言っています)。

今私は走っていますが、以下の構成で適切にキャッチしてください、

PHP 5.2.4(cli)(ビルド:2007年10月16日09:13:35)Copyright(c)1997-2007 PHP Group Zend Engine v2.2.0、Copyright(c)1998-2007 Zend Technologies with eAccelerator v0.9.6。 1、著作権(c)2004-2010 eAccelerator、eAccelerator



3

Xdebugには設定があります:

xdebug.show_exception_trace = 1

これにより、phpはtry catchブロックでも例外を出力します。これを0


2
私の場合、xdebugモジュールを完全に無効にする必要がありました(xdebug.show_exception_traceを変更するだけでは不十分でした)。
Thomas Sahlin 2017年

このリマインダーをありがとう。しばらく完全に混乱しました。
ブライアンリッツィンガー2018年

3

PHP 7を使用している場合、例外の代わりにThrowableが必要になる場合があります


これはかなり古い投稿です。答える前に、トピックの日付を確認してください。完了していない- -説明なし理由:その横にそのがあるとして、あなたの答えは本当に便利ではありません
monofone

1
その理由は、PHP7が例外の代わりにスロー可能を使用しているためです。このディスカッションは、問題に遭遇したときに最初に見つけたものであり、貢献したいと思っていました。このようなコメントは、Stackがコミュニティフレンドリーではない理由です。
user5528384

1
あなたを怒らせるのは私の意図ではありませんでした。この投稿は「最初の投稿」のレビューキューに表示されましたが、私の意見では、かなり古い質問に回答を投稿することは役に立ちませんでした。また、執筆時点では、PHPの世界でQuestion Throwableは発明されていませんでした。Throwableは例外(およびエラー)によって実装されるインターフェイスであり、キャッチすることもできるという回答を書いておくと役立ちます。ただし、これは例外の補足ではありません。
モノフォン



0

私もこれを経験しています。例外をスローする必要があると述べたRowinson Gallegoからのコメントを読みました。だから私はからコードを変更しました:

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());
}

できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.