PHPでメモリ内のアーカイブを操作します(ディスクに一時ファイルを作成せずに)
質問
私はPHPでフライでアーカイブを生成し、すぐにユーザーに送信しようとしています(保存せずに)。とにかく、私が送信しているデータが永続的ではないため、ディスク上にファイルを作成する必要はないと考えましたが、Webを検索すると、その方法がわかりませんでした。ファイル形式も気にしません。
だから、質問は次のとおりです。
途中でtempfileを作成せずに、PHPスクリプト内のメモリ内のファイルアーカイブを作成および操作することは可能ですか?
解決
私は同じ問題を抱えていましたが、最終的にやや不明瞭な解決策を見つけて、ここで共有することにしました。
私は偉大なものを吸収しました zip.lib.php
/unzip.lib.php
付属のスクリプト phpmyadmin
「ライブラリ」ディレクトリにあります。
使用 zip.lib.php
私にとって魅力として働いていました:
require_once(LIBS_DIR . 'zip.lib.php');
...
//create the zip
$zip = new zipfile();
//add files to the zip, passing file contents, not actual files
$zip->addFile($file_content, $file_name);
...
//prepare the proper content type
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=my_archive.zip");
header("Content-Description: Files of an applicant");
//get the zip content and send it back to the browser
echo $zip->file();
このスクリプトを使用すると、ファイルを実際のファイルとして持つ必要なく、ZIP自体をファイルとして保存する必要なく、ZIPをダウンロードできます。
この機能がより一般的なPHPライブラリの一部ではないことは残念です。
これが次のリンクです zip.lib.php
phpmyadminからのファイル出典:https://github.com/phpmyadmin/phpmyadmin/blob/release_4_5_5_1/libraries/zip.lib.php
アップデート:Zip.lib.phpの最初から次のチェックを削除してください。
if (! defined('PHPMYADMIN')) {
exit;
}
アップデート:このコードは、CodeIgniterプロジェクトでも利用できます。https://github.com/patricksavalle/codeigniter/blob/439ac3a87a448ae6c2cbae0890c9f672efcae32d/system/helpers/zip_helper.php
他のヒント
アーカイブを生成するために何を使用していますか?ストリームphp:// tempまたはphp://メモリを使用して、アーカイブに読み書きできる場合があります。
Php:// Tempが閉じた場合を除き、Tempが機能するというコメントについては、開いたままにして出力を洗い流してから、0に戻して読んでください。
より多くの例については、こちらをご覧ください。 http://us.php.net/manual/en/function.tmpfile.php
また、出力バッファリングとキャプチャを調査します。 http://us.php.net/manual/en/function.ob-start.php
使用する必要があります ZipArchive::addFromString
- 使用する場合 addFile()
ファイルは実際には追加されません。 (恐ろしいバグIMHO、ZIPを閉じる前にファイルをzipに移動して削除しようとしている場合はどうなりますか...)
addFromString()
メソッドはすぐにアーカイブに追加します。
ここに本当にパフォーマンスの問題はありますか、それともあなたの正義の感覚を怒らせるだけですか?多くのプロセスが一時的なファイルを書き、それらを削除します。多くの場合、キャッシュのためにディスクを押すことはありません。
TempFileは、閉じたときに自動的に削除されます。それが自然です。
メモリでzipファイルを作成してそれを提供するために考えることができる方法は2つしかありません。
- RAMディスクを使用します。
- Ziparchiveクラスを変更して、close()メソッドが実行するすべてを実行するメソッドを追加します。 を除外する 実際にファイルを閉じます。 (または、close()にleave-openパラメーターを追加します)。
これは、基礎となるCライブラリによっても不可能かもしれません。