我在php中有一个代码函数
它的作用:
它从表中吸收数据并将图像(保存为blob)转换为文件并放在名为" image
"的子文件夹下。在基于版本和日期动态创建的文件夹下
ex:v3-20-12-2012
然后它创建一个csv文件并将其保存在v3-20-12-2012
文件夹中。
然后它为文件夹v3-20-12-2012
创建一个zip文件。
问题是,zip文件保存在项目文件夹中。我希望它可以下载。
我怎样才能实现这一点。
这是我的代码:
function create_csv($version,$ctg,$cnt,$nt,$api)
{
$folder = $version."-".date('d-m-Y')."-".time();
if(!file_exists('./'.$folder))
{
mkdir('./'.$folder);
mkdir('./'.$folder.'/image/');
}
$cnt_table = "aw_countries_".$version;
$ctg_table = "aw_categories_".$version;
$off_table = "aw_offers_".$version;
$sizeof_ctg = count($ctg);
$cond_ctg = " ( ";
for($c = 0; $c < $sizeof_ctg ; $c++)
{
$cond_ctg = $cond_ctg." $ctg_table.category = '".$ctg[$c]."' ";
if($c < intval($sizeof_ctg-1))
$cond_ctg = $cond_ctg." OR ";
else if($c == intval($sizeof_ctg-1))
$cond_ctg = $cond_ctg." ) ";
}
$sizeof_cnt = count($cnt);
$cond_cnt = " ( ";
for($cn = 0; $cn < $sizeof_cnt ; $cn++)
{
$cond_cnt = $cond_cnt." $cnt_table.country = '".$cnt[$cn]."' ";
if($cn < intval($sizeof_cnt-1))
$cond_cnt = $cond_cnt." OR ";
else if($cn == intval($sizeof_cnt-1))
$cond_cnt = $cond_cnt." ) ";
}
$sizeof_nt = count($nt);
$cond_nt = " ( ";
for($n = 0; $n < $sizeof_nt ; $n++)
{
$cond_nt = $cond_nt." $off_table.network_id = '".$nt[$n]."' ";
if($n < intval($sizeof_nt-1))
$cond_nt = $cond_nt." OR ";
else if($n == intval($sizeof_nt-1))
$cond_nt = $cond_nt." ) ";
}
$sizeof_api = count($api);
$cond_api = " ( ";
for($a = 0; $a < $sizeof_api ; $a++)
{
$cond_api = $cond_api." $off_table.api_key = '".$api[$a]."' ";
if($a < intval($sizeof_api-1))
$cond_api = $cond_api." OR ";
else if($a == intval($sizeof_api-1))
$cond_api = $cond_api." ) ";
}
$output = "";
$sql = "SELECT DISTINCT $off_table.id,$off_table.name
FROM $off_table,$cnt_table,$ctg_table
WHERE $off_table.id = $cnt_table.id
AND $off_table.id = $ctg_table.id
AND ".$cond_api."
AND ".$cond_nt."
AND ".$cond_cnt."
AND ".$cond_ctg;
$result = mysql_query($sql);
$columns_total = mysql_num_fields($result);
for ($i = 0; $i < $columns_total; $i++)
{
$heading = mysql_field_name($result, $i);
$output .= '"'.$heading.'",';
}
$output .= '"icon"';
$output .="\n";
while ($row = mysql_fetch_array($result))
{
for ($i = 0; $i < $columns_total; $i++)
{
$output .='"'.$row["$i"].'",';
}
$sql_icon = "SELECT $off_table.icon FROM $off_table WHERE id = '".$row['id']."'";
$result_icon = mysql_query($sql_icon);
while($row_icon = mysql_fetch_array($result_icon))
{
$image = $row_icon["icon"];
$id = $row["id"];
$icon = "./$folder/image/{$id}.jpg";
$icon_link = "$folder/image/{$id}.jpg";
file_put_contents($icon, $image);
}
$output .= '"'.$icon_link.'"';
$output .="\n";
}
$filename = "myFile.csv";
$fd = fopen ( "./$folder/$filename", "w");
fputs($fd, $output);
fclose($fd);
$source = $folder;
$destination = $folder.'.zip';
$flag = '';
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if($flag)
{
$flag = basename($source) . '/';
}
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', realpath($file));
if (is_dir($file) === true)
{
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString($flag.basename($source), file_get_contents($source));
}
$zip->close();
if (is_dir($folder))
{
$objects = scandir($folder);
foreach ($objects as $object)
{
if ($object != "." && $object != "..")
{
if (filetype($folder."/".$object) == "dir")
{
$object_inner = scandir($folder."/".$object);
foreach ($object_inner as $object_inner)
{
if ($object_inner != "." && $object_inner != "..")
{
unlink($folder."/".$object."/".$object_inner);
}
}
rmdir($folder."/".$object);
}
else
unlink($folder."/".$object);
}
}
reset($objects);
}
rmdir("./".$folder);
/*$zipfile = $folder.'.zip';
$file_name = basename($zipfile);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$file_name");
header("Content-Length: " . filesize($zipfile));
readfile($zipfile);
exit;*/
}
EDIT:
我有两个文件实例。一个文件gettng自动保存在项目文件夹中。下一个是被迫下载。自动保存的那个没有解压缩的问题。但强行下载的那个,在解压时有问题。
答案 0 :(得分:0)
您忘记在最后发送实际数据,并且发送Content-Length标头也不错。
示例:
$filename = 'something.zip';
$filepath = './path/to/files/directory/';
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename='.$filename);
header("Content-Length: ".filesize($filepath.$filename));
ob_end_flush();
readfile($filepath.$filename);
作为旁注,您可能希望拆分该功能,因为它的功能超出了应有的范围。如名称所示,它应该只是create_csv
,但也在使用DB,创建zip,发送响应等。
更新后,我仔细查看了您的代码,并且您遇到了一些可能导致下载损坏的问题:
$source = str_replace('\\', '\\', realpath($source));
// more code ...
$file = realpath($file);
这些行将导致在归档中使用完整路径,这可能是您不想要的。我建议对这两行进行注释,以便在存档中存储相对路径。
将所有文件添加到存档后,不要关闭它,因为存档的临时名称与最后一个不同,发送标题时使用的代码将导致发送垃圾数据。
要解决此问题,您应该在发送标题之前关闭.zip:
// more code ...
$zip->close();
header('Content-type: application/zip');