SEEDS Creator's Blog

読者です 読者をやめる 読者になる 読者になる

例外はきちんと書こう

PHPで、とあるリクエストに対して、xml形式でレスポンスを返すというプログラムを作成していました。

メインPHP

main.php
function main() {

 // 1.DBより何か参照してくる
 $rs = $child->reference();

 // 2.domDocumentを利用し、xml生成する
 $dom = new domDocument('1.0', 'UTF-8');
 ・・・省略・・・

 // 3.レスポンス返す
 header('Content-Type: application/xhtml+xml');
 echo $dom->saveXML();
}

サブPHP

child.php
function reference() {
 try {
  // selectして結果返す
  $rs = $dao->select('table', $columns, $where);
  return $rs;
 } catch (Exception $e) {
  throw $e;
 }
}

が期待した動作をせず、、、

Empty reply from server

みたいなエラーが返されてます。空がサーバから返されてる。。!?

何気にapacheのログを参照すると、、

child pid xxxx exit signal Segmentation fault (11)

なるエラーが!? ググってみるとふむふむ、うーん、参照してはいけないメモリ領域を参照してるみたいで詳細を調査する場合は、コアダンプをはいてみないといけない・・・はい、レベル高いです!! まだロジックで調べてみることがあるだろうと、気持ちを入れなおし、ごにょごにょ調べていると。。おおっ!SQLがエラーログはいてました!!

2以降の処理は、1からの正常処理しか期待していないロジックを書いていました。 きちんと例外(エラー)のことを考えないといけないですね。 メインPHPを以下のように改善しました。

改善後メインPHP

main.php

function reference() {

 // 1.DBより何か参照してくる
 $isSuccess = true;
 try {
  $rs = $child->reference();
 } catch (Exception $e) {
  $isSuccess = false;
 }

 // 2.domDocumentを利用し、xml生成する
 $dom = new domDocument('1.0', 'UTF-8');
 if ($isSuccess) {
  // 2-1.正常処理
  ・・・省略・・・
 } else {
  // 2-2.例外処理
  ・・・省略・・・
 }

 // 3.レスポンス返す
 header('Content-Type: application/xhtml+xml');
 echo $dom->saveXML();
}

エラーでなくなりました。よかったです! SQLエラーは仕方ないとして、どうしてSegmentation faultが出力されるのでしょうかね。 XML(DOM?)オブジェクトあたりが怪しい??詳細は不明、、、

例外処理もちゃんと考慮して書くようにしましょう。