2

ウェブサイト全体をバックアップし、ワンクリックで自動的にダウンロードするコードを作成しました。私のコードは次のようになります。

if (file_exists("file.zip")) {
  unlink("file.zip");
}
$folder_array = array();
$file_array = array();
function listFolderFiles($dir){
  global $folder_array;
  global $file_array;
  $ffs = scandir($dir);
  foreach($ffs as $ff){
    if ($ff != '.' && $ff != '..') {
      if (is_dir($dir.'/'.$ff)) {
        $new_item = "$dir/$ff";
        $new_item = str_replace('..//','',$new_item);
        if ($new_item !== "stats") {
          array_push($folder_array, $new_item);
          listFolderFiles($dir.'/'.$ff);
        }
      }
      else {
        $new_item = "$dir/$ff";
        $new_item = str_replace('..//','',$new_item);
        if (($new_item !== "stats/logs") && ($new_item !== "stats/")) {
          array_push($file_array, $new_item);
        }
      }
    }
  }
}
listFolderFiles('../');
$zip = new ZipArchive;
if ($zip->open('file.zip', true ? ZIPARCHIVE::OVERWRITE:ZIPARCHIVE::CREATE) === TRUE) {
  foreach($folder_array as $folder) {
    $zip->addEmptyDir($folder);
  }
  foreach($file_array as $key => $file) {
    $file_path = "../$file";
    $zip->addFile($file_path, $file);
  }
}
$zip->close();
$file = "file.zip";
chmod("$file", 0700);
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=". $file);
readfile($file);

現在、このコードはしばらくの間うまく機能していましたが、今日は機能したくないようです。問題は、これは PHP スクリプト エラーではないということです。エラー ログを確認しましたが、何も表示されません。ブラウザ エラーのようですが、ブラウザごとに異なるメッセージが表示されます。

Chrome で「この Web ページは利用できません」と表示される Firefox で「接続がリセットされました」と表示される Internet Explorer で「このページを表示できません」と表示される

これらのエラーが発生しても、ZIP ファイルはまだ作成中であり、サーバーからダウンロードできます。

広範な調査の結果、私が試したことのリストは次のとおりです。

1) ZIP ファイルを自動的にダウンロードするコードを削除しました (すべてのコードは、ZIP ファイルを閉じた後に書き込まれます)。それでもブラウザエラーが発生します。

2) 開かれているファイルが多すぎて、制限を超えている可能性があることを読みました。200 ファイルごとに ZIP ファイルを閉じて再度開くようにコードを追加しました。それでもうまくいきませんでした。

3) ファイルの量を ZIP に制限しました。500 未満ではすべてが正常に機能していました。500 から 1,000 ファイルの間では、コードは一部の時間しか機能しませんでした。うまくいく場合もあれば、ブラウザのエラーが表示される場合もあります。1,000 かそこらを超えると、まったく適切に機能しなくなります。

ホスティングは GoDaddy を通じて行われます。

PHP のバージョンは 5.2.17 です

max_execution_time は 240 に設定されています (コードがこれほど長くなることはなく、通常は実行に約 30 秒しかかかりません)

memory_limit は 500M に設定されています (すべてのファイルを合わせたサイズの 2 倍以上)。

このコードは数週間前に 1,500 個のファイルに対して問題なく動作していたため、何が起こっているのか本当にわかりません。繰り返しになりますが、ZIP ファイルはまだ作成中で、PHP エラーはなく、これらのエラーが返されるのはブラウザだけです。

4

2 に答える 2

1

あなたのコードのどこが悪いのかわかりませんが、私は以下のコードを使用しています。

function create_zip($path, $save_as)
{
    if (!extension_loaded('zip'))
        throw new ErrorException('Extension ZIP has not been compiled or loaded in php.');
    else if(!file_exists($path))
        throw new ErrorException('The file/path you want to zip doesn\'t exist!');


    $zip = new ZipArchive();
    if (!$zip->open($save_as, ZIPARCHIVE::CREATE))
        throw new ErrorException('Could not create zip file!');

    $ignore = array('.','..');
    if($path == dirname($save_as))
        $ignore[] = basename($save_as);

    $path = str_replace('\\', '/', realpath($path));

    if (is_dir($path)) {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
        foreach ($files as $file) {
            $file = str_replace('\\', '/', $file);

            if( in_array(substr($file, strrpos($file, '/')+1),$ignore )) continue;

            $file = realpath($file);
            if (is_dir($file)) {
                $zip->addEmptyDir(str_replace($path . '/', '', $file . '/'));
            }
            else if (is_file($file)) {
                $zip->addFromString(str_replace($path . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($path)) {
        $zip->addFromString(basename($path), file_get_contents($path));
    }

    return $zip->close();
}

$zip = create_zip('/path/to/your/zip/directory', '/path/to/your/save.zip');

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename('/path/to/your/save.zip').'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize('/path/to/your/save.zip'));
echo readfile('/path/to/your/save.zip');
于 2013-04-02T01:24:51.477 に答える
0

イテレータをインスタンス化し (zip ファイルがソース フォルダ内に作成された場合に備えて、zip アーカイブを作成する前に)、ディレクトリを走査してファイル リストを取得します。

他のコードを参照してください:クリックしてください

于 2013-07-01T05:56:11.703 に答える