PHPの例外処理をサンプルコード付きで解説。finally内のreturn優先順位や複数catchの書き方、PDOを用いたDB接続の実践例まで、エンジニアが迷うポイントを網羅したリファレンスです。
PHPの例外処理は try catch finally を使用する。
try{} ブロック内でエラー(Exception)を捕捉し、catch{} ブロックで発生したエラーをどのように処理するか記述する。finally{} ブロックはエラーの発生を問わず必ず実行される。
throw は意図的に例外を発生する。
| 場所 | return がある場合の結果 | 優先順位 |
|---|---|---|
| finally | ここが最終的な戻り値になる | 最強(上書き) |
| catch | finally に return がなければ採用される | 中 |
| try | catch / finally に return がなければ採用される | 弱 |
例 PHP try catch finally
try {
// 例外が発生する可能性のある処理
} catch (PDOException $e) {
// データベース関連(JavaのSQLException相当)のエラー処理
echo "DBエラーが発生しました。";
} catch (TypeError $e) {
// 型の不一致など特定のエラー処理
echo "型エラーが発生しました。";
} catch (Exception $e) {
// それ以外の予期せぬエラー(JavaのException相当)の共通処理
echo "予期せぬエラーが発生しました。";
} finally {
// 最後に必ず実行する処理(PHP 5.5以降で使用可能)
}
例 Java try catch finally
try {
// 例外が発生する可能性のある処理
} catch (ClassNotFoundException e) {
System.err.println("JDBCドライバが見つかりません。");
} catch (SQLException e) {
System.err.println("DB操作エラーが発生しました。");
} catch (Exception e) {
System.err.println("予期せぬエラーが発生しました。");
} finally {
// finally句は処理の try句、catch句が実行された後に必ず実行される
}
throw は意図的に例外を発生することができる。
<?php
throw new Exception('意図的にエラーを発生する');
?><?php
try {
throw new Exception('意図的にエラーを発生する');
} catch(Exception $e) {
echo $e; /*「意図的にエラーを発生する」が出力される */
}
?>次のサンプルコードでは、try{} ブロック内で function func() を呼び出し、func() で throw 命令を使い意図的にエラーを発生させている。
func() 内で発生したエラーは、呼び出し元の try{} ブロック で捕捉され、catch{} ブロックが実行される。
<?php
function func() {
throw new Exception('意図的にエラーを発生する');
}
try {
func(); /* funcを呼び出し */
} catch(Exception $e) {
echo $e; /*「意図的にエラーを発生する」が出力される */
}
?>次のサンプルコードでは、try{} ブロック内で function func() を呼び出し、func() 内で function sub_func() を呼び出し、sub_func() で throw 命令を使い意図的にエラーを発生させている。
func()、sub_func()には try catch による例外処理は記述しておらず、func() の呼び出し元に try catch による例外処理を記述している。
sub_func() 内で発生したエラーは、呼び出し元の func() に投げられ、最終的に func() の呼び出し元の try{} ブロック で捕捉され、catch{} ブロックが実行される。
PHPにはJavaの throws Exception 宣言のような「例外を投げることを明示する構文」はないが、例外処理(try-catch)を書かなければ、エラーは自動的に呼び出し元へ伝播していくため、Java の throws Exception と同様の実装ができる。
<?php
function func() {
sub_func(); /* sub_funcを呼び出し */
}
function sub_func() {
throw new Exception('意図的にエラーを発生する');
}
try {
func(); /* funcを呼び出し */
} catch(Exception $e) {
echo $e; /*「意図的にエラーを発生する」が出力される */
}
?><?php
/**
* MySQLに接続する
*
* MySQLに接続する
*
* @version 1.0
* @author hoge
* @param &$pdo MySQLに接続するコネクションオブジェクト
* @return true:正常 false:異常 (Insert失敗)
* @throws Exception なんてPHPにはねぇよ
*/
/* PHP 7.0.0 以降で使用します。 */
function connectMySql(&$pdo) {
global $printDebugMode;
$printDebugMode = false;
print("");
print("▼ function MySQL 接続(connectMySql) ------------------------------");
/* MySql 接続情報 */
$host = "mysql0000.db.hogehoge.jp";
$db = "db_name";
$user = "db_user";
$pass = "db_pass";
$dsn = "mysql:host={$host};dbname={$db};charset=utf8mb4";
/* tryにPDOの処理を記述 */
try {
/* PDOインスタンスを生成 */
$pdo = new PDO($dsn, $user, $pass);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
print("データベース {$db} に接続しました。");
/* エラー(例外)が発生した時の処理を記述 */
} catch (PDOException $e) {
/* エラーメッセージを表示する */
print('データベースの接続に失敗しました mysql_error = ' . $e->getMessage());
return false;
} finally {
print("▲ function MySQL 接続(connectMySql) ------------------------------
");
}
return true;
}
/*
* MySQLに接続する
* @param &$connection MySQLに接続するコネクションオブジェクト
* @return true:正常 false:異常 (Insert失敗)
* @throws Exception なんてPHPにはねぇよ
*/
/* PHP 7.0.0 で削除されました。 */
function old_connectMySql(&$connection) {
print("");
print("▼ MySQL 接続(connectMySql) ------------------------------");
/* MySql 接続情報 */
$url = "mysql0000.db.hogehoge.jp";
$db = "db_name";
$user = "db_user";
$pass = "db_pass";
/* MySQLへ接続 */
$connection = mysql_connect($url,$user,$pass);
if ($connection === false) {
print('データベースの接続に失敗しました mysql_error = ' . mysql_error());
print("▲ MySQL 接続(connectMySql) ------------------------------");
print("");
return false;
}
/*
こんな書き方もできます。dieはその場で実行をphpの実行を止めます。 ※正直、美しいコードとは言えません。
$connection = mysql_connect($url,$user,$pass) or die("MySQLへの接続に失敗しました");
*/
/* データベースを選択する */
$rtn = mysql_select_db($db, $connection);
if ($rtn === false) {
print('データベースの選択に失敗しました mysql_error = ' . mysql_error());
mysql_close($connection);
print("▲ MySQL 接続(connectMySql) ------------------------------");
print("");
return false;
}
/*
* こんな書き方もできます。
* ※汚いコードです。なにより、$connectionの開放をしていません。
* ※PHPでは、die実行時に、自動的にデータベースとの接続を切断するそうです。
* が、PHP側で切断しても、DB側で切断を感知して、自動でコネクションを開放する仕組みになってないと、コネクションは掴みっぱなしになります。
*/
/* $rtn = mysql_select_db($db, $connection) or die("データベースの選択に失敗しました"); */
print("データベース接続に成功しました。");
print("▲ MySQL 接続(connectMySql) ------------------------------");
print("");
return true;
}
?>![]() | 10日で使えるPHP | 未経験のサルでも分かるPHPの学習サイト 文系未経験、サルでも10日でPHPを使えるように内容を構成した独学向け学習サイト。不要な基礎はバッサリ切り捨て必要な基礎を十分に深堀した・・・ 続きを見る |