青木ITプランニング
PHP、Smarty、ケータイサイトについて発信中。書籍 「Smarty動的webサイト構築入門」(技術評論社) 好評発売中
-
処理時間が長いとき、すばやくページ表示したい(4)
フォーム送信後、サーバ側の処理時間が長いとき、なかなか画面が変わらないことがあります。サーバ側の処理時間が長いときでも、すばやくページを表示するいくつかの方法について説明します。
(4) 難しい方法 (プログレスバーを表示する)
今回は、10000回のループ処理で時間がかかっている場合に、ループ処理を複数のリクエストに分けます。データベースのクエリー1回で時間がかかっている場合には、今回の方法は使えません。
人が10000件の一覧を見るときに例えると、10000件を1ページで見るのが、前回までの方法。100件づつ100ページに分けて、次へ次へで見ていくのが、今回の方法です。
ページ遷移は form.html ⇒ task.php ⇒ thanks.html となります。ただし、task.phpは、1回だけではなく、task.php ⇒ task.php?rcd_pos=0 ⇒ task.php?rcd_pos=200 と何回も呼ばれます。
次の例は、0.01秒 x 10000件の処理です。約2秒おきに進捗状況を表示します。
いろいろな実装方法があります。今回の実装では、セッション変数を使いました。クエリー変数 $_GET['rcd_pos']はループ処理には利用していません。また、100回づつで分けるのではなく、2秒ごとに分けました。
<?php /* * task.php?rcd_pos=123 */ define( 'MAX_PROCESS_SEC', 2 ); session_start(); if ( ! isset($_GET['rcd_pos']) ) { $_SESSION['rcd_cnt'] = 10000; $_SESSION['rcd_pos'] = 0; $_SESSION['time_st'] = time(); } else { $t0 = time(); for ( ; $_SESSION['rcd_pos'] < $_SESSION['rcd_cnt']; ++$_SESSION['rcd_pos'] ) { if ( MAX_PROCESS_SEC <= time() - $t0 ) { break; } usleep( 10000 ); // 0.01秒 } } if ( $_SESSION['rcd_cnt'] <= $_SESSION['rcd_pos'] ) { $url = "thanks.html"; } else { $url = "task.php?rcd_pos=" . $_SESSION['rcd_pos']; } $tpl['rcd_cnt'] = $_SESSION['rcd_cnt']; $tpl['rcd_pos'] = $_SESSION['rcd_pos']; $tpl['elapsed_sec'] = time() - $_SESSION['time_st']; $tpl['percent'] = floor(100 * $_SESSION['rcd_pos'] / $_SESSION['rcd_cnt']); ?> <html> <head> <meta http-equiv="refresh" content="0; url=<?php echo $url?>" /> <style> .frame { border: 1px solid #000; width: 400px; height: 50px; } .progress { width: <?php echo $tpl['percent'] ?>%; height: 50px; background: #00f; } </style> </head> <body> 処理中です<br /> 全件数 : <?php echo $tpl['rcd_cnt'] ?><br /> 処理済み: <?php echo $tpl['rcd_pos'] ?><br /> 経過時間: <?php echo $tpl['elapsed_sec'] ?>sec<br /> <div class="frame"> <div class="progress"> <br /> </div> </div>ブラウザがリクエストしなければ、次の処理へ進まないので、途中停止が簡単です。サーバ側にキャンセルという仕組みを用意する必要がありません。ブラウザの[中止]ボタン、[閉じる]ボタン、キャンセルページへのリンク、どれでも途中停止します。
Leave a reply




最近のコメント