此函数返回结果集(文件名)并将其压缩以供用户保存在桌面上。
function getFiles() {
error_reporting(E_ALL);
ini_set("display_errors", 1);
ini_set('zlib.output_compression', 'Off');
$result = null;
$ZIPresult = null;
$cleanup = null;
$output = null;
$fileName = 'SearchResult.zip';
//remove old zip if any
$cleanup = shell_exec("/bin/rm -f SearchResult.zip");
error_log("SHELL OUTPUT=>" . $cleanup, 0);
//test
if (empty($_POST['DBSite'])) { return null; }
$mydir = MYDIR; // set from the CONSTANT
$dir = opendir($mydir);
$DBSite = $_POST['DBSite'];
$getfilename = mysql_query("select /*! SQL_CACHE */ filename from automation_search where site='" . $DBSite . "'") or die(mysql_error());
while ($row = mysql_fetch_array($getfilename)) {
$filename = $row['filename'];
$result .= '<tr><td><a href="' . basename($mydir) . '/' . $filename . '" target="_blank">' . $filename . '</a></td></tr>';
$ZIPresult .= basename($mydir) . '/' . escapeshellarg($filename).' ';
}
if ($result) {
$result = "<table><tbody><tr><td>Search Results.</td></tr> $result</table>";
$output = shell_exec("/usr/bin/zip -R SearchResult.zip ". $ZIPresult ." 2>&1 ");
error_log("SHELL OUTPUT=>" . $output, 0);
error_log("ZIP FILENAME=>" . $fileName, 0);
if (file_exists($fileName)) {
//header for forced download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fileName));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fileName));
ob_clean();
flush();
readfile($fileName);
exit;
}
}
return $result;
}
仅适用于少于1,000个文件(大约)。这就像是一个内存限制命中,文件列表输出到屏幕。
Error.log
中没有错误。未创建ZIP文件我尝试从
shell_exec("/usr/bin/zip SearchResult.zip ". $ZIPresult ." ");
到
shell_exec("/usr/bin/zip -R SearchResult.zip ". $ZIPresult ." 2>&1 ");
没有区别。我错过了什么?
答案 0 :(得分:3)
您可能会达到命令行参数允许的最大字符数。您可能希望使用PHP的built-in ZIP-support来完成所需的任务。
并且旁注:如果您的脚本接受用户输入,您可能想要逃避它。作业$DBSite = $_POST['DBSite']
应该使用mysql_real_escape_string()
。
编辑:由于ZipArchive
不可用,您可以考虑另一个选项:
Open a pipe到ZIP二进制文件并传递-@
选项。这将从STDIN
读取文件名。然后,您可以编写要包含在此管道中的文件名。
$p = popen('/usr/bin/zip -@ -R SearchResults.zip', 'w');
foreach ($files as $filename)
fwrite($p, $filename . "\n");
pclose($p); // Important. Handle needs to be closed with pclose()
答案 1 :(得分:1)
您可能正在达到命令行大小限制(我不确切知道它是什么,但它应该是几千个字符)。
将您的任务拆分为几个:首先创建包含几百个文件的zip文件,然后发出更多命令添加到现有的zip文件中。