コード例

PHP用語集

カテゴリー: 制御構造  閲覧数:707 配信日:2010-05-22 10:16


投げない


例外を投げていない
・例外を「スロウ(投げる)」していないため、エラーが起こっても「トライ」が全部実行され「例外処理」も実行されない、無意味なサンプル
※「例外処理」は、「例外」が「スロウ(投げる)」されてはじめて実行される
 
   echo "--- 例外 テスト ---\n\n";//①
   
   try{
       echo "→→→ try 開始 →→→\n\n";//②
       #引数が不正な関数コール(「Warning」警告)
       //substr();
       echo "←←← try 終了 ←←←\n\n";
   }catch(Exception $e){
       echo "****** catch ******\n\n";
   }
   
   echo "--- 例外 テスト ---";

・結果
--- 例外 テスト ---

→→→ try 開始 →→→

←←← try 終了 ←←←

--- 例外 テスト ---


投げる


「例外」を「スロウ(投げる)」して「例外処理」を実行するサンプル
 
   echo "--- 例外 テスト ---\n\n";//①
   
   try{
       echo "→→→ try 開始 →→→\n\n";//②
       echo "- 例外が投げられました。-\n\n";
       throw new Exception("例外が投げられました。");//③「try」ブロックの処理はこの一文が実行された時点で中断。「Exception」クラスのインスタンスを生成し、コンストラクタに「"例外が投げられました。"」という文字列を渡している
       echo "←←← try 終了 ←←←\n\n";
   }catch(Exception $e){//④投げられた「例外」を「キャッチ」。「変数$e」は必ず「Exception」クラスのインスタンスが渡されることを想定した「catch」の引数。つまり、「throw文」によって投げられた「Exception」クラスのオブジェクトは「変数$e」に引数として代入され、キャッチブロック内で利用されることになる。
       echo "****** catch ******\n\n";
       echo '$e->getMessage() : ', $e->getMessage(), "\n\n";//キャッチブロック内の「例外処理」を実行
       //echo "\$e : \n", $e, "\n\n";
   }
   
   echo "--- 例外 テスト ---\n\n";//

・結果
--- 例外 テスト ---

→→→ try 開始 →→→

- 例外が投げられました。-

****** catch ******

$e->getMessage() : 例外が投げられました。

--- 例外 テスト ---


投げる順番


最初の「throw文」が実行される前に、コンストラクタ内の「throw文」が実行される例
    class NotException{}
   class Ex1 extends Exception{
       public function __construct($message = NULL, $code = 0){
           parent::__construct($message, $code);
           //throw new NotException; //「Not例外オブジェクト」を生成して投げようとしている//Fatal error:  Exceptions must be valid objects derived from the Exception base class
       }
   }
   
   try{
       throw new Ex1;//①「例外オブジェクト」を生成して投げようとしている
   }catch(Exception $e){
   }



0除算


エラーを発生させ、try~catchで例外を補足している例
・tryブロック内の処理でdivision関数の第2引数を0にして呼び出した際に例外が発生し、Exceptionクラスのオブジェクトが投げられる。続いて、「例外クラス名でExceptionを指定したcatchブロック」で例外が捕捉され、処理が行われていることが確認できる。なお、tryブロック内で例外が発生しなかった場合は、catchブロックの処理は行われない
function division($arg1, $arg2)
{
if ($arg2 === 0) {
throw new Exception('ゼロ除算はできません。<br>');
}
$answer = $arg1 / $arg2;
return $answer;
}

echo 'try catch start<br>', PHP_EOL;//定数 ソース上で改行

try {
echo 'try start<br>', PHP_EOL;
echo division(10, 2)."<br>", PHP_EOL;
echo division(10, 0), PHP_EOL;
echo 'try end<br>', PHP_EOL;
} catch (Exception $e) {
echo 'catch start<br>', PHP_EOL;
echo $e->getMessage(), PHP_EOL;
echo "例外コード:" . $e->getCode()."<br>", PHP_EOL;
echo "行番号:" . $e->getLine()."<br>", PHP_EOL;
echo "<pre>バックトレース:<br>";
p( $e->getTrace( ) );
echo "</pre>";
echo 'catch end<br>', PHP_EOL;
}

echo 'try catch end<br>例外処理後、スクリプト継続', PHP_EOL;
/* 出力:
try catch start
try start
5
catch start
ゼロ除算はできません。
例外コード:0
行番号:19

バックトレース:

Array
(
[0] => Array
(
[file] => /○○/PHPStyleNote/basic/exception/7.php
[line] => 30
[function] => division
[args] => Array
(
[0] => 10
[1] => 0
)

)

)

catch end
try catch end
例外処理後、スクリプト継続
*/


簡易クラス
class Calc
{
   public static function division($int1, $int2){
       try {
           if ($int2 == 0) {
               throw new Exception('0で割ろうとしました');
           }
           $answer = $int1 / $int2;
           echo $answer . "
";
           echo '割り算が終了しました' . "
";
       } catch (Exception $e) {
           echo $e->getMessage() . "
";
           echo '割り算が異常終了しました' . "
";
       }
   }
}

Calc::division(10, 2);
Calc::division(10, 0);

・結果
5
割り算が終了しました
0で割ろうとしました
割り算が異常終了しました

場合分け項目を増加
    function division($num1, $num2){//②
       try{
           if($num2 === 0)//「比較演算子===」等しい(型も同じ) ⑩
               throw new Exception('「0」で割ることは出来ません。');
           else if(!is_numeric($num1) || !is_numeric($num2))//「論理和||」いずれかのオペランドが「真」なら「true」 を返す
               throw new Exception('値が不正です。');//⑥
           return $num1 / $num2;//③ ⑧0÷10=0 「0を割る」は成立する。
       }catch(Exception $e){
           return $e->getMessage();
       }
   }
   
   echo division(10, 2), "\n";//①④
   echo division(10, ""), "\n";//⑤
   echo division(0, 10), "\n";//⑦
   echo division(10, 0), "\n";//⑨

・結果
5
値が不正です。
0
「0」で割ることは出来ません。

例外ごとのクラス作成
    class DivisionEx extends Exception{}//Exception」クラスを継承した「DivisionException」クラスを定義。“割算における「例外」”
   class DivisionIsZeroEx extends DivisionEx{//「DivisionEx」クラスを継承した「DivisionIsZeroEx」クラスを定義。“分母が「0」であるという「例外」”
       protected $message = '「0」で割ることは出来ません。';
   }
   class DivisionWrongValueEx extends DivisionEx{//「DivisionEx」クラスを継承した「DivisionWrongValueEx」クラスを定義。“値が不正であるという「例外」”
       protected $message = '値が不正です。';//⑮
   }
   
   class Division{//割算を行うためのクラス。コンストラクタに渡された2つの値をチェックし、問題があれば「例外」を投げ、問題がなければ(「例外」が投げられていなければ)演算結果をプロパティに保存
       private $result;//⑤⑳
       public function __construct($num1, $num2){
           if($num2 === 0)
               throw new DivisionIsZeroEx;
           else if(!is_numeric($num1) || !is_numeric($num2))
               throw new DivisionWrongValueEx;//⑬
           $this->result = $num1 / $num2;//④⑲
       }
       public function getResult(){//⑦
           return $this->result;
       }
   }
   
   function division($num1, $num2){//②⑪⑰
       try{//投げる元はココ
           $division = new Division($num1, $num2);//③⑫⑱
           return $division->getResult();//⑥⑧
       }catch(DivisionEx $e){//ここでキャッチ
           return $e->getMessage();//⑭
       }
   }
   
   echo division(10, 2), "\n";//①⑨
   echo division(10, ""), "\n";//⑩
   echo division(0, 10), "\n";//⑯
   echo division(10, 0), "\n";

・結果
5
値が不正です。
0
「0」で割ることは出来ません。


ファイルオープン


処理基点となるスクリプトをtry~catchすることで、全ての例外をそこで捕まえる例
class File
{
   public static function read($path)
   {
       if (false == file_exists($path)) {
           throw new Exception('ファイルが存在しません');
       }
       $fp = @fopen($path, 'r');
       if (false === $fp) {
           throw new Exception('ファイルのオープンに失敗しました');
       }
       $data = @stream_get_contents($fp);
       if (false === $fp) {
           throw new Exception('ファイルの読込に失敗しました');
       }
       return $data;
   }
}

class StringViewer
{
   public function display($path)
   {
       try {
           $data = File::read($path);
           echo $data;
       } catch (Exception $e) {
           die($e->getMessage());
       }
   }
}

$viewer = new StringViewer();
$viewer->display('C:/aaa.txt');

・結果
ファイルが存在しません


指定期間人気ページランキング / 2020-5-28 → 2024-4-22
順位 ページタイトル抜粋 アクセス数
1 PHP用語 6620
2 ブラウザを閉じたらセッションデータはどうなるの? | セッション 2172
3 Parse error: syntax error, unexpected 'public' (T_PUBLIC) | Parse error(エラーメッセージ) 2089
4 ブラウザを閉じたらセッションデータはどうなるの? | セッション 1540
5 【テスト投稿】テスト | 1130
6 セッション管理が必要な理由は、HTTPプロトコルには状態を保持する機能がないため | セッション 909
7 Fatal error: Access level to ▲::$△ must be protected (as in class ●) or weaker | Fatal error(エラーメッセージ) 727
8 PHPで定数を定義する方法は2種類ある / 配列定数の定義 716
9 Fatal error: Uncaught Error: Call to a member function modify() on string | Fatal error(エラーメッセージ) 715
10 Fatal error: require_once(): Failed opening required 'PEAR.php' | Fatal error(エラーメッセージ) 705
11 インターフェイス | クラスとオブジェクト 686
12 コード例 … 「例外処理」はネストすることができる 671
13 定数 670
14 Fatal error: Uncaught RuntimeException: SplFileObject::__construct(): failed to open stream: Permission denied in | Fatal error(エラーメッセージ) 647
15 メンバー | クラスとオブジェクト 637
16 curl で Cookie を使用する 636
17 Fatal error: Uncaught HeadlessChromium\Exception\OperationTimedOut: Operation timed out (3sec) in | Fatal error(エラーメッセージ) 604
18 Warning: include() [function.include]: Failed opening '**.php' for inclusion (in | Warning(エラーメッセージ) 592
19 ( ! ) Fatal error: Uncaught PDOException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column | Fatal error(エラーメッセージ) 562
20 セッション名 | セッション 534
2024/4/23 1:01 更新