質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

Q&A

解決済

2回答

2155閲覧

PHPにおける例外処理と関連する不明点

退会済みユーザー

退会済みユーザー

総合スコア0

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

0グッド

1クリップ

投稿2020/04/28 09:53

編集2020/04/28 12:37

理解が足りていない箇所が多いのですが、何卒よろしくお願いいたします。

PHPのエラー発生時の例外処理にての不明点がいくつかございます。
*例外処理について以外の内容も含みます。メソッドやメソッド外の定義並びに、
例外処理に関して誤解しているところが多いかと思います。

【不明点】
・echoの優先順序について
・メソッド内でreturnされた後の流れ
・throw処理について
・function test_exception()メソッド外の優先順位

【誤解しているであろう点】
・上から順に実行されることを強く認識しすぎている
・引数となる変数への誤解
・インスタンス化のタイミング。その後の流れ
・他

html

1<?php 2 3function test_exception($date) { 4 echo "2\n"; 5 try { 6 echo "3\n"; 7 8 return new DateTime($date); 9 echo "4\n"; 10 11 } catch (Exception $e) { 12 echo "5\n"; 13 throw $e; 14 } 15 echo "6\n"; 16} 17 18echo "1\n"; 19 20try { 21 22 $datetime = test_exception("1991-01-01"); 23 24 echo $dateTime->format('Y-m-d')."\n"; 25 echo "7\n"; 26} catch (Exception $e) { 27 echo "8\n"; 28} 29?> 30

まず、上記のコードが実行される流れとして,$datetimeの右辺が問題のない整数の場合は以下

html

11 22 33 47

$datetime = test_exception("199x-01-01")のように右辺に問題のある整数の場合("199x-01-01")
は以下

html

11 22 33 45 58

と実行されるようです。

Q1.

1点目の疑問ですが、上から順に実行される場合はなぜ「echo 2」ではなく、「echo 1」
が先に来るのでしょうか。「echo1」はメソッドfunction test_exception($date)の外のようですが、
メソッド外のechoが優先されるのには理由があるのでしょうか。

Q2.

「echo 2」,「echo 3」が優先されるのはわかりますが、2点目としてreturn new DateTime($date);がどのような状況になっているのか不明です。

returnで何らかの数値やメソッドを返す場合、このケースでは
return new DateTime($date);→function test_exception($date)に返っているのでしょうか??
その場合の流れの理解に困っています。

$datetimeの右辺の整数に問題があるかないかにしろ、echo4実行はなさそうです。
・問題ない整数の場合はreturn処理されるため、try-catchが終了され、次に移る。
・問題のある整数だった場合は、return箇所でエラーとなるため、catchに移りecho5の処理が行われる。

よって、echo4が出力されないのはわかります。

ただreturn new DateTime($date);自体がどのような状態なのか理解できておりません。

・newでインスタンス化する。
・DateTimeというクラスに$date引数が入っている。
・$date引数には下で定義した1991-01-01もしくは199x-01-01が入っている?

function test_exception()は冒頭で定義したメソッドなので、$datetimeの右辺がリンクしているのはわかりますが、引数に任意の数字を入れても、それは最終的に$datetimeに代入されるため、冒頭のfunction test_exception()で使いたくても$datetimeとして使用する??
この辺りが理解できておりません。

わかりにくいですが

$datetime → function test_exception() 
*形式が違うからfunction test_exception()の引数内になぜ1991-01-01もしくは199x-01-01を反映できるのか??

根本的な理解が足りていないと思うのですが、どうしても理解できません。

Q3.

echo 6についてですが、こちらもfunctionメソッド内でtry-catchの外の領域かと思われますが、echo2は問題なく出力されているのに、echo6が出力されない理由も不明です。

Q4.
catch内の echo "5\n";の後、throw $e;で投げられた$e変数の行方が不明です。

まず、paizaなどで学んだ際、通常throwはtry内で使っておりましたが、catch内でも使用は問題なのでしょうか。

また、try内でthrowが使用された場合はcatchへエラー内容を$eとして投げるかと思われますが、こちらの箇所ではecho 5の後に$e変数をどこに投げたのか不明です。

下部のecho 8の箇所へ投げられたのかと思いましたが、echo 7とecho 8の箇所でもtry-catchで例外処理がされるので、その場合は

・echo7箇所でエラー発生

・catchへエラーが運ばれecho8実行されるが、その場合、Exception $eへ運ばれたエラーは
echo5で投げられた$eが優先されるのかecho 7箇所のエラーが優先されるのか不明

*echo 5でのthrow $eが上記のような動作をしていない場合は、現時点で、単にecho 7,echo8の箇所のtry-catchが実行されただけと認識しております。


質問内容や関数に関しての理解が足りていないながら、このような的外れなご質問をさせていただきました。勉強不足だと自認しておりますが、助言などいただけますと幸いです。

*そもそもメソッドと関数という言葉を同義で使用しておりましたがどうやら違いそうです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/28 09:55

おめぇ、マークダウン使えって。
退会済みユーザー

退会済みユーザー

2020/04/28 11:26

マークダウンの件、失礼いたしました。
kei344

2020/04/28 11:51

(質問文は編集できます)質問文のコードはそれぞれコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。
退会済みユーザー

退会済みユーザー

2020/04/28 12:38

失礼いたしました。マークダウン処理を終えました。
guest

回答2

0

ベストアンサー

おす!

###Q1.1点目の疑問ですが、上から順に実行される場合はなぜ「echo 2」ではなく、「echo 1」が先に来るのでしょうか。「echo1」はメソッドfunction test_exception($date)の外のようですが、メソッド外のechoが優先されるのには理由があるのでしょうか。

関数は定義されただけでは実行されねぇぞ。呼び出されて初めて実行される。

$datetime = test_exception("1991-01-01");

が実行されて、初めてfunction test_exception($date){}の中が評価されるんだ。

###Q2.「echo 2」,「echo 3」が優先されるのはわかりますが、2点目としてreturn new DateTime($date);がどのような状況になっているのか不明です。

returnで何らかの数値やメソッドを返す場合、このケースでは
return new DateTime($date);→function test_exception($date)に返っているのでしょうか??
その場合の流れの理解に困っています。

そうじゃねぇ。

new DateTime($date) が実行されて DateTimeクラスのオブジェクト(インスタンス)が生成されて、それが、

$datetime = test_exception("1991-01-01");

ここに返されて $datetime に代入されるんだ。

###Q3.echo 6についてですが、こちらもfunctionメソッド内でtry-catchの外の領域かと思われますが、echo2は問題なく出力されているのに、echo6が出力されない理由も不明です。

そりゃな、try{}ブロックの中ではreturn、catch{}ブロックの中では 新しい例外が throw されるからだ。
throw が実行された時点でそのさらに上の階層にある catch{}ブロックが呼び出される。

つまり、ここに処理が移される。だから echo 6 は絶対に実行されねぇ。

try { $datetime = test_exception("1991-01-01"); echo $dateTime->format('Y-m-d') . "\n"; echo "7\n"; } catch(Exception $e) <-- ここ { echo "8\n"; }

###Q4.catch内の echo "5\n";の後、throw $e;で投げられた$e変数の行方が不明です。

$eは、上のQ3で示したcatch(Exception $e)の $e として渡されるんだ。

まず、paizaなどで学んだ際、通常throwはtry内で使っておりましたが、catch内でも使用は問題なのでしょうか。

throw はどこからでも好きな場所から投げられる。
だけんども、それより上の階層に catch{} ブロックがねぇと、UncaughtException エラーが発生すっぞ。

下部のecho 8の箇所へ投げられたのかと思いましたが、echo 7とecho 8の箇所でもtry-catchで例外処理がされるので、その場合は
・echo7箇所でエラー発生

・catchへエラーが運ばれecho8実行されるが、その場合、Exception $eへ運ばれたエラーは

echo5で投げられた$eが優先されるのかecho 7箇所のエラーが優先されるのか不明

echo 5でthrowされるのはecho 3の下のnew DateTime($date)が失敗した時だろ。
その場合はecho 8に処理が移動するので、echo 7が実行されることは絶対にねぇ。
だから、優先とか関係ねぇ。優先ってぇのは、2つの事が同時に起きた時の選択だ。
2つが同時に起きる事はねぇ。

ふぅ、長ぇな。

投稿2020/04/28 10:15

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/28 10:18

gokuさん、ありがとうございます。マークダウン機能を知りませんでした。すみません。 回答内容これから確認させていただきます。 今後はマークダウンをしっかり使用してご質問させていただきたいと思っております。
退会済みユーザー

退会済みユーザー

2020/04/28 10:30

プログラムってぇのは基本的には一筆書きだ。 $datetime = test_exception("1991-01-01"); で、 function test_exception($date) を呼び出して実行しつつ、 echo $dateTime->format('Y-m-d') . "\n"; echo "7\n"; も実行されるってことは、ねぇ。 $datetime = test_exception("1991-01-01"); で正常に処理が返ってきた時だけ、 echo $dateTime->format('Y-m-d') . "\n"; echo "7\n"; が実行されっぞ。
退会済みユーザー

退会済みユーザー

2020/04/28 11:25

理解できた箇所とわからなかった箇所がございます。 失礼だとは思いますが、gokuさんの説明の仕方なんか好きです笑 まず理解できた箇所としてecho 6が実行されないのはわかりました、エラーがあるにしろないにしろecho 6に到達し得ないのですね。 エラーなし→ return処理で関数処理終了後 echo7箇所tryへ移る。 エラーあり→echo5の箇所からthrowでecho6を無視してecho 8箇所のcatchに移り実行 (echo 7のtryも同様に無視) echo7箇所のtryに関してもエラーがあった場合は上記の流れで、エラーがない場合は、単にtry-catch実行にてecho 7実行でecho 8 catch箇所は無視。 という認識ができました(あっているのか少し不安)。 echo 1に関しては最初に出力されるのは関数の外にあるため、外の領域が優先されるためでしょうか? やはり不明な点としては、 ```html return new DateTime($date); と $datetime = test_exception("1991-01-01"); ``` の箇所です。 まず、 ・Datetimeクラス自体が定義されていないのに、クラスとして使用できるのが不明な点。 ・return new DateTime($date);が$datetime = test_exception("1991-01-01");へ返されるとのことですが、返されるというのは$datetime = test_exception("1991-01-01");全体に"インスタンス化しましたよ" という状態が付与されるのか。 例えばなのですが、 ```html class Test { function example __construct($num) { return $num + 1; } } $num = new Test(9); echo $num; 結果: 10 ``` 上記であれば、クラスも定義されているし、メソッド引数の$numとメソッド内の$numが紐付いており、 下で定義した$num引数への具体的な数字を含め理解できるのですが、 今回のnew DateTime($date)の場合は$numの時のように、対になる記述がないにも関わらず、 $datetime = test_exception("1991-01-01");に返るというのがどうしても理解に苦しんでおります。 $datetime = test_exception("1991-01-01");のどこに返ったのか。 $numの例の場合は、最終的に具体的な演算子を入れているのは$num = new Test(9);の箇所ですので、 順序としては $num = new Test(9); ↓ function example __construct($num) ↓ return $num + 1; ↓ echo $num; という印象ですが、今回の例の時系列がわかっておりません。 関数についてもう少し学んでいかねばならないと思っております。 gokuさんのおかげで他の箇所は理解できたかと思っております。 ありがとうございました。
退会済みユーザー

退会済みユーザー

2020/04/28 11:25

こちらでマークダウンは使用できないのですね。失礼しました。
退会済みユーザー

退会済みユーザー

2020/04/28 12:41

> まず、 > ・Datetimeクラス自体が定義されていないのに、クラスとして使用できるのが不明な点。 DateTimeはPHPの組み込みクラスだからな。PHP 5.2以上なら、デフォルトで利用できるんだ。
退会済みユーザー

退会済みユーザー

2020/04/28 12:53

> 今回のnew DateTime($date)の場合は$numの時のように、対になる記述がないにも関わらず、 > $datetime = test_exception("1991-01-01");に返るというのがどうしても理解に苦しんでおります。 test_exception("1991-01-01"); を実行すると、 function test_exception($date) { } が実行されて、 $date の中に"1991-01-01"が入ってる。 それで、new DateTime($date); が実行されるんだが、$date は"1991-01-01"なので、 この日付情報を持ったDateTimeオブジェクトが生成される。 このオブジェクトは"1991-01-01"という日付を内部に持っていて、 例えば echo obj->format("Y年m月d日") とやれば、"1991年01月01日"というフォーマットで日付を取得できたりする。 で、そのオブジェクトを return している。 return すると、function の呼び出し元である test_exception("1991-01-01"); に処理が返ってきて、objも渡される。つまり、 $datetime = obj こういうわけで、$datetime には new DateTime("1991-01-01")の結果が代入される。 だからその後で、echo $dateTime->format('Y-m-d') とやると、 Y = 西暦4桁 m = 月2桁 d = 日2桁となって 1991-01-01 が出力される ってぇ、わけだ。
guest

0

つまりだ、わかり易く書くと

<?php echo "1\n"; try { echo "2\n"; try { echo "3\n"; $datetime = new DateTime("1991-01-01"); goto success; echo "4\n"; } catch(Exception $e) { echo "5\n"; throw $e; } echo "6\n"; success: echo $dateTime->format('Y-m-d') . "\n"; echo "7\n"; } catch(Exception $e) { echo "8\n"; }

こうなってんだ。

投稿2020/04/28 10:20

編集2020/04/28 10:22
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/29 11:36

gokuさん。ご回答ありがとうございました!! なんとか理解できた気がします。 echo1 はメソッドの外のため、優先的に実行。 echo 2はメソッド内の初めの処理で時点で優先される try-catch処理に移り、echo 3実行後に returnの部分でエラーの可否を判断し エラーがない場合は、returnで二つ目のtry-catchのtryへ返ってecho 7実行。 一つ目のtry-catchでエラーが発生した場合はcatchに投げられ、まずecho5実行の後、 二つ目のtry-catchのcatch処理へ移行。echo 5で渡された$eエラーを含むcatch処理で echo 8実行。 という認識に変わりました。 色々とご指導いただきまして、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問