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

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

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

解決済

PHPでzipファイルのダウンロードがうまくできません(文字化けがブラウザ上で表示される)

takasworld
takasworld

総合スコア10

3回答

0評価

0クリップ

928閲覧

投稿2021/12/27 02:06

編集2022/01/26 06:48

前提・実現したいこと

ダウンロードボタンを押すとzipファイルを作成してダウンロード出来るようにしたいです。

下記のコードだとzipファイル作成までは出来たのですが、その後にダウンロードが始まることはなくブラウザ上にzipの中身が文字化けして表示されるだけで何も動作しません。作成できたzipファイルを直接ダウンロードして解凍してみたのですが問題なく解凍できました。なのでダウンロード周りのコードが間違っているのかもしれません。

該当のソースコード

php

<?php $test_file = __DIR__ . '/../../../uploads/txt/test.txt'; if (isset($_POST['downloadbutton'])) { $zip = new ZipArchive(); $zipFileName = get_the_ID() . '.zip'; $zipTmpDir = __DIR__ . '/../../../uploads/zip/'; $result = $zip->open($zipTmpDir.$zipFileName, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE); if ($result === true) { set_time_limit(0); $zip->addFile($test_file, 'test.txt'); $zip->close(); header('Content-type: application/zip'); header('X-Content-Type-Options: nosniff'); header('Content-Length: '.filesize($zipTmpDir.$zipFileName)); header('Content-Disposition: attachment; filename="'.$zipFileName.'"'); header('Connection: close'); while (ob_get_level()) { ob_end_clean(); } readfile($zipTmpDir.$zipFileName); } unlink($zipTmpDir.$zipFileName); exit; } ?> <form id="testdl" method="post"> <button id="button" type="submit" name="downloadbutton"><p>Download</p></button> </form>

php.iniに下記を追加することで文字化けがブラウザに表示されなくなり、ダウンロード出来るようになりました。ただこの方法が正しいのか、もしくはただエラーがあるのに無理やりダウンロード出来るようにしているのか分かりません。

php.ini

output_buffering = on

参考にしたサイト: PHP:Warning: Cannot modify header information - headers already sent by ...の解決策

試したことと結果

  • いくつかのサイトを参考にしたのでいらないものを足してしまったか、もしくは引いてしまったのかと思いダウンロード周りのコードを何度も修正したのですが別のエラー(Cannot modify header information - headers already sent)が表示され結局解決できませんでした。

  • while (ob_get_level()) { ob_end_clean(); } を ob_end_clean(); に変更しました。文字化けが表示されるようになりました→  PK 8b�Stest.txtPK? 8b�S��test.txtPK6&

  • 上記のコードを別のphpファイルに移しfunctionにして元のファイルからincludeで呼んだんですが同じ文字化けが表示されました。

  • mb_output_handler("pass"); と mb_http_output("pass"); をコメントアウトしてみましたが同じ文字化けが表示されました。

  • header('Content-Type: application/zip; name="' . $zipFileName . '"'); をコメントアウトしてheader('Content-type: application/zip'); を追加してみましたが同じ文字化けが表示されました。

  • サーバーのファイルパーミッションを確認したんですがダウンロード出来ない原因は見つかりませんでした。

  • 私と同じようにzipの中身が文字化けしてブラウザに表示されてダウンロード出来ない方の解決済みの投稿を見つけたんですが(https://teratail.com/questions/279532)その方はCakePHPを使用されているみたいで、その解決策のコードを追加してもエラーが出るだけでした。

追加したコード→ Configure::write('debug', 0);

  • unlink($zipTmpDir.$zipFileName); をコメントアウトし作成されたzipファイルを削除せず、そのzipファイルをhtmlコード <a href="test.zip" download>download test</a> でダウンロードしてみたんですが、それは問題なくダウンロードも解凍もできました。

  • header('X-Content-Type-Options: nosniff'); を追加しました。

  • php.ini に output_buffering = on を追加しました。

  • ob_end_clean(); を再び while (ob_get_level()) { ob_end_clean(); } に戻したらダウンロードも解凍もできました。ただiphoneのchromeからだとダウンロードはできても解凍ができません。

補足情報(FW/ツールのバージョンなど)

phpのバージョン: 7.4.25

phpのzipのバージョン
Zip enabled
Zip version 1.15.6
Libzip headers version 1.3.2
Libzip library version 1.3.2

使用しているサーバー: Conoha Wing

使用しているEditer: Visual Studio Code

Wordpressでサイトを作っています

よろしくお願いいたします。

良い質問の評価を上げる

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

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

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

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

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

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

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

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

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

AsukaKobayashi

2022/01/07 05:32

1/7時点で質問に記載のコードを、 WordPress環境ではない、さくらサーバーにて動かしてみたところ問題なく動作しました。 ($test_file $zipFileName $zipTmpDir の3か所は適宜変更してテストしています) > 作成できたzipファイルを直接ダウンロードして解凍してみた とのことですが、 `unlink($zipTmpDir.$zipFileName);` の行を消した状態で Download ボタンをクリックし、その後 https://example.com/uploads/zip/hoge.zip というような形で、「作成できたzipファイル」のURLに直接アクセスしたときは 文字化けは発生せず、ファイルのダウンロードができるということでしょうか?
takasworld

2022/01/07 05:54

AsukaKobayashiさん テストしていただき有難うございます! 同じコードで問題なく動作したということはコード以外のサーバーか何かの設定のところで問題があるのかもしれませんね...。 「直接ダウンロード」というのは unlink($zipTmpDir.$zipFileName); の部分を一度コメントアウトしてその後にダウンロードボタンをクリックし、Conoha Wingが用意してあるファイルマネージャーで直接上記のコードで指定したサーバー上のフォルダを開き、zipファイルをそのファイルマネージャーからダウンロードしました。 一応その後にphpコードで作成されたzipファイルをHTMLコードだけで <a href="test.zip" download>download test</a> と記述してダウンロードしてみたんですが、それは問題なくダウンロードも解凍もできました。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

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