<?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
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"; } ?>
この結果は、_ _ _ | _ _ _ | _ _ _ | _ となり、たぶん期待通りの結果だと思います。
丁寧にありがとうございました。理解できました。
「tickとはdeclareブロックの実行中にパーサが N個の低レベル命令を実行するごとに 発生するイベント」と説明されています。
http://jp.php.net/manual/ja/control-structures.declare.php#contr...
推論ですが、以下のように考えるとうまく説明できます。
for文で10回プリントするという処理は、低レベル命令として、プリント、カウンタのチェック、ループを終了するという3つの処理があると考えられます。プリント処理をP、チェック処理をC、終了処理をEとすると、その実行過程は21tickとなり、次のように表現できます。
PCPCPCPCPCPCPCPCPCPCE
そして、register_tick_functionで指定された関数内のプリント処理をTとすると、3tick毎に実行されるので、次のように表現できます。
PCPTCPCTPCPTCPCTPCPTCPCTPCET
ここで、画面に表示されない処理であるCとEを取り除き、さらに、Pを_、Tを|で置き換えると
__|_|__|_|__|_|_|
これを縦に並べると、ご質問パターンになります。
>そもそもdeclareの意味がよくわかりません
これについては、コメントにて回答します。
よくわかりました。
丁寧にありがとうございました。理解できました。