質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

3838閲覧

header()関数でリダイレクトする前にスクリプトの途中経過の文字列を表示させたい

nyaan

総合スコア11

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/04/14 14:56

前提・実現したいこと

とある掲示板のスクレイピングツールを製作中です。
スクリプト実行中に現在読み込んでいるページ数を表示するためにfor文の中でechoを実行しています。
for文が終了した後にページ更新によるフォームの再送信を防ぐためにheader()関数でリダイレクト処理をかけているのですが先のechoによってエラーが発生してしまいます。

header()関数でリダイレクト処理をする前のfor文の中でロード画面のような文字列を表示させることはできないのでしょうか。
ご教授よろしくお願いいたします。

発生している問題・エラーメッセージ

Warning: Cannot modify header information – headers already sent by (output started at …

該当のソースコード

php

1<?php 2if(!empty($_POST['action'])){ 3 4 $maxPage = 100;//読み込むページが100ページの場合 5 6 for($i = 0;$i <= $maxPage;$i++){ 7 /*スクレイピングのスクリプトは省略します*/ 8 $countDown = $maxPage - $i; 9 $countDownEcho = "あと".$countDown."ページ"; 10 echo $countDownEcho;//ここで現在処理中のページ数を表示させたい 11 } 12 13 header('Location:#');//フォームの再送信を防ぐためにリダイレクトしたい 14 exit(); 15 16} 17?> 18 19<html> 20<head> 21</head> 22<body> 23 <form action="" method="post"> 24 <input type="submit" name="action" value="スクリプトを実行する"> 25 </form> 26</body> 27</html>

試したこと

セッションに一時的に値を与えてリロードした場合リダイレクトするような事もやってみたのですが以下のコードだとリロードではなくフォームから正常にポストした場合でもリダイレクトされてしまいました。
なにかいい方法はないでしょうか。

php

1<?php 2session_start(); 3 4if(isset($_SESSION['hoge'])){ 5 session_unset($_SESSION['hoge']); 6 header('Location:#'); 7 exit(); 8} 9 10if(!empty($_POST['action'])){ 11 12 $maxPage = 100;//読み込むページが100ページの場合 13 14 for($i = 0;$i <= $maxPage;$i++){ 15 /*スクレイピングのスクリプトは省略します*/ 16 $countDown = $maxPage - $i; 17 $countDownEcho = "あと".$countDown."ページ"; 18 echo $countDownEcho;//ここで現在処理中のページ数を表示させたい 19 } 20 $_SESSION['hoge'] = "hoge"; 21} 22?>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

header関数でできないのは既存の回答の通りです。これは原理的にできません。
ですが、header関数以外の方法、たとえばJavaScriptによる遷移であれば、表示を出すことも可能です。

しかし、まだ問題があります。

ウェブの表示というものは処理が終わった後でないとできないのです。処理途中の表示は、絶対にできないわけでもないようですが、難易度が高いです。

そこで、A→B という遷移をするとして

A: 「処理中」と表示してから JavaScript でBに遷移
B: 処理をする

という流れでどうでしょうか? PoC(概念実証コード)を簡単に書いてみました。

PHP

1<!-- A.php --> 2<body>処理中 3<script> 4window.location = 'B.php'; // B.phpに遷移 5</script> 6</body>

PHP

1<?php // B.php 2 sleep(3); // 時間がかかる処理の代わり 3?><body> 4処理しました 5</body>

投稿2019/04/15 10:11

ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyaan

2019/04/15 13:33

ありがとうございます。 サーバーサイド側だけでなんとかしたかたったのですが根本的な考え方を変えてご教示頂いた代案も試させていただきます。
guest

0

header()
覚えておいて頂きたいのは、header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要があることです

phpはどんなにechoを書いてもプログラムを全て終えてから一気に出力する(画面が出力を受け取る)ので、
途中でechoしても想定通りには動かないと思いますし、httpヘッダー送信することでそのプログラムやページをどのように扱うかが決まるので、扱いが決まらないのに出力してはいけません。

多重送信を防ぐやり方は調べれば幾らでも出てきますので、調べて試してみてください。

投稿2019/04/14 20:49

m.ts10806

総合スコア80731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyaan

2019/04/15 13:32

ありがとうございます。 基本的に1つのページでスクリプト処理中の表示+リロード対策は難しいということがわかりました。 header()関数でのリダイレクトは諦めてSESSIONを用いた確認ページ等への画面遷移でなんとかできないか試してみます。
guest

0

header()関数でリダイレクト処理をする前のfor文の中でロード画面のような文字列を表示させることはできないのでしょうか。

できません。

エラーメッセージに書かれている通りです。

投稿2019/04/14 15:49

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyaan

2019/04/15 13:28

ありがとうございます。代替案を考えたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問