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

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

ただいまの
回答率

89.65%

ファイルのダウンロード後に別URLへリダイレクト

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,241

mokemoke

score 40

ファイルのダウンロードを行った後、別のURLへリダイレクトさせる為、
以下の様なコードで組みましたが、ダウンロードは出来た物の別URLに
リダイレクトされません。
ちなみに、リダイレクトの部分を追加したところ、ダウンロードされた
ファイルが上手く開かなくなりましたので、記述したコードでは出来ない
のかもしれませんが・・・
コード上、何か漏れている部分が御座いましたら、アドバイス願います。

<?php
  ini_set('display_errors', 1);
  error_reporting(E_ALL | E_STRICT);

  // PhpSpreadsheet読み込み
  require_once 'c:\windows\system32\vendor\autoload.php';

  // 読み込みオブジェクト指定
  $reader = new PhpOffice\PhpSpreadsheet\Reader\Xlsx();
  $reader->setIncludeCharts(TRUE);

  // テンプレート読み込み
  $book = $reader->load('nippou_template.xlsx');

  // エクセルファイルをダウンロードする
  //header("Content-Description: File Transfer");
  //header('Content-Disposition: attachment; filename="test.xlsx"');
  //header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  //header('Content-Transfer-Encoding: binary');
  //header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  //header('Expires: 0');
  //ob_end_clean(); //バッファ消去
  //$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($book);
  //$writer->save('php://output');

  // 別URLへリダイレクト
  $next_url = "nippo_sentaku.php";
  header("Location: {$next_url}");
?>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

1回のhttp要求でダウンロードとリダイレクトは同時にできません。どちらか片方です。
つまり、PHP側だけでなんとかするのは無理です。

php側はダウンロードだけにしておき、
クライアント側のjavascript等で、ダウンロードが完了した後に
ページ遷移させるなどの実装が楽だと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/05 18:48

    taka-saanさん、こんにちは。

    アドバイス頂き、ありがとうございます。
    やはり同時では出来ないのですね。
    とりあえずjavascriptで遷移させるべく、以下のコードに書き換えてみましたが、
    画面が遷移せず、ダウンロード後のファイルも上手く開けない状況です。
    組み込み方に問題があるかと思いますが、とにかくPHP初経験なので、
    良くわからない状況です。
    引き続きアドバイス等ございましたら、お願い致します。

    ```php
    // 別URLへリダイレクト
    $next_url = "nippo_sentaku.php";
    $src = '<script type="text/javascript">';
    $src .= 'document.location.assign(';
    $sqc .= $next_url;
    $sqc .= ');';
    $src .= '</script>';
    echo $src;
    ```

    キャンセル

checkベストアンサー

+1

headerで宣言するとその処理中はすべてそのモードになります。
つまりダウンロード(attachment)で宣言すると、そのあとのすべての出力はダウンロードファイルの一部として含まれてしまうことになります。
もしExcelをダウンロードしようとしているとしたら、そのあとにhtmlが書かれていたらExcelとしては正しくないファイル=破損ファイルとしてなってしまう可能性が高いです(良くてExcelの中にそのhtmlが書き込まれる)
header宣言のあとは「これ以上処理・出力なし」ということでexit();を置くこともよくあります。(少なくとも私がみてきた中では)

一応、javascriptでダウンロード終了を検知するという記事があるので1つ試してください。
他には、ダウンロード処理の最後にファイルを削除するように書いておき、非同期(JavaScript)でPHPを実行し、ファイルの存在をチェックし、なくなっていたら削除された→リダイレクト というのも考えられなくはないですが、ダウンロードしたいファイルをどのように作っているかにもよるので、ダウンロードファイルそのものよりもダミー用のファイルのほうが作りとしては現実的かもしれません。

ただ、今回の質問内容は非常にスポットでの質問(大きな流れの中での一部分のみ)ですので、もう少し全体の流れを要件として追記いただけると、代替案が提案できるかもしれません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/06 10:42

    mts10806さん、こんにちは。

    アドバイスありがとうございます。
    とりあえず「javascriptでダウンロード終了を検知する」の記事内容を試してみたいと思います。

    それから全体の流れについてですが、処理としては清掃作業の日報データを登録し、登録された
    データをお客様単位で抽出し、作業日別、月別、総計の3種類のエクセルを作成し、ダウンロード
    する流れになります。

    最初の画面でお客様を選択し、次の画面で作業日を指定し、作業内容(コード分けされている)と
    作業時間を入力して、データベースに登録します。

    こちらで作成しているエクセルを生成してダウンロードする処理(画面なし)については、
    お客様を選択する画面と作業時間を登録する画面の2か所から呼び出され、お客様選択の
    画面から呼び出された場合は、そのお客様の全件を抽出し、日毎にシート分けした日報、
    月毎にシート分けした月報、総計のシートにデータをセットし、1つのブックにまとめて
    ダウンロードさせ、作業時間登録の画面から呼び出された場合は、そのお客様のその日の
    データを抽出し、日報シートにセットしてダウンロードさせます。
    エクセルの操作についてはPhpSpreadsheetを利用し、日報・月報・総計のシートを含む
    テンプレートのエクセルファイルを読み込み、データをセットしております。
    ダウンロードについては、HTTPヘッダを用いて、PhpSpreadsheetで作成したシートを
    ブラウザに出力させる事で実現しております。

    全体の流れをの中で、何かアドバイスが御座いましたら、引き続きお願い致します。

    キャンセル

  • 2018/09/06 22:41

    確認と返信遅れました。
    特に問題はなさそうですが下記が気になります。
    「ダウンロードについては、HTTPヘッダを用いて、PhpSpreadsheetで作成したシートを
    ブラウザに出力させる事で実現しております。」
    私が知らないだけかもしれませんが、Excelのシートをそのままブラウザ出力ってヘッダにそのようなものありましたっけ・・?結局ダウンロードになるような気がします(xlsファイルリンクに直接貼った場合ダウンロードになりますよね)

    いずれにしてもブラウザで表示した時点でhtmlもクライアント側でダウンロードされた情報(キャッシュと言ったほうがいいか)を表示しているので、既に書いたように多重ダウンロードのような形になると思います。

    キャンセル

  • 2018/09/07 11:08

    mts10806さん、こんにちは。

    アドバイスありがとうございます。
    とりあえずダウンロード側の処理でリダイレクトを意識しなくても良いとの話が
    ありましたので、クローズと致します。
    また何かありましたら、よろしくお願い致します。

    キャンセル

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

  • ただいまの回答率 89.65%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る