2

ユーザーがサーバー上のすべてのファイルのzipファイルとデータベースダンプをダウンロードできるようにする、比較的小さなWebアプリケーション用のオンデマンドバックアップシステムを統合しようとしています。zip ファイルは、サーバー上の一時ディレクトリに全体としてパッケージ化されるのではなく、ユーザーにストリーミングされます。

これを実現するために、ZipStream と呼ばれるサードパーティの PHP クラスを使用しています。クラスはここでホストされ、特定のクラス ファイルはここで表示できます。ディレクトリを含めることをサポートしているため、このバージョンを選択しました(別の古いバージョンがあります)。shell_exec()また、セットアップは、またはを介し​​てシェル コマンドにアクセスできないサーバーでも機能するはずpassthru()です。

私の簡単なテスト セットアップは機能しておりunzip、コンソールからコマンドを使用するか、The Unarchiver.app. ただし、OS X のアーカイブ ユーティリティ (Mac OS X 10.6 およびそれ以前のバージョンとそれ以降のバージョンの可能性が非常に高い) は、次のエラーでアーカイブの抽出に失敗するため、問題を引き起こしています。

Unable to unarchive "test.zip" into "test". (Error 1 - Operation not permitted.)

ログに記録された実際のエラーは次のとおりです。

ditto: Couldn't read pkzip signature.

この問題に関する考えられる説明をいくつか見つけました。StackOverflow のこちらこちらで、ZipStream クラスにパッチを適用して Zip 仕様に準拠させ、アーカイブ ユーティリティが期待どおりにアーカイブを展開できるようにしたいと考えています。

ATTR_VERSION_TO_EXTRACTZipStream クラスの「抽出に必要なバージョン」(定数に格納されている) は: ですが、その表記が前述の質問で言及されてx0Ax00いる標準と異なるかどうかはわかりません。0x000A

問題は、zip ファイルに追加されたディレクトリに関連しているようです。テキスト ファイルのみを含む zip ファイルでは、アーカイブ ユーティリティを使用しても問題は発生しません。

これは PHP の領域の周辺に沿って移動するため、正しい 16 進文字列を使用してスクリプトを編集する方法や、この特定のスクリプトに Zend ソリューションを適切に適用する方法がわかりません。

生成された zip をここにアップロードしました: http://dl.dropbox.com/u/6887873/test.zip

生成するコードは、サンプル コードの縮小版です。

$extime = ini_get('max_execution_time');
ini_set('max_execution_time', 600);

include_once("ZipStream.php");

$fileTime = date("D, d M Y H:i:s T");

$chapter1 = "Chapter 1\n"
. "Lorem ipsum\n"
. "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec magna lorem, mattis sit amet porta vitae, consectetur ut eros. Nullam id mattis lacus. In eget neque magna, congue imperdiet nulla. Aenean erat lacus, imperdiet a adipiscing non, dignissim eget felis. Nulla facilisi. Vivamus sit amet lorem eget mauris dictum pharetra. In mauris nulla, placerat a accumsan ac, mollis sit amet ligula. Donec eget facilisis dui. Cras elit quam, imperdiet at malesuada vitae, luctus id orci. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque eu libero in leo ultrices tristique. Etiam quis ornare massa. Donec in velit leo. Sed eu ante tortor.\n";

$zip = new ZipStream("test.zip");

$zip->addFile("Hello World!\r\n", "Hello.txt");

$zip->addDirectory("files/");
$zip->addDirectoryContent("../images", "files/testing/");

$zip->finalize();

編集:

問題をもう少し絞り込んだと思います。16進文字列が実際に違いを生むようには見えません。テキスト ファイルのみを含む生成された zip は、アーカイブ ユーティリティを使用してエラーなく展開されるため、ディレクトリを追加するとき、特にZipStream クラスをaddDirectoryContent()呼び出す を呼び出すときに破損が発生するようです。addLargeFile()ディレクトリが正しく追加され、無効なファイルが生成されることはありません。ミックスに追加されるとすぐにaddDirectoryContent()、アーカイブ ユーティリティがファイルの抽出に失敗し、上記のエラーが出力されます。

4

0 に答える 0