<?php
function mytick() {
print "|";
}
register_tick_function("mytick");
declare(ticks=3) {
for ($i=0; $i < 10; $i++) {
print "_\n";
}
}
これを実行すると
_
_
|_
|_
_
|_
|_
_
|_
|_
|
と表示されるんですが、そもそもdeclareの意味がよくわかりません。
3つの文が実行されるたびに自動的にmytickを呼び出すらしいのですが、それだと
_
_
|_
_
_
|_
_
_
|_
_
_
こうだと思うのですが。
tickとはdeclareブロックの実行中にパーサが N個の低レベル命令を実行するごとに 発生するイベントのことです。Nの値は declareブロックの命令の箇所で ticks=Nのように 指定します。
ここでいう低レベル命令というのが何を指すかのかのドキュメントは無く、非常にわかりにくいのですが $i++ もその低レベル命令に含まれてカウントされているようです。
なので、上記プログラムは以下のように動いていることになります。
print "_\n"; //カウンタは1 $i++ //カウンタは2 print "_\n"; //カウンタが3になったのでmytickを呼ぶ。カウンタは0に戻る print "|"; //declare外なのでカウンタは上がらない $i++ //カウンタは1 print "_\n"; //カウンタは2 $i++ //カウンタが3になったのでmytickを呼ぶ。カウンタは0に戻る print "|"; //declare外なのでカウンタは上がらない print "_\n"; //カウンタは1 $i++ //カウンタは2 print "_\n"; //カウンタが3になったのでmytickを呼ぶ。カウンタは0に戻る print "|"; //declare外なのでカウンタは上がらない $i++ //カウンタは1 print "_\n"; //カウンタは2 $i++ //カウンタが3になったのでmytickを呼ぶ。カウンタは0に戻る print "|"; //declare外なのでカウンタは上がらない print "_\n"; //カウンタは1 $i++ //カウンタは2 print "_\n"; //カウンタが3になったのでmytickを呼ぶ。カウンタは0に戻る print "|"; //declare外なのでカウンタは上がらない $i++ //カウンタは1 print "_\n"; //カウンタは2 $i++ //カウンタが3になったのでmytickを呼ぶ。カウンタは0に戻る print "|"; //declare外なのでカウンタは上がらない $i++ //カウンタは1
その結果、_ _ | _ | _ _ | _ | _ _ | _ | _ | となりますが、これは正しい動作と言えそうです。
試しに$i++を発生させないようにforループを無くして以下のようにしてみます。
<?php function mytick() { print "|"; } register_tick_function("mytick"); declare(ticks=3) { print "_\n"; print "_\n"; print "_\n"; print "_\n"; print "_\n"; print "_\n"; print "_\n"; print "_\n"; print "_\n"; print "_\n"; } ?>
この結果は、_ _ _ | _ _ _ | _ _ _ | _ となり、たぶん期待通りの結果だと思います。
PHPのマニュアル(http://php.mirror.camelnetwork.com/manual/ja/control-structures....)から抜粋
tickとはdeclareブロックの実行中にパーサが N個の低レベル命令を実行するごとに 発生するイベントのことです。Nの値は declareブロックの命令の箇所で ticks=Nのように 指定します。
低レベル命令を実行するごとにとあるので、単純に文単位というわけではないようです。
参考URL
の回答は、コメントで書くと書いたので、書きます。
(単にマニュアルを読んで私なりに理解したことです。)
http://jp.php.net/manual/ja/control-structures.declare.php
「declareブロックの挙動を指定することが出来ます」とあります。
declare{}の中(declareブロック)内のプログラムの実行過程で何かをすることができるということでしょう。何ができるかは、引数によって決まるとのことです。現在は、まだ、ticks命令を実行することしかできないとのこと。
ticks命令は、register_tick_functionで指定した関数の処理を、本体のプログラムの実行に応じて一定のタイミングで繰り返し割り込ませる命令です。
では、どのようなときに使用するのかですが、「ticksはデバッグ、単純なマルチタスク処理、バックグラウンドI/Oや その他多くの処理を実装するのに便利です。 」とあります。
重い処理の原因を探るときなど、すべての命令文の後にデバッグ用のプリント文を書いたりするのは大変なので、このdeclareとticks命令が使えそうですね。あとは、割り込み処理ができるので、マルチタスク、バックグラウンド処理などが実現できるということでしょう。
×「21tick」→○「21個の低レベル命令」
×「3tick」→○「3個の低レベル命令」
低レベル命令1つ毎に、縦棒(|)がプリントされます。
次のように表示されました。(改行を削除しました)
_ ||_ ||_ ||_ ||_ ||_ ||_ ||_ ||_ ||_ ||||
縦棒(|)が22本表示されましたので、
低レベル命令は、22回だということになります。
おそらく、ループ終了処理が2個の低レベル命令で構成されていると思われます。