SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

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

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

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

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

 本連載では、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");

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
CMakeを使ってビルドをする

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
PHPエクステンションの作り方連載記事一覧

もっと読む

この記事の著者

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

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7690 2014/04/04 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング