I have one application that upload some files and then I can compress as zip file and download.
The export action:
public function exportAction() {
$files = array();
$em = $this->getDoctrine()->getManager();
$doc = $em->getRepository('AdminDocumentBundle:Document')->findAll();
foreach ($_POST as $p) {
foreach ($doc as $d) {
if ($d->getId() == $p) {
array_push($files, "../web/".$d->getWebPath());
}
}
}
$zip = new \ZipArchive();
$zipName = 'Documents-'.time().".zip";
$zip->open($zipName, \ZipArchive::CREATE);
foreach ($files as $f) {
$zip->addFromString(basename($f), file_get_contents($f));
}
$response = new Response();
$response->setContent(readfile("../web/".$zipName));
$response->headers->set('Content-Type', 'application/zip');
$response->header('Content-disposition: attachment; filename=../web/"'.$zipName.'"');
$response->header('Content-Length: ' . filesize("../web/" . $zipName));
$response->readfile("../web/" . $zipName);
return $response;
}
everything is ok until the line header.
and everytime I'm going here I got the error: "Warning: readfile(../web/Documents-1385648213.zip): failed to open stream: No such file or directory"
What is wrong?
and why when I upload the files, this files have root permissions, and the same happens for the zip file that I create.
SYMFONY 3 - 4 example :
use Symfony\Component\HttpFoundation\Response;
/**
* Create and download some zip documents.
*
* #param array $documents
* #return Symfony\Component\HttpFoundation\Response
*/
public function zipDownloadDocumentsAction(array $documents)
{
$files = [];
$em = $this->getDoctrine()->getManager();
foreach ($documents as $document) {
array_push($files, '../web/' . $document->getWebPath());
}
// Create new Zip Archive.
$zip = new \ZipArchive();
// The name of the Zip documents.
$zipName = 'Documents.zip';
$zip->open($zipName, \ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFromString(basename($file), file_get_contents($file));
}
$zip->close();
$response = new Response(file_get_contents($zipName));
$response->headers->set('Content-Type', 'application/zip');
$response->headers->set('Content-Disposition', 'attachment;filename="' . $zipName . '"');
$response->headers->set('Content-length', filesize($zipName));
#unlink($zipName);
return $response;
}
solved:
$zip->close();
header('Content-Type', 'application/zip');
header('Content-disposition: attachment; filename="' . $zipName . '"');
header('Content-Length: ' . filesize($zipName));
readfile($zipName);
apparently closing the file is important ;)
Since Symfony 3.2+ can use file helper to let file download in browser:
public function someAction()
{
// create zip file
$zip = ...;
$this->file($zip);
}
ZipArchive creates the zip file into the root directory of your website if only a name is indicated into open function like $zip->open("document.zip", ZipArchive::CREATE). Specify the path into this function like $zip->open("my/path/document.zip", ZipArchive::CREATE). Do not forget delete this file with unlink() (see doc).
Here you have an example in Symfony 4 (may work on earlier version):
use Symfony\Component\HttpFoundation\Response;
use \ZipArchive;
public function exportAction()
{
// Do your stuff with $files
$zip = new ZipArchive();
$zip_name = "../web/zipFileName.zip"; // Users should not have access to the web folder (it is for temporary files)
// Create a zip file in tmp/zipFileName.zip (overwrite if exists)
if ($zip->open($zip_name, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
// Add your files into zip
foreach ($files as $f) {
$zip->addFromString(basename($f), file_get_contents($f));
}
$zip->close();
$response = new Response(
file_get_contents($zip_name),
Response::HTTP_OK,
['Content-Type' => 'application/zip',
'Content-Disposition' => 'attachment; filename="' . basename($zip_name) . '"',
'Content-Length' => filesize($zip_name)]);
unlink($zip_name); // Delete file
return $response;
} else {
// Throw an exception or manage the error
}
}
You may need to add "ext-zip": "*" into your Composer file to use ZipArchive and extension=zip.so in your php.ini.
Answser inspired by Create a Response object with zip file in Symfony.
I think its better that you use
$zipFilesIds = $request->request->get('zipFiles')
foreach($zipFilesIds as $zipFilesId){
//your vérification here
}
with the post variable of your id of zip = 'zipFiles'. Its better of fetching all $_POST variables.
To complete vincent response, just add this right before returning response :
...
$response->headers->set('Content-length', filesize($zipName));
unlink($zipName);
return $response;
Work for me. Where $archive_file_name = 'your_path_to_file_from_root/filename.zip'.
$zip = new \ZipArchive();
if ($zip->open($archive_file_name, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE) === TRUE) {
foreach ($files_data as $file_data) {
$fileUri = \Drupal::service('file_system')->realpath($file_data['file_url']);
$filename = $file_data['folder'] . $file_data['filename'];
$zip->addFile($fileUri, $filename);
}
$zip->close();
}
$response = new Response();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', 'application/zip');
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($archive_file_name) . '"');
$response->headers->set('Content-length', filesize($archive_file_name));
// Send headers before outputting anything.
$response->sendHeaders();
$response->setContent(readfile($archive_file_name));
return $response;
Related
i am trying to download documents and pictures means files in zip using PHP in laravel application but it throughs the following error i checked everywhere online but not found any solution
ZipArchive::addFile(): Invalid or uninitialized Zip object
method
public function downoad()
$officeSpecs = DB::table('specifications_draged_files')->where('user_id', Auth::user()->id)->get();
$files = array();
foreach ($officeSpecs as $officeSpec) {
$files[] = $_SERVER['DOCUMENT_ROOT'] . '/public/uploads/zsdf_specs/' . Auth::user()->id . '/files/' . $officeSpec->draged_file;
}
$zipname = $_SERVER['DOCUMENT_ROOT'] . 'public/uploads/zsdf_specs/office_specs.zip';
$zip = new \ZipArchive();
$zip->open($zipname, \ZipArchive::CREATE);
if ($zip->open($zipname) != true) {
dd("Could not open archive");
}
$i= 0;
foreach ($files as $key => $file) {
if (file_exists($file)) {
$zip->addFile($file);
}
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
}
I am trying to download the zip file with many images.This code is working when i call the path in browser but not downloading when i call from Jquery ajax.Need to change or add anything in header?please help.
Controller:
public function actionZipdownload(){
$files = Yii::$app->request->post('imgsrc');
//it displays the URLs.
$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);
}
$zip->close();
header('Content-disposition: attachment; filename="my file.zip"');
header('Content-type: application/zip');
readfile($tmp_file);
unlink($tmp_file);
}
Jquery:
$.ajax({
url:url+'site/zipdownload',
data:{'imgsrc':imgsrc},
type:'POST',
success:function(data){
//alert(data);
}
});
In console response:
I just ignore the Jquery Ajax and done it by Html::a with two actions..When i am calling the url in a tag then the file got downloaded.And also done some changes in controller.
Views:
<?=Html::a('Create Zip',['site/zipdownload'],['class'=>'btn btn-danger pull-left'])?>
<?=Html::a('Download',['site/download'],['class'=>'btn btn-danger pull-left'])?>
Controller:
public function actionZipdownload(){
$files = Yii::$app->request->post('img_src');
$zip = new \ZipArchive();
$tmp_file = 'uploads/images.zip';
if(file_exists($tmp_file)){
$zip->open($tmp_file, ZipArchive::OVERWRITE);
}
else{
$zip->open($tmp_file, ZipArchive::CREATE);
}
$i=1;
foreach ($files as $file) {
$download_file = file_get_contents($file);
$fileParts = pathinfo($file);
$filename = $i.explode("?",$fileParts['filename'])[0];
$zip->addFromString($filename, $download_file);
$i++;
}
$zip->close();
}
public function actionDownload(){
$path = 'uploads/images.zip';
if(file_exists($path)){
\Yii::$app->response->sendFile($path)->send();
unlink($path);
}
else{
return $this->redirect(['site/dashboard']);
}
}
I'd like download multiple files in a zip but it doesn't work: the downloaded zip folder is still empty and is like opt/lampp/htdocs/MYPROJECT/... which one I'd like simple like /filename.zip
my controller, I just get all the file names from the DB and concatenate them with the directory name where they are physically saved:
$response = new Response();
// Get the entity manager
$em = $this->getDoctrine()->getManager();
//Collect all the result from the database and zip all the files related
$files = $em->getRepository('IballotCmsBundle:Result')->findAll();
$directory = __DIR__.'/../../../../web/uploads/pinkSheet';
//$directory = __DIR__.'/../temp/de.jpg';
$filename = 'all.zip';
$zip = new ZipArchive;
$zip->open($filename, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($directory.'/'.$file->getImage());
}
$zip->close();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '"');
$response->headers->set('Content-length', filesize($filename));
// Send headers before outputting anything
$response->sendHeaders();
$response->setContent(readfile($filename));
return $response;
I think it has to do with this line of code:
$filename = 'all.zip';
$zip = new ZipArchive;
$zip->open($filename, ZipArchive::CREATE);
You are trying to create a zip file called all.zip but you haven't specified the actual path. $filename should probably be something like this:
$filename = '/absolute/path/to/all.zip'
As for the structure of the zip file you'll need to read the docs which has a great example:
$zip = new ZipArchive;
if ($zip->open('test.zip') === TRUE) {
$zip->addFile('/path/to/index.txt', 'newname.txt');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
This will add the /path/to/index.txt file to the test.zip with the name newname.txt instead of /path/to/index.txt. You can use the second argument to control the directory (have a look at the comments in the docs for more info)
I'm trying to make a zip file download. So I try to make the code like this :
$zip = new ZipArchive();
$create = $zip->open($zipName, ZipArchive::CREATE);
if ($create === TRUE) { // check if the zip file is created
$basePath = $this->container->getParameter('kernel.root_dir').'/../marks/';
foreach ($listToken as $token) {
$file = $repoMarks->findByToken($token);
if($file) {
$fileName = $file[0]->getNameOnServer();
$filePath = $basePath . $fileName;
$root = realpath($this->container->getParameter('kernel.root_dir') . '/../marks');
$filePath = $root . '/' . $fileName;
if (file_exists($filePath)) {
$zip->addFile($filePath, $fileName);
}
}
}
$zip->close();
$root = realpath($this->container->getParameter('kernel.root_dir') . '/../marks');
$zipFilePath = $root . '/' . $zipName;
// prepare BinaryFileResponse
$response = new BinaryFileResponse($zipFilePath);
$response->trustXSendfileTypeHeader();
$response->headers->set('Cache-Control', 'public');
$response->headers->set('Content-type', 'application/zip');
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_INLINE,
$zipName,
iconv('UTF-8', 'ASCII//TRANSLIT', $zipName)
);
return $response;
}
I think it was successful. But, when I tried to open the zip file, There is an error like this An error occurred while loading the archive.
then I tried to make the code like this
$zip = new ZipArchive();
$create = $zip->open($zipName, ZipArchive::CREATE);
if ($create === TRUE) { // check if the zip file is created
$basePath = $this->container->getParameter('kernel.root_dir').'/../marks/';
foreach ($listToken as $token) {
$file = $repoMarks->findByToken($token);
if($file) {
$fileName = $file[0]->getNameOnServer();
$filePath = $basePath . $fileName;
$root = realpath($this->container->getParameter('kernel.root_dir') . '/../marks');
$filePath = $root . '/' . $fileName;
if (file_exists($filePath)) {
$zip->addFile($filePath, $fileName);
}
}
}
$zip->close();
header('Content-Type', 'application/zip');
header('Content-disposition: attachment; filename="' . $zipName . '"');
header('Content-Length: ' . filesize($zipName));
readfile($zipName);
}
but I got nothing. The same thing also happen when i change it to this :
$zip = new ZipArchive();
$create = $zip->open($zipName, ZipArchive::CREATE);
if ($create === TRUE) { // check if the zip file is created
$basePath = $this->container->getParameter('kernel.root_dir').'/../marks/';
foreach ($listToken as $token) {
$file = $repoMarks->findByToken($token);
if($file) {
$fileName = $file[0]->getNameOnServer();
$filePath = $basePath . $fileName;
$root = realpath($this->container->getParameter('kernel.root_dir') . '/../marks');
$filePath = $root . '/' . $fileName;
if (file_exists($filePath)) {
$zip->addFile($filePath, $fileName);
}
}
}
$zip->close();
header("HTTP/1.1 303"); // 303 is technically correct for this type of redirect
header("Location: http://{$_SERVER['HTTP_HOST']}/" . $fileName);
}
is there anyone who can help me to solve this download zip file problem?
An error occurred while loading the archive. occured in your clients side is because :
Your client doesn't have any application to open zip file.
zip file corrupt or missing extension.
There is possibility you never updated / fresh install. Try to
update it sudo apt-get update
Make sure your downloader app (like IDM or flareget) is working good. (I have problem with this, and when I disable the downloader app, it works) -By Asker
It is problem with client side, (connection or program error) or with the file it self. Try open the file using another PC.
i am trying to create a zip file(using php) for this i have written the following code:
$fileName = "1.docx,2.docx";
$fileNames = explode(',', $fileName);
$zipName = 'download_resume.zip';
$resumePath = asset_url() . "uploads/resume/";
//http://localhost/mywebsite/public/uploads/resume/
$zip = new ZipArchive();
if ($zip->open($zipName, ZIPARCHIVE::CREATE) !== TRUE) {
echo json_encode("Cannot Open");
}
foreach ($fileNames as $files) {
$zip->addFile($resumePath . $files, $files);
}
$zip->close();
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=".$zipName."");
header("Content-length: " . filesize($zipName));
header("Pragma: no-cache");
header("Expires: 0");
readfile($zipName);
exit;
however on a button click i am not getting anything..not even any error or message..
any help or suggestion would be a great help for me.. thanks in advance
Why not use the Zip Encoding Class in Codeigniter - it will do this for you
$name = 'mydata1.txt';
$data = 'A Data String!';
$this->zip->add_data($name, $data);
// Write the zip file to a folder on your server. Name it "my_backup.zip"
$this->zip->archive('/path/to/directory/my_backup.zip');
// Download the file to your desktop. Name it "my_backup.zip"
$this->zip->download('my_backup.zip');
https://www.codeigniter.com/user_guide/libraries/zip.html
... it work for me
public function downloadall(){
$createdzipname = 'myzipfilename';
$this->load->library('zip');
$this->load->helper('download');
$cours_id = $this->input->post('todownloadall');
$files = $this->model_travaux->getByID($cours_id);
// create new folder
$this->zip->add_dir('zipfolder');
foreach ($files as $file) {
$paths = 'http://localhost/uploads/'.$file->file_name.'.docx';
// add data own data into the folder created
$this->zip->add_data('zipfolder/'.$paths,file_get_contents($paths));
}
$this->zip->download($createdzipname.'.zip');
}
What is asset_url() function? Try to use APPPATH constant istead this function:
$resumePath = APPPATH."../uploads/resume/";
Add "exists" validation for file names:
foreach ($fileNames as $files) {
if (is_file($resumePath . $files)) {
$zip->addFile($resumePath . $files, $files);
}
}
Add exit() after:
echo json_encode("Cannot Open");
Also I think it's the better desision to use CI zip library User Guide. Simple example:
public function generate_zip($files = array(), $path)
{
if (empty($files)) {
throw new Exception('Archive should\'t be empty');
}
$this->load->library('zip');
foreach ($files as $file) {
$this->zip->read_file($file);
}
$this->zip->archive($path);
}
public function download_zip($path)
{
if (!file_exists($path)) {
throw new Exception('Archive doesn\'t exists');
}
$this->load->library('zip');
$this->zip->download($path);
}
Below scripting working ok in my local system. 1st remove asset_url() from $resumePath and set zip file store location relative path.
- Pass zip file name with its location path to $zip->open()
$fileName = "1.docx,2.docx";
$fileNames = explode(',', $fileName);
$zipName = 'download_resume.zip';
$resumePath = "resume/";
$zip = new ZipArchive();
if ($zip->open($resumePath.$zipName, ZIPARCHIVE::CREATE) !== TRUE) {
echo json_encode("Cannot Open");
}
foreach ($fileNames as $files) {
$zip->addFile($files, $files);
}
$zip->close();
/* create zip folder */
public function zip(){
$getImage = $this->cart_model->getImage();
$zip = new ZipArchive;
$auto = rand();
$file = date("dmYhis",strtotime("Y:m:d H:i:s")).$auto.'.zip';
if ($zip->open('./download/'.$file, ZipArchive::CREATE)) {
foreach($getImage as $getImages){
$zip->addFile('./assets/upload/photos/'.$getImages->image, $getImages->image);
}
$zip->close();
$downloadFile = $file;
$download = Header("Location:http://localhost/projectname/download/".$downloadFile);
}
}
model------
/* get add to cart image */
public function getImage(){
$user_id = $this->session->userdata('user_id');
$this->db->select('tbl_cart.photo_id, tbl_album_image.image as image');
$this->db->from('tbl_cart');
$this->db->join('tbl_album_image', 'tbl_album_image.id = tbl_cart.photo_id', 'LEFT');
$this->db->where('user_id', $user_id);
return $this->db->get()->result();
}