phpのdeclare文


<?php

function mytick() {
 print "|";
}

register_tick_function("mytick");

declare(ticks=3) {
 for ($i=0; $i < 10; $i++) {
  print "_\n";
 }
}

これを実行すると
_
_
|_
|_
_
|_
|_
_
|_
|_
|
と表示されるんですが、そもそもdeclareの意味がよくわかりません。
3つの文が実行されるたびに自動的にmytickを呼び出すらしいのですが、それだと
_
_
|_
_
_
|_
_
_
|_
_
_
こうだと思うのですが。

回答の条件
  • 1人2回まで
  • 登録:2007/12/27 15:18:42
  • 終了:2007/12/28 03:04:16

ベストアンサー

id:y-kawaz No.2

y-kawaz回答回数1421ベストアンサー獲得回数2262007/12/27 17:41:30

ポイント30pt

PHP: declare - Manual

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";
}
?>

この結果は、_ _ _ | _ _ _ | _ _ _ | _ となり、たぶん期待通りの結果だと思います。

id:nagiwind

丁寧にありがとうございました。理解できました。

2007/12/28 03:02:46

その他の回答(2件)

id:blueberrystream No.1

KID the Euforia回答回数34ベストアンサー獲得回数52007/12/27 17:21:44

ポイント20pt

PHPのマニュアル(http://php.mirror.camelnetwork.com/manual/ja/control-structures....)から抜粋

tickとはdeclareブロックの実行中にパーサが N個の低レベル命令を実行するごとに 発生するイベントのことです。Nの値は declareブロックの命令の箇所で ticks=Nのように 指定します。

低レベル命令を実行するごとにとあるので、単純に文単位というわけではないようです。


参考URL

id:y-kawaz No.2

y-kawaz回答回数1421ベストアンサー獲得回数2262007/12/27 17:41:30ここでベストアンサー

ポイント30pt

PHP: declare - Manual

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";
}
?>

この結果は、_ _ _ | _ _ _ | _ _ _ | _ となり、たぶん期待通りの結果だと思います。

id:nagiwind

丁寧にありがとうございました。理解できました。

2007/12/28 03:02:46
id:nandedarou No.3

nandedarou回答回数230ベストアンサー獲得回数342007/12/27 17:44:29

ポイント30pt

「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の意味がよくわかりません

これについては、コメントにて回答します。

id:nagiwind

よくわかりました。

2007/12/28 03:02:42
  • id:nandedarou
    >そもそもdeclareの意味がよくわかりません
    の回答は、コメントで書くと書いたので、書きます。
    (単にマニュアルを読んで私なりに理解したことです。)

    http://jp.php.net/manual/ja/control-structures.declare.php
    「declareブロックの挙動を指定することが出来ます」とあります。

    declare{}の中(declareブロック)内のプログラムの実行過程で何かをすることができるということでしょう。何ができるかは、引数によって決まるとのことです。現在は、まだ、ticks命令を実行することしかできないとのこと。

    ticks命令は、register_tick_functionで指定した関数の処理を、本体のプログラムの実行に応じて一定のタイミングで繰り返し割り込ませる命令です。

    では、どのようなときに使用するのかですが、「ticksはデバッグ、単純なマルチタスク処理、バックグラウンドI/Oや その他多くの処理を実装するのに便利です。 」とあります。

    重い処理の原因を探るときなど、すべての命令文の後にデバッグ用のプリント文を書いたりするのは大変なので、このdeclareとticks命令が使えそうですね。あとは、割り込み処理ができるので、マルチタスク、バックグラウンド処理などが実現できるということでしょう。
  • id:nandedarou
    私の回答の一部を次のように訂正します。
    ×「21tick」→○「21個の低レベル命令」
    ×「3tick」→○「3個の低レベル命令」
  • id:nagiwind
    ありがとうございました。
  • id:nandedarou
    質問文にあるプログラムで、ticks=3をticks=1にすると、
    低レベル命令1つ毎に、縦棒(|)がプリントされます。
    次のように表示されました。(改行を削除しました)
    _ ||_ ||_ ||_ ||_ ||_ ||_ ||_ ||_ ||_ ||||
    縦棒(|)が22本表示されましたので、
    低レベル命令は、22回だということになります。
    おそらく、ループ終了処理が2個の低レベル命令で構成されていると思われます。

この質問への反応(ブックマークコメント)

トラックバック

  • プログラミングPHP 第2版を読んだ 気になったところをメモ。 スタティック変数 関数が終了しても破棄されない。関数内でしか使用できない。 &lt;?php function counter () { static $count = 0; return ++$co
「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません