how to force zip to dowload without temp file? - php

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.

Related

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.

PHP error - fileSize returns the image string

I am downloading a public image and writing it to file. But the filesize(file) returns the entire encoded string of the image
My code is as follows
<?php header('Access-Control-Allow-Origin: *'); ?>
<?php
function download_and_write($src,$filename)
{
$ch = curl_init($src);
$fp = fopen($_SERVER["DOCUMENT_ROOT"]."/dashboard/uploads/".$filename, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($ch);
fclose($fp);
$filepath = $_SERVER["DOCUMENT_ROOT"]."/dashboard/uploads/".$filename;
return filesize($filepath);
}
$src_url = $_POST['source'];
$dest_url = $_POST['destination'];
$filename = $_POST['filename'];
try{
$download = download_and_write($src_url,$filename);
echo $download;
}
catch(Exception $e) {
$mess=$e->getMessage();
echo "exception";
echo $mess;
}
?>
And echo of the download variable is like this
����T۸\u001b\u0014��Yl����\u0000�\"#?d�k�ϵ.Ⱦ)�;�+.�t��x/�M�E>}࿝7�\u0015�ݎ��b۪N+\u001e�K\u000f/�T�]�W3���\bhyx����~\tvM����3�|��:o�)��\u0005���(�N�u��6�RwV\u001d��\u001e_���f_�t��/\u0003�|��:o�)��\u0005���(�]��[��\u000fg\f���lN�0��g]~*�\u0018ۖ_0�Zk\u0002'\u0016�Ѱ�\u0012������j+>�uo�x/�M�E>}࿝7�\u0015Lj �A\u0004w��K��E_����C�����\u001a��ޗfW�4��/\u0006u_�x/�M�E>}࿝7�\u0015���]��l�VvWv�ds\bi�wU3���uqe�\u001d�M�\u0012�\u0000�{}�K��m.�XV]ώ�����>o�)��\u0005���(�T�u��\u001b+C<�tM��\u0011\u0004\u0003�=#ڬ[�b�ݕ�d�Mo�F�t�d��𨫸�\u0003�|��:o�)��\u0005���(�ck\tn�>��\u0014�m��\u0000������ޣO��^x�����/F1� ����f��].;��\u001f\u001d�W����tߔS��\u000b��~Q\\����䓲$n\r{�Ѥ�\u0003�S\"�\\\u0016��j\t�2̍c\u001f$d\u000e�u��ݒ?\u0017ҥ�+��?>�_Λ��|��:o�+�d1���:z�6\u000er�J�\u0010���\u0014^�N�K��Ȼ��]9���R���ƕ\u0017g\u0015���}࿟7�\u0014����|ߔW'����tN�f��\u0004�0�3d\u000e��e��͙�RC�2\u001b6]\\=ёɣ��=�\u001e�n����eO���:\u0017ϼ\u0017�����>�_Λ����1��5��^h�y<�{\u000bC����C\u000b�\fq��\r/�#Op�ܗf\u001f�4��4�\u000e���\u0005���(�ϼ\u0017�����DX��O�ERw��\u001f��\u0012yOq�(�E$\u0012�)���aӚ��\u000f�.��Ɣ��W�:�\u0000ϼ\u0017�����>�_Λ��㨗fvޑ�x~N���\u0005���(�ϼ\u0017������%��zG%��;\u0017ϼ\u0017�����>�_Λ��㨗cm�\u001c����_>�_Λ��|��:o�+��]���r^\u001f��|��:o�)��\u0005���(�:�v6ޑ�x~N���\u0005���(�ϼ\u0017������%��zG%��;\u0017ϼ\u0017�����>�_Λ��㨗cm�\u001c����_>�_Λ��|��:o�+��]���r^\u001f��|��:o�*#��`;�i�\u0000(�*�vU��!p^\u001f���!`�?�\u0014\\T\"��v���x~C��^*�;=\n�G��>-�\u0011{�|\nr�\u0002���/yO�NS�PX�\u0017����)�(,x��S�S��\u0014\u0016<E�)�)�|\n\u000b\u001e\"���\u0014�>\u0005\u0005�\u0011{�|\nr�\u0002�Lj��>\u00059O�PX�h��\n���:�/����,���7G��֔,��a��X��\u001c_(��5�ӹ9G)>�-o��')�*�ǥI��y����n���de��kQ�\u0004V$�ɹ�(`��� ;����L�Cnk��r\t-?\u001f\u0014\u0006g�\u0006K#\u001c\t󏳦�:Zg)�NS����ۻ������7\u001brA\u00060�\u0016`���\u0018�c�\u0005���G�H�C���E���%���\t�\u0007\u0003�k��Ѣ\u0016��|\u0013�� 폧͙N\u0018��e��_��i�'��7�\u001d\u001f�g�����c!��\u001d\u0015AJ��w+y�A���<�V���>>�oY���h\u0017�;��7�}�3����l���}(b�����W�˕����Y��>&�۰>�#����s61#4Ɨ{�\u001bX̜\r��\u0015���y,\u000bo{�\u0014����\u0001�,\u0007)�NS��ZN(���m���q���P��,�Nh��$�D�z9��=�Yl���\\��n=��#����\u001f �\u0004\u0010�N���KH�>\u00059O�\u0016:\\�\\m��X�6�\u00172���\u0013�X�'g\b���/F�z9U�{`�#��ymVA\u00151\u0013��\u0001���\u001c�������T�5G��4\f��'lo�p�V9O�\u001d\u001e��x{�����m�\\�8btv\u0018׷\n��\u000f�\u000f�==��{\u000fn)p���*>z�y��-�\u0012�\u0017l?�\u001c�_E�r�\u0004�>\bb:d�����e��\u001b<T٦�����s���\u001b׽��\u0003ڶ\u001c��f\u0016hɧ\u0014��/\f�ٙ�h'n$�o�h����)�P�=%�Ia���mV�\u0006{�R%��\u001c�wd\u000b�\u001d�F�~�\u0005�F�g�ې\u000e\u001eYv6S���g�?x\fZ�)�*]��/\bD���������\u0003��zO���SjW��o�o��}̖\u0005ݶ##J\u000b\u0011׹+�{\\�;0��{o7�\n�fH�R�\u0016rM�'mT>f�5�����|V��|\u0013��!��\u000e1Q�w\u001e�\u001fs}�����\rl�5#\u0007d�\u0000,3K0\u000fi�#z\u001d=\u001a���.�l�\u0010��Z��Q����\u001f��>\u001e��r�\u0004�>\bt���Zѷ��m��\u0013��:v8|��h�{w0�}���h���z<�L��\u0013Dq5��p���=\u001a��j<���)�P�KrVq�g#����ʈ���KU͊g�2K?#~���v�\u0019,F��sb'F�?b\u001ad\u001b�\u0004m�w���S����SR�\\�����\u0000f�<�\u0019;�Gd v2Z�k!\u0012��lЏ��h�\u0000��K!��\r�֫GM�x��F����Z�)�NS�P��%{����;�w\u001b�\u0019��\u0013\u0007��]�G]ы\u0010�1�\u0018��\u0018�\u0000����kM����\u0004�\r\u0011�\ta\u000e\u0007����Z�>\n��G��qqk\u0006�<\u0006��:���I�����n\u0018����Y����z�ls��y\u000b]�K��O0=�4|���\"�߂���J���\u0011�gl?�]:-W��')�C�kv������r39+u����`�j�-y�~�\u0004l�ۣ�[\u0013�,Q�\u001d�\u0017��ZV��6��H�\u001av[��\u000e�+Ea{\u001e׳msN�\u001e��w�w��$SvMl�\u0019Lq5����Gz��KIQ�)��o�5��6|���\u001eF�\rǚ�b-k���{��\u001d��\u0011��������g�fI\u0019�\u001b:<\u0012�4h�;��r�\u0002���S5��U4��\u0000[�6�ݎ(gt6\u001a�\u000e\u001e(�k��s7m��k\u0013���Ⱏ�\u0012J�\u001e���#�:\u0007�X~S�������L��m���\u0000F㉵\u0013)a�}�����~g?�R;|�#�\u000fj����Î�%v\u0019�\u0019\u0006N9%�DQ��$�\u001e�=�P�>\t�|\u0010��$��s]ﻇ�}\rң+�a���j��߂nH�\u000f%��<�=���,��M��^\ta��r26J$�\u001c��?`\u0000��S����\u0007k�%\u001d۳~ٱ�x���\u0013g��\u0017�c�\u000e~�绨��ܬp����V���6�-.�Q���F����\u0004�>\u0005C�h�56�yݷ��}��\u0012�\u001ddJ�)�<2Z��Ń��z��][\u0011:�\t\u0005�Du�ҾNi#�\\G)פw�Z/)�)�|\u0015:�6W�^�����u�\u001d?\u000ed�<�IM����잎�\u001f�y���x~�6O\u0004v\f��\u0004�\u0006\u0002�\u001c\u000e���X>S�S��(qU�$䯕��Sz���U�\u00043R�\u000b��i�ILb^V����\u0011�V�İE&FyjX�c�6\u00199�\u000f-q\u001a�k��\u0002���\u0004�>\n���ҝX�q����x��S�S��\u0014<�<E�)�)�|\n\u000b\u001e\"���\u0014�>\u0005\u0005�\u0011{�|\nr�\u0002�Lj��>\u00059O�Ac�^��\u0002������/yO�NS�PX�\u0017����)�(,x��S�W�>\u0007࠱�E�\u0007��ȱ��
Why would this occur ? The file didn't download.
EDIT:
I'm not checking the size of a remote file. I'm checking the size of the file on my own server. So this can't be related to the possible duplicate you mentioned.
I think fopen is getting an error, so you're not redirecting the curl output to the file. Add error checking.
error_reporting(E_ALL);
$fp = fopen($_SERVER["DOCUMENT_ROOT"]."/dashboard/uploads/".$filename, 'wb');
if (!$fp) {
throw new Exception("Unable to open download file");
}

cURL Download of image isn't an image

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).

php curl to download multiple photos as zip from facebook not working

I'm using curl to fetch photos from Facebook url for authorized user, for each photo I'm adding it to a zip file to allow user to download whole album as zip.
if( !isset($_GET['id']) )
die("No direct access allowed!");
require 'facebook.php';
$facebook = new Facebook(array(
'appId' => 'removed',
'secret' => 'removed',
'cookie' => true,
));
if( !isset($_GET['id']) )
die("No direct access allowed!");
$params = array();
if( isset($_GET['offset']) )
$params['offset'] = $_GET['offset'];
if( isset($_GET['limit']) )
$params['limit'] = $_GET['limit'];
$params['fields'] = 'name,source,images';
$params = http_build_query($params, null, '&');
$album_photos = $facebook->api("/{$_GET['id']}/photos?$params");
if( isset($album_photos['paging']) ) {
if( isset($album_photos['paging']['next']) ) {
$next_url = parse_url($album_photos['paging']['next'], PHP_URL_QUERY) . "&id=" . $_GET['id'];
}
if( isset($album_photos['paging']['previous']) ) {
$pre_url = parse_url($album_photos['paging']['previous'], PHP_URL_QUERY) . "&id=" . $_GET['id'];
}
}
$photos = array();
if(!empty($album_photos['data'])) {
foreach($album_photos['data'] as $photo) {
$temp = array();
$temp['id'] = $photo['id'];
$temp['name'] = (isset($photo['name'])) ? $photo['name']:'photo_'.$temp['id'];
$temp['picture'] = $photo['images'][1]['source'];
$temp['source'] = $photo['source'];
$photos[] = $temp;
}
}
?>
<?php if(!empty($photos)) { ?>
<?php
$zip = new ZipArchive();
$tmp_file =tempnam('.','');
$file_opened=$zip->open($tmp_file, ZipArchive::CREATE);
foreach($photos as $photo) {
$url=$photo['source'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$download_file=curl_exec($ch);
#add it to the zip
$file_added=$zip->addFile($download_file);
}
# close zip
$zip->close();
# send the file to the browser as a download
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="albums.zip"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmp_file));
ob_clean();
flush();
readfile($tmp_file);
exit;
} ?>
problem: zip->open creates a file, zip->add returns 1 for each file added but the zip size is still 0 and readfile do not prompt for downloading.
At the moment, you're trying to do this:
foreach ($photos as $photo) {
$url = $photo['source'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$download_file = curl_exec($ch);
$file_added = $zip->addFile($download_file);
}
This will not work because $dowload_file is a string and not a filename. You need to save your cURL parameter to a file, and pass the filename to $zip->addFile. If you look at PHP's documentation, it's expecting a filename, not a string:
The path to the file to add.
You need to do something like:
$temp_file = './temp_file.txt';
file_put_contents($temp_file, $download_file);
$file_added = $zip->addFile($temp_file);
// Delete after use
unlink($temp_file);

How can I save a file url submitted in a form with curl?

I am trying to create an upload plugin that allows for a user to upload any file from their computer or from a url they type into the provided text field.
This is the script I have to upload files from a local disk:
session_start();
//Loop through each file
for($i=0; $i<count($_FILES['file']); $i++) {
//Get the temp file path
if (isset($_FILES['file']['tmp_name'][$i]))
{
$tmpFilePath = $_FILES['file']['tmp_name'][$i];
}
//Make sure we have a filepath
if ($tmpFilePath != ""){
//Setup our new file path
if (isset($_FILES['file']['name'][$i]))
$newFilePath = "./uploaded_files/" . $_FILES['file']['name'][$i];
}
//Upload the file into the temp dir
if(move_uploaded_file($tmpFilePath, $newFilePath)) {
echo "Uploaded Successfully!<br />";
}
All I need now is for the curl part to take the file from the url submitted in the text field and save it to the same location.
Here is the cURL I have so far:
function GetImageFromUrl($link) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch,CURLOPT_URL,$link);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
return $result;
}
$sourcecode=GetImageFromUrl("http://domain.com/path/image.jpg");
$savefile = fopen('/home/path/image.jpg', 'w');
fwrite($savefile, $sourcecode);
fclose($savefile);
Is there a specific reason you want to use curl? Here's how you can simply do that without it:
$url = $_POST['url'];
$file_content = file_get_contents($url);
$file_name = array_pop(explode('/', parse_url($url, PHP_URL_PATH)));
file_put_contents('/home/path/' . $file_name, $file_content);
You should also consider looking into $url and checking if it's valid before working with it.

Categories