PHPで次のプログラムを作成してください。


配列を使ったユーザー定義関数を作成する時、
処理を行ってる配列要素をechoするというスクリプトを作成してください。
下記に配列とユーザー定義関数を用意していますが、
実際に使用する関数はもっとずっと複雑で大量です。

$u = array('a','b','c','d','e');
function xxxx($m){
foreach($m as $o){
$t .= $o;
}
return $t;
}
echo xxxx($u);

上記のスクリプトで
aの処理が終了した時点で、aをecho。
bの処理が終了した時点で、aのechoを消し、bをechoするということです。
現在、どの要素の処理をしているのか確認することを目的としています。
上記のスクリプトだと一瞬で終わってしまいますが、
意図を汲んで作成していただけると幸いです。

Vista,PHP5,XAMPP,Firefoxという環境でやっています。
以上、よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:2008/12/05 06:51:19
  • 終了:2008/12/05 21:43:59

回答(1件)

id:kn1967 No.1

kn1967回答回数2915ベストアンサー獲得回数3012008/12/05 09:08:51

ポイント100pt
// 関数宣言
function xxxx($m){
    foreach($m as $o){
        // 開始をecho
        echo "$o";
        // echoを即時反映するための処置(出力バッファから即時出力するように指示)
        ob_flush();
        flush();
        $t .= $o;
        // 処理しているつもりで1秒待つsleep
        sleep(1);
    }
    return $t;
}

// メイン処理
$u = array('a','b','c','d','e');
echo xxxx($u);

ループの中でechoを順次出力すれば良いのは理解しておられると思いますが

そこでのミソは

        ob_flush();
        flush();

という処置です。


phpやwebサーバなどは1文字単位で出力するのではなく

出力がある程度溜まるまで出力用バッファに貯めます。

それを強制的に吐き出させるのが上記の2行です。

上記の2行が在る場合と無い場合で実験してみれば目で確認できますよ。


なお、バッファの強制出力は、

今回のような要望や、時間がかかる処理のために

ブラウザ側が接続タイムアウトを返してしまう場合などに有効な手段ですが

出力するという手間な動作の回数を減らして負荷を下げ

高速化を図るというバッファの主旨に反する行為でもありますので

むやみやたらとは使わないようにしてください。


余談ですが、関数などは先に書くのが常道です。

(コンパイルが若干早くなるといったような事は

最近のコンピュータでは些細で微妙な話なのですが

自分でコードを見る際に、上から下に見ていけば済むので便利ですよ)

id:taroemon

いつも大変お世話になっています。


のぞみどおりうまくいきました。

また、丁寧な解説ありがとうございます。

実はバッファ関連はあまり理解できてなかったので、とても参考になりました。


>バッファの強制出力は、(中略)むやみやたらとは使わないようにしてください。

>余談ですが、関数などは先に書くのが常道です。

私は独学でPHPの勉強をしていますので、

こうしたことを教えていただけるのは本当に勉強になりますし、

またそれが励みにもなります。ありがとうございました。

2008/12/05 21:43:34
  • id:kn1967
    >aのechoを消し、bをechoする

    aを消すという処理はクライアント側(FireFox側)で行わせる必要があるので
    ajaxなどの仕組みを用いなければならずphpだけ(サーバー側だけ)では無理ですよ。
  • id:taroemon
    kn1967さん
    いつもありがとうございます。

    >ajaxなどの仕組みを用いなければならずphpだけ(サーバー側だけ)では無理ですよ。
    それは知らないで質問しました。すみません。

    では、aは消さずにa→ab→abcといった感じで増えていくのだとどうでしょう。
    要は現在どの要素の処理をしているかわかればどんな方法でもかまいません。
    回答者の方が良いようにアレンジしていただければ幸いです。

    以上、よろしくお願いします。
  • id:kn1967
    >aは消さずにa→ab→abcといった感じで増えていく

    それならば簡単な話・・・でもないのでサンプルと説明を書いてみました。
  • id:pahoo
    WebサーバとPHPの実装にもよるのですが、普通は、PHPの1つのスクリプトが完了してから、Webサーバの表示処理が始まります。この点は、Windowsアプリとは異なります。
    もし1つのPHPファイルのスクリプト実行状況をリアルタイムで表示させたいというご要望でしたら、ちょっと工夫が必要です。
  • id:kn1967
    >pahoo 2008-12-05 10:36:34
    >PHPファイルのスクリプト実行状況をリアルタイムで表示させたいというご要望でしたら、ちょっと工夫が必要です。

    私はバッファをフラッシュさせるという手法を回答させていただいたのですが
    フラッシュは強制的に吐き出させるだけの事であって
    実行状況のリアルタイム表示とは異なりますので、
    ちょっとの工夫でリアルタイム表示が出来るのであれば、
    私もポイント乗っかりさせていただきますので、ご回答願えればと思います。
  • id:taroemon
    pahooさん
    いつもお世話になってます。

    >もし1つのPHPファイルのスクリプト実行状況をリアルタイムで表示させたいというご要望でしたら、
    処理が完了した要素はどれかをざっと把握できればいいので、
    特にリアルタイムにこだわってるわけではありません。

    しかし、pahooさんのおっしゃる「ひと工夫」というのは今後の参考になると思います。
    もしお時間があれば、お教えください。
  • id:pahoo
    taroemon > もしお時間があれば、お教えください

    Webサーバを介さずに、PHPとクライアント(ブラウザ)の間に直接通信ソケットを張る方法があります。一種のP2P通信になるので、ブラウザ側にも受け口が必要になります。
    セキュリティ仕様の関係で Flash では実装できないと思いますが、Curl なら実装できると思います。
    他に面白い方法として、MSN Messenger経由でメッセージを流すというClassがあります。リアルタイム性については確認できていませんが、HTTPサーバを回避する経路としては、有用な方法の1つだと思います。

    ●MSN Messenger Class
    http://flumpcakes.co.uk/php/msn-messenger
  • id:kn1967
    ふむふむ・・・それらが「ちょっと工夫」で出来るようなものなのですか・・・。

    かなりハードル高いと思いますけどねぇ・・・。
  • id:taroemon
    pahooさん、kn1967さん
    再度のコメントありがとうございました。

    pahooさん
    いろんな方法があるものですね。とても参考になりました。
    お忙しいのにわざわざご回答いただき、恐縮です。

    kn1967さん
    >「かなりハードル高いと思いますけどねぇ・・・。」
    今の私にはそうかもしれませんね。
    これが活用できるようもっと勉強しますので、今後もお導きください。

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

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

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

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