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

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

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

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

Q&A

解決済

3回答

8429閲覧

if文と例外処理の違い

fukiten

総合スコア12

PHP

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

0グッド

2クリップ

投稿2018/07/03 03:40

編集2018/07/03 03:43

if文と例外処理(try, catch)の違いがわかりません。
画像投稿サイトを作っていて、アップロードされたファイルのバリデーションを
どうすべきか調べていたところ、例外処理をみかけて思いました。

私は①のようなコードを書いていたのですが、例えば②を私のようにtry, catchを使わず
①のように$errs[]に入れた としてなにか違いはあるのでしょうか?

PHP

12if(a){ 3バリデーション 4だめなら$errs['a']にエラーメッセージを入れる 5} 6if(b){ 7バリデーション 8だめなら$errs['b']にエラーメッセージを入れる 9} 10if(c){ 11バリデーション 12だめなら$errs['c']にエラーメッセージを入れる 13} 14151617 18if(empty($errs)){ 19本番の処理 20} 21 2223try { 24 25 // 未定義である・複数ファイルである・$_FILES Corruption 攻撃を受けた 26 // どれかに該当していれば不正なパラメータとして処理する 27 if (!isset($_FILES['upfile']['error']) || !is_int($_FILES['upfile']['error'])) { 28 throw new RuntimeException('パラメータが不正です'); 29 } 30 31 // $_FILES['upfile']['error'] の値を確認 32 switch ($_FILES['upfile']['error']) { 33 case UPLOAD_ERR_OK: // OK 34 break; 35 case UPLOAD_ERR_NO_FILE: // ファイル未選択 36 throw new RuntimeException('ファイルが選択されていません'); 37 case UPLOAD_ERR_INI_SIZE: // php.ini定義の最大サイズ超過 38 case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過 (設定した場合のみ) 39 throw new RuntimeException('ファイルサイズが大きすぎます'); 40 default: 41 throw new RuntimeException('その他のエラーが発生しました'); 42 } 43 44 // ここで定義するサイズ上限のオーバーチェック 45 // (必要がある場合のみ) 46 if ($_FILES['upfile']['size'] > 1000000) { 47 throw new RuntimeException('ファイルサイズが大きすぎます'); 48 } 49 50 // $_FILES['upfile']['mime']の値はブラウザ側で偽装可能なので 51 // MIMEタイプに対応する拡張子を自前で取得する 52 if (!$ext = array_search( 53 mime_content_type($_FILES['upfile']['tmp_name']), 54 array( 55 'gif' => 'image/gif', 56 'jpg' => 'image/jpeg', 57 'png' => 'image/png', 58 ), 59 true 60 )) { 61 throw new RuntimeException('ファイル形式が不正です'); 62 } 63 64 // ファイルデータからSHA-1ハッシュを取ってファイル名を決定し,保存する 65 if (!move_uploaded_file( 66 $_FILES['upfile']['tmp_name'], 67 $path = sprintf('./uploads/%s.%s', 68 sha1_file($_FILES['upfile']['tmp_name']), 69 $ext 70 ) 71 )) { 72 throw new RuntimeException('ファイル保存時にエラーが発生しました'); 73 } 74 75 // ファイルのパーミッションを確実に0644に設定する 76 chmod($path, 0644); 77 78 echo 'ファイルは正常にアップロードされました'; 79 80} catch (RuntimeException $e) { 81 82 echo $e->getMessage(); 83 84} 85 86https://qiita.com/mpyw/items/939964377766a54d4682#%E7%94%BB%E5%83%8F%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E5%87%A6%E7%90%86%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E9%9B%86 87より引用

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

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

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

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

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

guest

回答3

0

ベストアンサー

単純な意味だけでいうと if は条件分岐で、 try は例外時のアクションの規定です。

if でその時点での条件を調べて処理を分岐させます。どちらに進んでも逐次的な動作(上から順に動く)です。

一方 try は「以後の処理ができない」という例外が発生した箇所から catch に飛びます。途中の処理は実行されません。
発生した例外のクラスに応じて catch できるので、例外Aはリカバリ可能なのでcatchで処理して、例外Bは処理できないので更に関数の呼び出し元で対応する(エスカレーションする)ということもできます。
また、例外が発生するのは自分で throw するときだけではなく、DBへの書き込みエラーやURLへのアクセスなどの関数の呼び出し結果として例外を受け取ることがあります。
関数の呼び出し元への非常事態のエスカレーションという意味で重要な役割を持っています。

①の例のようにどのパラメーターが間違っているのか全部チェックしたい(ひとつミスがあったとしてもそこで止めない)という場合は if が適しています。

一方、②の例は何でもかんでも RuntimeException にしているのであまり良くないです。例外クラスは自分で定義することもできるので、パラメータ不正エラーなどいくつかの例外を定義することでより適切な例外処理を実現できると思います。
あくまでも「状態に問題があって以後の処理が継続できない」というケースを基準に例外を使うべきだと思います。

投稿2018/07/03 04:31

mather

総合スコア6753

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

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

fukiten

2018/07/03 04:58

ありがとうございます。引っかかった処理以降をどうするかによるのですね。 中断せずに全部チェックしたかったのでifで行こうと思います。
guest

0

例外処理のいいところは

throwしたところで処理を中断できること
ifだと中断しないので後の処理がいらないという場合結構めんどくさい

catchされるとこまで戻せること
例のやつとかだとこういう感じにもできて、各部の判定をテストしやすくなる

php

1<? 2function check_file_error($file){ 3 // 未定義である・複数ファイルである・$_FILES Corruption 攻撃を受けた 4 // どれかに該当していれば不正なパラメータとして処理する 5 if (!isset($file['error']) || !is_int($file['error'])) { 6 throw new RuntimeException('パラメータが不正です'); 7 } 8 9 // $file['error'] の値を確認 10 switch ($file['error']) { 11 case UPLOAD_ERR_OK: // OK 12 break; 13 case UPLOAD_ERR_NO_FILE: // ファイル未選択 14 throw new RuntimeException('ファイルが選択されていません'); 15 case UPLOAD_ERR_INI_SIZE: // php.ini定義の最大サイズ超過 16 case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過 (設定した場合のみ) 17 throw new RuntimeException('ファイルサイズが大きすぎます'); 18 default: 19 throw new RuntimeException('その他のエラーが発生しました'); 20 } 21} 22function check_file_size($file,$max_size=1000000){ 23 // ここで定義するサイズ上限のオーバーチェック 24 // (必要がある場合のみ) 25 if ($file['size'] > $max_size) { 26 throw new RuntimeException('ファイルサイズが大きすぎます'); 27 } 28} 29function check_file_type($file){ 30 // $file['mime']の値はブラウザ側で偽装可能なので 31 // MIMEタイプに対応する拡張子を自前で取得する 32 if (!$ext = array_search( 33 mime_content_type($file['tmp_name']), 34 array( 35 'gif' => 'image/gif', 36 'jpg' => 'image/jpeg', 37 'png' => 'image/png', 38 ), 39 true 40 )) { 41 throw new RuntimeException('ファイル形式が不正です'); 42 } 43} 44function save_file($file){ 45 46 // ファイルデータからSHA-1ハッシュを取ってファイル名を決定し,保存する 47 if (!move_uploaded_file( 48 $file['tmp_name'], 49 $path = sprintf('./uploads/%s.%s', 50 sha1_file($file['tmp_name']), 51 $ext 52 ) 53 )) { 54 throw new RuntimeException('ファイル保存時にエラーが発生しました'); 55 } 56 57 // ファイルのパーミッションを確実に0644に設定する 58 chmod($path, 0644); 59} 60try { 61 check_file_error($_FILES['upfile']); 62 check_file_size($_FILES['upfile']); 63 check_file_type($_FILES['upfile']); 64 65 save_file($_FILES['upfile']) 66 67 echo 'ファイルは正常にアップロードされました'; 68 69} catch (RuntimeException $e) { 70 71 echo $e->getMessage(); 72 73}

投稿2018/07/03 04:32

KazuhiroHatano

総合スコア7802

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

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

0

例外とは

例外とは、プログラムの実行中に何らかの異常が発生することを言いますが、開発者が明示的に例外を発生させることもできます。例外処理とは、実行中に発生した例外を捕捉し、それに対応する処理を行うことです。

基本的には後続の処理が継続不可となる事態が発生したことによる処理の中断です。

提示の(というか提示記事の)コードではRuntimeException()をthrow することで、明示的に次の処理を行わないようにしています。
①のコードはバリデーションを行った結果でエラーメッセージをためていっているだけですよね。
もちろん途中でreturnなどすれば「中断」と言えるかもしれませんが、「後続の処理が継続不可となった」かどうかの判断ではありません。

投稿2018/07/03 04:13

編集2018/07/03 04:20
m.ts10806

総合スコア80765

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問