I am using PHP to create csvs files, put them into a folder and then zip the folder. This all works perfectly however I can't then get the ZIP the user created to auto download.
EDIT
it now works after taking out a redirect, however it lacks the .zip extension when being downloading, is there a way to force this?
My zips are stored in /zips in the root
Here is my code
// Add the folder we just created to a zip file.
$zip_name = 'groups_' . time();
$zip_directory = '/zips';
$zip = new zip( $zip_name, $zip_directory );
$zip->add_directory( 'group-csvs' );
$zip->save();
$zip_path = $zip->get_zip_path();
header( "Content-Description: File Transfer" );
header( "Content-type: application/zip" );
header( "Content-Disposition: attachment; filename=" . $zip_name . "");
header( "Content-Length: " . filesize( $zip_path ) );
readfile($zip_path);
Here is the get path method and constructor in my zip class
public function __construct( $file_name, $zip_directory)
{
$this->zip = new ZipArchive();
$this->path = dirname( __FILE__ ) . $zip_directory . $file_name . '.zip';
$this->zip->open( $this->path, ZipArchive::CREATE );
}
/**
* Get the absolute path to the zip file
* #return string
*/
public function get_zip_path()
{
return $this->path;
}
I don't get any errors, it just creates the zip then nothing happens
Add .zip extension to the name of your file:
$zip_name = 'groups_' . time() . '.zip';
The extension you are using in your custom zip class isnt being appended to variable in your main file.
Related
I try to develop something like dropbox(very basic one). For one file to download, it's really easy. what i want is: when client asks me big file, i zip file in server side then send to user. But if file is too big it takes too many times to zip them and send to user.
is there any way to send files while they are compressing?
thanks for your help. Here is my simple sample code
<?php
function createzip($files, $zip_file) {
$zip = new ZipArchive;
if($zip->open($zip_file, ZipArchive::CREATE) === TRUE) {
foreach($files as $file){
$zip->addFile($file);
}
$zip->close();
return true;
}
else return false;
}
$ss=array("jj.mp4");
createzip($ss,'archiv.zip');
if(filesize("archiv.zip")>3000){
$vv=array("archiv.zip");
createzip($vv,"bbb.zip");
}
?>
use do while loop in if statement. Until file size become a desired value. I don't understand how to use do while loop and does it make it that type of compresses. Please help me out.
I'm using this code for database backup with zipped type and download automaticly.
you can get referance this codes
<?php
$DBUSER="username";
$DBPASSWD="password";
$DATABASE="dbname";
$filename = "backup-" . date("d-m-Y") . ".sql.gz";
$mime = "application/x-gzip";
header( "Content-Type: " . $mime );
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
$cmd = "mysqldump -u $DBUSER --password=$DBPASSWD $DATABASE | gzip --best";
passthru( $cmd );
echo ('Backup Ok !');
exit(0);
?>
My PHP script keeps crashing/timing out, presumably because of the readfile.
My goal is to generate the zip, let the user download it, and remove the zip afterwards.
Code:
<?php
if(isset($_POST['version']) && isset($_POST['items']) && isset($_POST['identifier'])) {
$identifier = $_POST['identifier'];
$version = $_POST['version'];
$tmp = dirname(__FILE__) . "/download/";
$zipfile = $tmp . $identifier . ".zip";
$name = "Program v" . $version . ".zip";
$path = dirname(__FILE__) . "\\download\\template\\" . $version;
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::LEAVES_ONLY
);
$zip = new ZipArchive();
if ($zip->open($zipfile, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
foreach ($files as $name => $file) {
// Skip directories (they would be added automatically)
if (!$file->isDir()) {
// Get real and relative path for current file
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($path) + 1);
//echo "adding " . $file . " as " . $relativePath;
// Add current file to archive
$zip->addFile($file, $relativePath);
}
}
$zip->close();
} else {
die('Error: Unable to create zip file');
}
// Stream the file to the client
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($zipfile));
header('Content-disposition: attachment; filename="'.$name.'"');
readfile($zipfile);
exit;
}
Everything works up until the download part. The zip file gets generated fine on the server, when trying to download it, it crashes.
Sometimes it shows an error in my logs, which is telling me it expects a valid path and that an object is given. Even though it strictly puts out a string (the path).
Note: The file is less than 300 KiB so I highly doubt the webserver is running out of memory.
I'm pretty lost, any help is highly appreciated.
The problem is with the generation of the ZIP file.
The addFile method requires a file path as its first parameter, not an object. See documentation:
bool ZipArchive::addFile ( string $filename [, string $localname = NULL [, int $start = 0 [, int $length = 0 ]]] )
http://php.net/manual/en/ziparchive.addfile.php
Therefore in your case the correct expression would be:
$zip->addFile($filePath, $relativePath);
In laravel i am making an application that uploads a file and the user can download that same file.
But each time i click to download i get this error.
The view code:
<h5>Download</h5>
The route code:
Route::get('/download/{fileName}/{fileType}', 'FilesharingsController#download');
The controller code:
public function download($fileName, $fileType){
$downloadPath = public_path(). '/assests/' . $fileName ;
$headers = array(
'Content-Type: application/octat-stream',
'Content-Type: application/pdf'
);
return Response::download($downloadPath, $fileName . '.' . $fileType, $headers);
}
Please not that when i upload a file i remove its extension.
Example: if i upload 'sample.pdf' it is saved as 'sample'.
I have no clue what is wrong as the path in the error is the correct path.
And the file exists in that path. Plz help
The folder Structure:
And the code used to upload the file is:
// Save uploaded file
if ($this->request->hasFile('file') && $this->request->file('file')->isValid()) {
$destinationPath = public_path() . '/assests/';
$fileName = $filesharing->fileName . '.' . $this->request->file('file')->guessClientExtension();
$this->request->file('file')->move($destinationPath, $fileName);
}
Your $downloadPath is missing the file extension. The second parameter of Response::download is the file name shown to the user.
Your variable should look like this:
$downloadPath = public_path() . '/assets' . $fileName . '.' . $fileType;
I've hosted my all code files on one server whose domain is like example.com and I'm at one of those html pages. I want some files of example.com to move on another server whose domain is like example2.com. I've searched through Internet but I couldn't find any good solution. Please tell me is this possible without FTP client or without browser where we upload files manually. Or is there any way to submit file from HTML form from one server to another like if on action we'll write
<form action="http://example2.com/action_page.php">
Any help would be much appreciated.
If you set the contents of this file: example2.com/action_page.php to:
<?php
$tobecopied = 'http://www.example.com/index.html';
$target = $_SERVER['DOCUMENT_ROOT'] . '/contentsofexample/index.html';
if (copy($tobecopied, $target)) {
//File copied successfully
}else{
//File could not be copied
}
?>
and run it, through command line or cron (as you have written a php related question, yet banned use of browsers!) it should copy the contents of example.com/index.html to a directory of your site (domain: example2.com) called contentsofexample.
N.B. If you wanted this to copy the whole website you should place it in a for loop
There are still 2 possible ways which can used to copy your files from another server.
-One is to remove your .htaccess file from example.com or allow access to all files(by modifying your .htaccess file).
-Access/Read those files via their respective URLs, and save those files using 'file_get_contents()' and 'file_put_contents()' methods. But this approach will made all files accessible to other people too.
$fileName = 'filename.extension';
$sourceFile = 'http://example.com/path-to-source-folder/' . $fileName;
$targetLocation = dirname( __FILE__ ) . 'relative-path-destination-folder/' + $fileName;
saveFileByUrl($sourceFile, $targetLocation);
function saveFileByUrl ( $source, $destination ) {
if (function_exists('curl_version')) {
$curl = curl_init($fileName);
$fp = fopen($destination, 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
} else {
file_put_contents($destination, file_get_contents($source));
}
}
Or you can create a proxy/service on example.com to read a specific file after validating a pass key or username/password combination(whatever as per your requirement).
//In myproxy.php
extract($_REQUEST);
if (!empty($passkey) && paskey == 'my-secret-key') {
if (!empty($file) && file_exists($file)) {
if (ob_get_length()) {
ob_end_clean();
}
header("Pragma: public");
header( "Expires: 0");
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0");
header( 'Content-Type: ' . mime_content_type($file) );
header( "Content-Description: File Transfer");
header( 'Content-Disposition: attachment; filename="' . basename( $file ) . '"' );
header( "Content-Transfer-Encoding: binary" );
header( 'Accept-Ranges: bytes' );
header( "Content-Length: " . filesize( $file ) );
readfile( $file );
exit;
} else {
// File not found
}
} else {
// You are not authorised to access this file.
}
you can access that proxy/service by url 'http://example.com/myproxy.php?file=filename.extension&passkey=my-secret-key'.
You can exchange files between servers by also using zip method.
You own both servers so you shouldn't have security issues.
On the server that hosts the file or folder you want, create a php script and create a cron job for it. Sample code below:
<?php
/**
* ZIP All content of current folder
/* ZIP File name and path */
$zip_file = 'myfiles.zip';
/* Exclude Files */
$exclude_files = array();
$exclude_files[] = realpath( $zip_file );
$exclude_files[] = realpath( 'somerandomzip.php' );
/* Path of current folder, need empty or null param for current folder */
$root_path = realpath( '' ); //or $root_path = realpath( 'folder_name' ); if the file(s) are in a particular folder residing in the root
/* Initialize archive object */
$zip = new ZipArchive;
$zip_open = $zip->open( $zip_file, ZipArchive::CREATE );
/* Create recursive files list */
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $root_path ),
RecursiveIteratorIterator::LEAVES_ONLY
);
/* For each files, get each path and add it in zip */
if( !empty( $files ) ){
foreach( $files as $name => $file ) {
/* get path of the file */
$file_path = $file->getRealPath();
/* only if it's a file and not directory, and not excluded. */
if( !is_dir( $file_path ) && !in_array( $file_path, $exclude_files ) ){
/* get relative path */
$file_relative_path = str_replace( $root_path, '', $file_path );
/* Add file to zip archive */
$zip_addfile = $zip->addFile( $file_path, $file_relative_path );
}
}
}
/* Create ZIP after closing the object. */
$zip_close = $zip->close();
?>
Create another php script and cron job on the server to receive the copy as below:
/**
* Transfer Files Server to Server using PHP Copy
*
*/ /* Source File URL */
$remote_file_url = 'url_of_the_zipped';
/* New file name and path for this file */
$local_file ='myfiles.zip';
/* Copy the file from source url to server */
$copy = copy($remote_file_url, $local_file );
/* Add notice for success/failure */
if( !$copy ) {
echo "Failed to copy $file...\n"; }
else{
echo "Copied $file successfully...\n"; }
$file = 'myfiles.zip';
$path = pathinfo( realpath( $file ), PATHINFO_DIRNAME );
$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) {
$zip->extractTo( $path );
$zip->close();
echo "$file extracted to $path"; }
else {
echo "Couldn't open $file";
}
?>
Voila!
<?php
/* Source File URL */
$remote_file_url = 'http://origin-server-url/files.zip';
/* New file name and path for this new file */
$local_file = 'files.zip';
/* Copy the file from source url to server */
$copy = copy( $remote_file_url, $local_file );
/* Add notice for success/failure */
if( !$copy ) {
echo "Doh! failed to copy $file...\n";
}
else{
echo "WOOT! Thanks Munshi and OBOYOB! success to copy $file...\n";
}
?>
I've implemented the code to Create Zip Folder of Files (from db path) and download zipped folder in PHP. I am using Ubuntu OS.
public function actionDownload($id) {
$model = $this->loadModel($id, 'Document');
$results = array();
$results = $this->createZip($model);
$zip = $results[0];
$size = filesize($zip->filename);
if ($zip->filename) {
header("Content-Description: File Transfer");
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"" . $model->name . "\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $size);
ob_end_flush();
flush();
readfile($zip->filename);
// To Store User Transaction Data
//$this->saveTransaction();
//ignore_user_abort(true);
unlink($zip->filename);
$zip->close();
// Delete newly created files
foreach ($results[1] as $fl) {
unlink($fl);
}
}
}
public function createZip($model) {
$data = Document::model()->findAll('parent_folder=:id', array(':id' => (int) $model->document_id));
$fileArr = array();
foreach ($data as $type) {
$fileArr[] = $type->path;
}
$filestozip = $fileArr; // FILES ARRAY TO ZIP
$path = Yii::app()->basePath . DS . 'uploads' . DS . Yii::app()->user->id;
//$model->path = trim(DS . $path . DS); // DIR NAME TO MOVE THE ZIPPED FILES
$zip = new ZipArchive();
$files = $filestozip;
$zipName = "USR_" . Yii::app()->user->id . "_" . $model->name . "_" . date("Y-m-d") . ".zip";
$fizip = $path . DS . $zipName;
if ($zip->open($fizip, ZipArchive::CREATE) === TRUE) {
foreach ($files as $fl) {
if (file_exists($fl)) {
$zip->addFile($fl, basename($fl)) or die("<p class='warning'>ERROR: Could not add file: " . $fl . "</p>");
}
}
}
$resultArr = array();
$resultArr[] = $zip;
$resultArr[] = $files;
return $resultArr;
}
The Zip creation code working fine and its creating zip file there but the issue is owner of the file is www-data and file permission is Read-Only.
When I am trying to set chmod($zip->filename, 0777) permission to that zipped folder then its showing an error?
Error 500
chmod(): No such file or directory
In fact file is present there.
If I am trying without chmod() then its showing me error of
Error 500
filesize(): stat failed for /home/demo.user/myapp/public_html/backend/uploads/1/USR_1_kj_2013-12-23.zip
and then its not downloading the zip file.
This is really weird issue I am facing. It seem to be some permission issue of zip file that's why filesize() is not able to perform any operation on that file but strange thing is chmod() also not working.
Need Help on this.
Thanks
If www-data has read permissions, the file permissions are properly set. No chmod required.
You need to call $zip->close() before the download, as only on $zip->close() the file will be written to disk. readfile() will not work unless the file is written to disk.
A smarter way, could be to create the archive in memory only using the php://memory stream wrapper. However this is only an option if you need the archive for a single download only.