スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Tag:スポンサー広告 

【PHP/C】PHP extension で 引数を受け取る

前回に引き続きPHP extensionに関する記事を書きます

前回はプログラミングの基本「Hello, World!の出力」でした

今回は作成した関数に引数を渡してみたいと思います

今回主に使う事柄として

zend_parse_parameters()
ZEND_NUM_ARGS()

の2つになります

【1】ZEND_NUM_ARGS()
まずはZEND_NUM_ARGS()から説明します

ひとことでこの関数の役割を表すなら

「引数の数を取得する関数」

と言えるでしょう

C言語でのプログラミング経験のあるかたでしたら

main(int argc, char *argv[])

みたいなことを書いてargcの値を利用してmain関数の引数の数を取得していたと思います

これとほとんど同じです

int argc;
argc = ZEND_NUM_ARGS();

と言う感じで使います

【2】zend_parse_parameters()
次にzend_parse_parameters()の使い方を簡単な実例を見ながら書いていきます

int argc;
char *input;
int input_len;
zend_bool case_bool;

argc = ZEND_NUM_ARGS();

zend_parse_parameters(argc TSRMLS_CC, "s", &input, &input_len)
zend_parse_parameters(argc TSRMLS_CC, "sb", &input, &input_len, &case_bool)
zend_parse_parameters(argc TSRMLS_CC, "s|b", &input, &input_len, &case_bool)

いきなり使用例みたいなのを書いてしまいましたが、コレを見てなんとなく直感的に使い方が分かった方もいるかもしれませんね

まず
(2-1)TSRM
TSRMについてですが、正直厳密に正確なことはまだ調査中です。ごめんなさい。

TSRM … Thread Safe Resourse Manager

どうやら変数をスレッドセーフにしてくれるみたいです。

スレッドセーフ…マルチスレッド環境で、ライブラリやプログラム、クラスなどが複数のスレッドから同時に利用されても正常に動作すること

PHPにおいてはソース内にTSRMディレクトリがあって、その中にAPIとして用意されているようです

(2-2)2つめの引数
なにやら"s"とか"sb"とか"s|b"とかが渡されていますね。

これは引数の型をあらわしています

s…string(文字列)
b…boolean(ブール値)

という対応になっています

ほかにはどんなものがあるのかというと
l…Long
d…double
r…resource
a…array
o…任意のobject
O…クラス名により識別されたobject
z…zval
があるらしいです

3つ目の例にある
"|"はパイプを意味し、付加的にに引数を渡すときに使う

例えば2つめの例であれば必ずstringとbooleanを関数に渡さなければダメ
3つめのように"|"というパイプでつながれていれば最悪なくても動かすことはできる

ほかには
"/"であった場合参照系でないならば値をコピーする
"!"であった場合nullが来た場合array, object, resource, zvalsに限りnullをセットする

といったものが用意されています。ここは詳しくあとで調べてみる必要がありそうです

(2-3)3つ目以降の引数
例えば"s"に対応するのは文字列(char *)、文字列の長さ(int)とあったり
"b"に対応するのはBoolean(zend_bool)であったり
"l"に対応するのはintだったりとここはそんなに迷わないかと思います

ただ今のところ"s"に関しては文字列(char *)、文字列の長さ(int)と渡さなければいけないということは一つ注意しておくべきですね

【3】extensionの実例
前置きがかなり長くなりましたが、前回の記事で書いた「Hello, World」関数を改造し第1引数に出力したい文字列を受け取り第2引数がtrueだったら第1引数で受け取った文字列を出力する関数を作ってみましょうちなみに第2引数がfalseだったら"hogehoge"と出力します

hello_world.cに
PHP_FUNCTION(hello_world){

    char *input = NULL;
    int argc = ZEND_NUM_ARGS();
    int input_len;
    zend_bool case_bool;

    if(zend_parse_parameters(argc TSRMLS_CC, "s|b", &input, &input_len, &case_bool) == FAILURE){
        return;
    }  

    if(case_bool == 1){
        printf("%s\n", input);
    }else{
        printf("hogehoge\n");
    }  

    return;
}

と書いて前回の記事の通りにbuildしてコピーしてもらえればOKです

test.php
<?php
hello_world("hello", true);
?>

php test.php
hello

となります
関連書籍:







Building Custom Php Extensions Building Custom Php Extensions
(2003/09/30)
Blake Schwendiman

商品詳細を見る
スポンサーサイト
テーマ : プログラミング
ジャンル : コンピュータ

Tag:PHP  Trackback:0 comment:0 

Comment

comment form
(編集・削除用):
管理者にだけ表示を許可
プロフィール

6rats

Author:6rats
こんにちは、ITベンチャーで働くエンジニアです
主に自分の周りで起きた技術的なことをメモとして書き残して行きます。
Android以外にもRuby/Ruby on RailsやFuelPHPなどなどたまにやります。基本的なスタンスとしては興味があるもしくは必要になったらいろんなことにチャレンジします。
最近はiOSアプリ開発を始めています。

購読
follow us in feedly
個人プロダクト

Androidアプリ

Twitterクライアント

Webアプリケーション

EcPriceWatch(Amazon価格の推移を計測、最安値を知らせるサービス)
Google AdSense
ブログ村
にほんブログ村 IT技術ブログへ
にほんブログ村
ブロとも申請フォーム

この人とブロともになる

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。