cURL Download of image isn't an image - php

I'm downloading an image via curl from filepicker.io. Here's the downloading code:
if ($_GET['download']== 'true'){
$downloadarray = array();
while($row = mysql_fetch_array($res)){
$url= $row['loc'];
$path = 'tmp/';
$path .= rand(100,999);
$path .= $row['name'];
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
echo print_r($data);
$downloadarray[] = array($path, $row['name']);
}
$zipname = rand(0,9999) . 'download.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($downloadarray as $file) {
$zip->addFile($file['0'], $file['1']);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=' . $zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
unlink($zipname);
}
For some reason the downloaded file is an image, for example 'palm-tree.jpeg' but it isn't actually being stored as an image. There is no header information being added in the image file. When I open the image with Get Info on my mac a preview correctly renders but the file type is listed as Document. Am I doing something wrong?
EDIT: Now added full code including zipping

Remove:
fwrite($fp, $data);
When you use CURLOPT_FILE, cURL writes the results to the file, you don't need to do it yourself. $data contains true, and you're appending that to the file (actually you're appending 1 to the file, since you're converting true to a string when you write it).

Related

how to force zip to dowload without temp file?

i want to make dynamic zip, so when admin click .zip, it will download and zip all files in folder based on user ud
user will have document and store on folder with their id
i.e /public/stroage/file/ID001, so when user click button download it will force to download ID0001.zip
here is my code
$zip = new \ZipArchive();
$uploaddir = public_path().'/temp';
$tmp_file = tempnam($uploaddir,'');
$zip->open($tmp_file, \ZipArchive::CREATE);
// Loop through each file
foreach($files as $file){
$url2 = $url.$file->upload;
$url2 = str_replace(' ', '%20', $url2);
if (!function_exists('curl_init')){
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
$download_file = $output;
$type = substr($url2, -5, 5);
#add it to the zip
$zip->addFromString(basename($url.$file->upload.'.'.$type),$download_file);
}
// close zip
$zip->close();
// Set Time Download
date_default_timezone_set("Asia/Kuala_Lumpur");
$time_name = date('Ymd');
$time_download = date('Y-m-d H:i:s');
$log_download = new Log_download;
$user = Auth::user();
$id_user = $user->id;
$log_download->id_praapplication = $id_pra;
$log_download->id_user = $id_user;
$log_download->Activity = 'Download ZIP File';
$log_download->type = 'Zip Archive';
$log_download->downloaded_at = $time_download;
$log_download->save();
# send the file to the browser as a download
ob_start();
$strFile = file_get_contents($tmp_file);
header('Content-disposition: attachment; filename=DOC-'.$id_pra.'-'.'.zip');
header('Content-type: application/zip');
echo $tmp_file;
while (ob_get_level()) {
ob_end_clean();
}
readfile($tmp_file);
//$filetopath=$public_dir.'/'.$zipFileName;
//$filetopath = public_path().'/storage/uploads/file/'. $id_pra.'/'.$zipFileName;
// Create Download Response
// if(file_exists($filetopath)){
// return response()->download($filetopath,$zipFileName,$headers);
//}
exit;
actually this code work. but every utton to dowload zip i clicked, will create a temporary file inside folder /public.
how to download zip without creating temp file or can i make a folder like /public/tmp and save all temp zip to that folder?
You should be able to do $zip->open('php://output', \ZipArchive::CREATE);. Complete code:
header('Content-disposition: attachment; filename=DOC-'.$id_pra.'-'.'.zip');
header('Content-type: application/zip');
$zip = new \ZipArchive();
$zip->open('php://output', \ZipArchive::CREATE);
// Loop through each file
foreach($files as $file){
$url2 = $url.$file->upload;
$url2 = str_replace(' ', '%20', $url2);
if (!function_exists('curl_init')){
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
$download_file = $output;
$type = substr($url2, -5, 5);
#add it to the zip
$zip->addFromString(basename($url.$file->upload.'.'.$type),$download_file);
}
// close zip
$zip->close();
// Set Time Download
date_default_timezone_set("Asia/Kuala_Lumpur");
$time_name = date('Ymd');
$time_download = date('Y-m-d H:i:s');
$log_download = new Log_download;
$user = Auth::user();
$id_user = $user->id;
$log_download->id_praapplication = $id_pra;
$log_download->id_user = $id_user;
$log_download->Activity = 'Download ZIP File';
$log_download->type = 'Zip Archive';
$log_download->downloaded_at = $time_download;
$log_download->save();
exit;
However, the zip filesize should not exceed the PHP max memory limit. If it does, you'll end up with corrupted zip files.

How to save download zip to public folder in laravel?

I want to download a folder into ZIP format with my code below.
Actually this work perfectly for download folder to zip only.
But i want the zip file also save to public folder in public/folder.
i use laravel and ziparchive
Please help me
public function downloadzip($id_pra) {
$dcmt = DB::table('document')->select(DB::raw(" max(id) as id"))->where('id_praapplication',$id_pra)->groupBy('type')->pluck('id');
$files = Document::whereIn('id', $dcmt)->get();
$url = url('')."/storage/uploads/file/".$id_pra."/";
# create new zip opbject
$zip = new \ZipArchive();
# create a temp file & open it
$tmp_file = tempnam('.','');
$zip->open($tmp_file, \ZipArchive::CREATE);
# loop through each file
foreach($files as $file){
$url2 = $url.$file->upload;
$url2 = str_replace(' ', '%20', $url2);
if (!function_exists('curl_init')){
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
$download_file = $output;
$type = substr($url2, -5, 5);
#add it to the zip
$zip->addFromString(basename($url.$file->upload.'.'.$type),$download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
ob_start();
$strFile = file_get_contents($tmp_file);
header('Content-disposition: attachment; filename=DOC-'.$id_pra.'-'.$url.'.zip');
header('Content-type: application/zip');
echo $tmp_file;
while (ob_get_level()) {
ob_end_clean();
}
readfile($tmp_file);
exit;
}
Instead of creating a temp file you can just create the ZIP file directly and later use the Filesystem API to download it.
public function downloadzip($id_pra) {
$dcmt = DB::table('document')->select(DB::raw(" max(id) as id"))->where('id_praapplication',$id_pra)->groupBy('type')->pluck('id');
$files = Document::whereIn('id', $dcmt)->get();
$url = url('')."/storage/uploads/file/".$id_pra."/";
// create new zip object
$zip = new \ZipArchive();
// store the public path
$publicDir = public_path();
// Define the file name. Give it a unique name to avoid overriding.
$zipFileName = 'Documents.zip';
// Create the ZIP file directly inside the desired folder. No need for a temporary file.
if ($zip->open($publicDir . '/folder/' . $zipFileName, \ZipArchive::CREATE) === true) {
// Loop through each file
foreach($files as $file){
$url2 = $url.$file->upload;
$url2 = str_replace(' ', '%20', $url2);
if (!function_exists('curl_init')){
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
$download_file = $output;
$type = substr($url2, -5, 5);
#add it to the zip
$zip->addFromString(basename($url.$file->upload.'.'.$type),$download_file);
}
// close zip
$zip->close();
}
// Download the file using the Filesystem API
$filePath = $publicDir . '/folder/' . $zipFileName;
if (file_exists($filePath)) {
return Storage::download($filePath);
}
}
Note:
I would extract the CURL part to a method fetchFile($url); which returns the downloaded file, but this is out of scope of this question.

when downloading the zip file from the url it showing like "The requested URL /export/name.zip was not found on this server." using php

Some of the zip files is download but some files showing like "The requested URL /export/1286.zip was not found on this server."
But i am using the same code for both.
final_zip($certificate_id);
function final_zip($certificate_id){
$zip = new ZipArchive;
$zip_file=$certificate_name.'-licence-documents-'.date("d-m-Y h:i:s").'.zip';
if ($zip->open("$zip_file",ZipArchive::CREATE) === TRUE){
$q_pack="(select * from filename where cerid=$id)";
$res_pack = db_query($q_pack);
if ($res_pack){
$fp = fopen('Package_list.csv', 'w');
while ($pack_row = db_fetch_object($res_pack))
{fwrite($fp, "\n");
foreach ($pack_row as $line) {
$val = '"'.$line.'"'.',';
fwrite($fp, $val);}}
fclose($fp);
$zip->addFile('Package_list.csv', "Package list.csv");
}}$zip->close();
ob_get_clean();
header('Content-Type: application/zip');
header("Content-Disposition: attachment; filename=$zip_file");
header('Content-Length: ' . filesize($zip_file));
header("Location: $zip_file");}
And also please find the screenshor of the error
I saw the your zip file have space, so when create the name please remove all space.
Base on your code you can change as:
$zip_file=$certificate_name.'-licence-documents-'.date("d-m-Y h:i:s").'.zip';
To
$zip_file=$certificate_name.'-licence-documents-'.date("d-m-Yh:i:s").'.zip';
or
$zip_file=$certificate_name.'-licence-documents-'.date("d-m-Y-h:i:s").'.zip';

Download all images from a website url

I need to download all images (only) from a url.I've been searching but never got the right answer for this. I have a page that will accept website url to a input box then after submitting it will download all the images from that website.I got this code from the web, but I dont know how to use or where to put the web url. For example i want to download all images from http://www.microsoft.com/en-ph/default.aspx
$url = $_REQUEST['webUrl'];
$string = FetchPage($url);
$image_regex_src_url = '/<img[^>]*'.
'src=[\"|\'](.*)[\"|\']/Ui';
$image_regex_src_url = '/<img[^>]*'.
'src=[\"|\'](.*)[\"|\']/Ui';
preg_match_all($image_regex_src_url, $string, $out, PREG_PATTERN_ORDER);
$images_url_array = $out[1];
foreach ($images_url_array as $pica)
{
echo '<img src="'.$pica.'" >';
$fileNames[] = $pica;
}
$_SESSION['filesArr'] = $fileNames;
function FetchPage($path)
{
$file = fopen($path, "r");
if (!$file)
{
exit("URL Unknown");
}
$data = '';
while (!feof($file))
{
$data .= fgets($file, 1024);
}
return $data;
}
This is my download script.
$files = array ('http://c.s-microsoft.com/en-ph/CMSImages/mslogo.png?version=856673f8-e6be-0476-6669-d5bf2300391d');
$zip = new ZipArchive();
$tmp_file = tempnam('.','');
$zip->open($tmp_file, ZipArchive::CREATE);
foreach($files as $file){
$download_file = file_get_contents($file);
$zip->addFromString(basename($file),$download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
header('Content-disposition: attachment; filename=download.zip');
header('Content-type: application/zip');
readfile($tmp_file);
You could also use wget... For example:
wget -r -A=.jpg,.png http://www.microsoft.com/en-ph/default.aspx

PHP output empty ZIP

This script successfully generated the pdfs to a folder tmp/....
However the ZIP output to the browser is empty and I don't know what I have done wrong.
$file = tempnam("tmp", "zip");
$zip = new ZipArchive();
// Zip will open and overwrite the file, rather than try to read it.
$zip->open($file, ZipArchive::OVERWRITE);
foreach( explode( ',', $_POST["ids"]) as $Client_ID)
{
$sql_qry="select *
from ca_client_statement
where client_id='".$Client_ID."' and trading_period_month like '".$TP_Month."'";
$sql_err_no=sql_select($sql_qry,$sql_res,$sql_row_count,$sql_err,$sql_uerr);
//echo $sql_qry;
//echo '<br/>';
$row = mysql_fetch_assoc($sql_res);
$file_content = $row['pdf_statement'];
$file_name = 'tmp/'.$Client_ID.'statement.pdf';
$pdf=file_put_contents($file_name, $file_content);
$zip->addFile($pdf);
}
$zip->close();
// Stream the file to the client
header("Content-Type: application/zip");
header("Content-Length: " . filesize($file));
header("Content-Disposition: attachment; filename=\"a_zip_file.zip\"");
readfile($file);
unlink($file);
file_put_contents() returns the number of bytes written, not the file name. Try changing the line right after it to this:
$zip->addFile($file_name);

Categories