Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

PHPエクステンションのエラー処理

PHPエクステンションの作り方 第7回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2014/04/04 14:00

 本連載では、PHPエクステンションの作成方法を紹介します。前回までで基本的な関数からクラス定義、そしてストリーム処理の開発方法について紹介しました。今回はそこで紹介ができなかったエラー処理に対する方法と、より開発しやすいように筆者が利用しているCMakeビルドシステムについて紹介します。

目次

対象読者

 PHPでの基本構文を理解している方で、PHPエクステンションに興味がある方、さらに深くPHPを知りたい方で、C言語の基本的な構文を理解している方を対象としています。

必要な環境

 この記事では、PHP 5.4を使用し、Linux環境で確認を行っています。インストール方法は初回を参照してください。

PHPのエラーログにエラー情報を出力する

 PHPのエラーは、php.iniで設定しているerror_logに表示されます。以下の表示例はサンプルコードにより表示させた時のエラーログの内容です。

エラー出力例
Notice: errchk_report(): simple message in /errchk/errchk.php on line 2                      // ・・・(1)
Warning: errchk_report(): message format[message arg] in /errchk/errchk.php on line 2        // ・・・(2)
Notice: errchk_report(arg1): docref1 message in /errchk/errchk.php on line 2                 // ・・・(3)
Notice: errchk_report(arg1,arg2): docref2 message in /errchk/errchk.php on line 2            // ・・・(4)

 このエラー表示のフォーマットは、以下のようになっています。

エラー出力例
[エラーレベル]: [エラーの関数名]: [エラーメッセージ] in [PHPのプログラム名] on line [PHPのプログラムの行数]

 エクステンション内で表示させるには、以下の関数を使います。

エラー表示するための関数
void php_error_docref0(const char *docref TSRMLS_DC, int type, const char *format, ...)
void php_error_docref1(const char *docref TSRMLS_DC, const char *param1, int type, const char *format, ...)
void php_error_docref2(const char *docref TSRMLS_DC, const char *param1, const char *param2, int type, const char *format, ...)

#define php_error_docref php_error_docref0

 php_error_docref0から2まで用意されていますが、実際によく使うと思われるphp_error_docref0だけは数字がつかない別名のphp_error_docrefが定義されており、通常はこちらを利用します。

 実際にエクステンション内では、以下のように利用します。

利用例
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "simple message");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "message format[%s]", "message arg");
php_error_docref1(NULL TSRMLS_CC, "arg1", E_NOTICE, "docref1 message");
php_error_docref2(NULL TSRMLS_CC, "arg1","arg2", E_USER_NOTICE, "docref2 message");

 第一引数に指定するdocrefはPHPのドキュメントへのリンクを表示するためのものですが、PHPのソース内でもあまり使われておらず、NULLを指定すれば問題ありません。

 また、指定できるログレベルはPHPのerror_reporing()関数の同様であり、それぞれのエラーレベルはPHPマニュアルのエラー処理での定義済み定数を参照してください。

例外を投げる

 エクステンションプログラム内で例外を投げることも可能です。エラーログとは異なり、例外はPHPのプログラムでコントロールすることができますので、より実行時にコントロールしたい場合に利用します。

 エクステンション内で例外を投げるには、以下の2つの関数を利用します。

zval * c(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...);

 2つの関数の違いは、エラーメッセージで"%s"などを使ったフォーマット形式が使えるかどうかですが、message変数と、code変数の引数の順番がかわっていますので、注意してください。以下にサンプルコードを示します。

例外を投げるためのコード
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "exception message", 100 TSRMLS_CC);

 zend_class_entryで例外クラスを指定するところで、zend_exception_get_default()関数を使えば、PHPでの標準例外クラスであるExceptionクラスになります。また、zend_class_entryをNULLで指定することも可能ですが、その場合もzend_exception_get_default()と同様になります。

独自の例外を投げる

 Exceptionクラスを継承した例外を投げる場合には、zend_class_entryを独自に作成し、それをzend_throw_exception()の引数に設定する必要があります。今までクラスを定義してきましたが、その手順とほとんど変わりません。(1)で独自のzend_class_entryを作成し、(2)で例外の関数を設定します。ただし、Exceptionクラスのメソッドを継承しますので、何も定義はありません。(3)のzend_register_internal_class_exでExceptionクラスを取得するzend_exception_get_default()関数を実行すれば、ErrchkExceptionクラスが定義できます。

独自例外クラス(errchk.cの抜粋)
zend_class_entry *ce_errchk_exception;  // ……(1)
// : (省略)
static zend_function_entry errchk_exception_methods[] = {  // ……(2)
        {NULL, NULL, NULL}
};
// : (省略)
PHP_MINIT_FUNCTION(errchk)
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "ErrchkException",errchk_exception_methods);
    ce_errchk_exception = zend_register_internal_class_ex(&ce,zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); // ……(3)
    return SUCCESS;
}

 あとは、通常の例外を投げる時と同様に、以下のようにしてユーザが定義した例外を投げます。

独自例外を投げる処理
zend_throw_exception_ex(ce_errchk_exception, 100 TSRMLS_CC, "errchk exception");

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2012年2月時点での登録メンバは37名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:PHPエクステンションの作り方

おすすめ記事

All contents copyright © 2006-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5