copy file from one server to another programmatically in php - php

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";
}
?>

Related

How to create zip file from a large folder using Codeigniter and PHP?

I'm trying to create zip file from a large folder which size almost 2GB. My code is working well on the localhost but it's not working on the server(Cpanel). In server, it's creating a zip file which size is only 103 MB out of 2GB. According to my strategy, first of all, I'm creating a backup folder recursively named "system_backup". And the backup folder is creating well without any problem. The next is, to create the zip file of 'system_backup' folder by calling the function ZipData and stored it to another folder. In this time, it's not creating the zip file properly.
After that, the function rrmdir will be called. And it will delete the 'system_backup' folder recursively. And the deletion is not working properly as well. And, in localhost, it works well.
Then, when I'm trying to download the created zip file by the function download_file, it also not download properly. It's downloaded as a broken zip file. And, in localhost, it also works well.
I have already checked the read and write permission of folders and files.
The code is given below:-
public function backup_app(){
//Backup System
ini_set('memory_limit', '-1');
set_time_limit(0);
$this->recurse_copy(FCPATH,'system_backup');
$backup_name = 'Customs-system-backup-on_'. date("Y-m-d-H-i-s") .'.zip';
$path = FCPATH.'system_backup';
$destination = FCPATH.'bdCustomsBackup/'.$backup_name;
$this->zipData($path, $destination);
//Delete directory
$this->rrmdir($path);
$message = "Application Backup on ".date("Y-m-d-H-i-s");
$this->submit_log($message);
echo 1;
}
function zipData($source, $destination) {
if (extension_loaded('zip')) {
if (file_exists($source)) {
$zip = new ZipArchive();
if ($zip->open($destination, ZIPARCHIVE::CREATE)) {
$source = realpath($source);
if (is_dir($source)) {
$iterator = new RecursiveDirectoryIterator($source);
// skip dot files while iterating
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
$counter = 1;
foreach ($files as $file) {
$file = realpath($file);
if (is_dir($file)) {
$zip->addEmptyDir(str_replace($source . '/', 'system_backup/', $file . '/'));
} else if (is_file($file)) {
$zip->addFromString(str_replace($source . '/', 'system_backup/', $file), file_get_contents($file));
}
}
} else if (is_file($source)) {
$zip->addFromString(basename($source), file_get_contents($source));
}
}
return $zip->close();
}
}
return false;
}
public function recurse_copy($src,$dst) {
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' ) && ( $file != $dst ) && ( $file != "bdCustomsBackup" )) {
if ( is_dir($src . '/' . $file) ) {
$this->recurse_copy($src . '/' . $file, $dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
public function rrmdir($src) {
$dir = opendir($src);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
$full = $src . '/' . $file;
if ( is_dir($full) ) {
$this->rrmdir($full);
}
else {
unlink($full);
}
}
}
closedir($dir);
rmdir($src);
}
public function download_file($file){
$message = "Download ".$file." on ".date("Y-m-d-H-i-s");
$this->submit_log($message);
$path = FCPATH.'bdCustomsBackup/'.$file;
$this->load->helper('download_helper');
force_download($file, $path);
}
Here is the custom download_helper:-
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('force_download'))
{
function force_download($filename = '', $file = '')
{
if ($filename == '' OR $file == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
#include(APPPATH.'config/mimes'.EXT);
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".filesize($file));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".filesize($file));
}
readfile_chunked($file);
die;
}
}
if ( ! function_exists('readfile_chunked'))
{
function readfile_chunked($file, $retbytes=TRUE)
{
$chunksize = 1 * (1024 * 1024);
$buffer = '';
$cnt =0;
$handle = fopen($file, 'r');
if ($handle === FALSE)
{
return FALSE;
}
while (!feof($handle))
{
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes)
{
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes AND $status)
{
return $cnt;
}
return $status;
}
}
/* End of file download_helper.php */
/* Location: ./application/helpers/download_helper.php */
The below code is using PHP:
$zip = new ZipArchive;
if ($zip->open('test_new.zip', ZipArchive::CREATE) === TRUE)
{
// Add files to the zip file
$zip->addFile('test.txt');
$zip->addFile('test.pdf');
// Add random.txt file to zip and rename it to newfile.txt
$zip->addFile('random.txt', 'newfile.txt');
// Add a file new.txt file to zip using the text specified
$zip->addFromString('new.txt', 'text to be added to the new.txt file');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
Line 1 creates an object of the ZipArchive class
Line 2 opens a file with filename as test_new.zip so that we can add files to it. The flag ZipArchive::CREATE specifies that we want to create a new zip file
Lines 5 & 6 are used to add files to the zip file
Line 9 is used to add a file with name random.txt to the zip file and rename it in the zipfile as newfile.txt
Line 12 is used to add a new file new.txt with contents of the file as ‘text to be added to the new.txt file’
Line 15 closes and saves the changes to the zip file
Note: Sometimes there can be issues when using relative paths for files. If there are any issues using paths then we can also use absolute paths for files
Overwrite an existing zip file
If you want to overwrite an existing zip file then we can use code similar to following. The flag ZipArchive::OVERWRITE overwrites the existing zip file.
$zip = new ZipArchive;
if ($zip->open('test_overwrite.zip', ZipArchive::OVERWRITE) === TRUE)
{
// Add file to the zip file
$zip->addFile('test.txt');
$zip->addFile('test.pdf');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
This code will create a file test_overwrite.zip if it already exists the file will be overwritten with this new file
Create a new zip file and add files to be inside a folder
$zip = new ZipArchive;
if ($zip->open('test_folder.zip', ZipArchive::CREATE) === TRUE)
{
// Add files to the zip file inside demo_folder
$zip->addFile('text.txt', 'demo_folder/test.txt');
$zip->addFile('test.pdf', 'demo_folder/test.pdf');
// Add random.txt file to zip and rename it to newfile.txt and store in demo_folder
$zip->addFile('random.txt', 'demo_folder/newfile.txt');
// Add a file demo_folder/new.txt file to zip using the text specified
$zip->addFromString('demo_folder/new.txt', 'text to be added to the new.txt file');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
The above code will add different files inside the zip file to be inside a folder demo_folder
The 2nd parameter to addfile function can be used to store the file in a new folder
The 1st parameter in the addFromString function can be used to store the file in a new folder
Create a new zip file and move the files to be in different folders
$zip = new ZipArchive;
if ($zip->open('test_folder_change.zip', ZipArchive::CREATE) === TRUE)
{
// Add files to the zip file
$zip->addFile('text.txt', 'demo_folder/test.txt');
$zip->addFile('test.pdf', 'demo_folder1/test.pdf');
// All files are added, so close the zip file.
$zip->close();
}
Explanation of code
We store the file test.txt into demo_folder and test.pdf into demo_folder1
Create a zip file with all files from a directory
$zip = new ZipArchive;
if ($zip->open('test_dir.zip', ZipArchive::OVERWRITE) === TRUE)
{
if ($handle = opendir('demo_folder'))
{
// Add all files inside the directory
while (false !== ($entry = readdir($handle)))
{
if ($entry != "." && $entry != ".." && !is_dir('demo_folder/' . $entry))
{
$zip->addFile('demo_folder/' . $entry);
}
}
closedir($handle);
}
$zip->close();
}
Explanation of code
Lines 5-16 opens a directory and creates a zip file with all files within that directory
Line 5 opens the directory
Line 7 gets the name of each file in the dir
Line 9 skips the “.” and “..” and any other directories
Line 11 adds the file into the zip file
Line 14 closes the directory
Line 17 closes the zip file

Downloading a folder with phpseclib Net_SFTP.get does not work

I am trying to access a file in an SFTP folder server using phpseclib. But when I try using $sftp->get, it returns false. I am not sure how to debug the problem at all.
public function get_file_from_ftps_server()
{
$sftp = new \phpseclib\Net\SFTP(getenv('INSTRUM_SERVER'));
if (!$sftp->login(getenv('INSTRUM_USERNAME'), getenv('INSTRUM_PASSWORD'))) {
exit('Login Failed');
}
$this->load->helper('file');
$root = dirname(dirname(__FILE__));
$root .= '/third_party/collections_get/';
$path_to_server = 'testdownload/';
$result = $sftp->get($path_to_server, $root);
var_dump($result);
}
In the $result, I get a false and I am not sure why its happening, I read their documentation but still not sure. Root is the directory where I want my information to be stored. Right now I only added a trial.xml file there, but also wondering how can I get multiple files if its in the folder.
Here is a picture of the server structure:
Normally when I use sftp, I normally change directory and then try to download the information.
$sftp->pwd(); // This will show you are in the root after connection.
$sftp->chdir('./testdownload'); // this will go inside the test directory.
$get_path = $sftp->pwd()
//If you want to download multiple data, use
$x = $sftp->nlist();
//Loop through `x` and then download the file using.
$result = $sftp->get($get_path); // Normally I use the string information that is returned and then download using
file_put_contents($root, $result);
// Root is your directory, and result is the string.
The Net_SFTP.get method can download a single file only. You cannot use it to download a whole directory.
If you want to download whole directory, you have to use one of the "list" methods (Net_SFTP.nlist or Net_SFTP.rawlist) to retrieve list of files and then download the files one-by-one.
<?php
use phpseclib\Net\SFTP;
$sftp = new SFTP("server");
if(!$sftp->login("username", "password")) {
throw new Exception("Connection failed");
}
// The directory you want to download the contents of
$sftp->chdir("/remote/system/path/");
// Loop through each file and download
foreach($sftp->nlist() as $file) {
if($file != "." && $file != "..")
$sftp->get("/remote/system/path/$file", "/local/system/path/$file");
}
?>
I'm a bit late but nonetheless I wanted to share this.
The approach I take is to use zip files to download folders. The reason for this is that you will have a feedback that something is being downloaded.
If you don't want that, simply remove the things related to zip. Then, remove the headers and replace them with $sftp->get("remote/file", "local/file");
<?PHP
use phpseclib\Net\SFTP;
$sftp = new SFTP("IP:Port");
if(!$sftp->login("username", "password")) throw new Exception("Connection failed");
# Create directory variable
$directory = "/remote/path/";
# Set directory
$sftp->chdir($directory);
# File Name
$name = 'file';
# Retrieve file
$file = $sftp->get('file');
# Check if is folder
if ($sftp->is_dir($file)) {
# Temporarily file
$tmp = sys_get_temp_dir()."\\yourSite_".rand().".zip";
# Create new Zip Archive.
$zip = new ZipArchive();
# Open new Zip file
$zip->open($tmp, ZipArchive::CREATE | ZipArchive::OVERWRITE);
function recursive($src, $zip, $sftp) {
# Loop Through files
foreach ($sftp->nlist($src) as $file) {
# Skip . & ..
if ($file == "." || $file == "..") continue;
if (!$sftp->is_file($src . "/" . $file)) {
# Make directory
$zip->addEmptyDir($src . "/" . $file);
# Run the loop again
recursive($src . "/" . $file, $zip, $sftp);
} else {
# Add file to zip within folder
$zip->addFromString($src . "/" . $file, $sftp->get($src . "/" . $file));
}
}
}
# Run Recursive loop
recursive($name, $zip, $sftp);
# Close zip file
$zip->close();
header('Content-Description', 'File Transfer');
header('Content-type', 'application/zip');
header('Content-Disposition', 'attachment; filename="' . $name . '.zip"');
header('Content-length', filesize($tmp));
echo file_get_contents($tmp);
# Delete temporarily file
unlink($tmp);
return;
}
# Otherwise download single file
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"". $name ."\"");
echo $file;
return;

Extract specific files in zip (include sub directories)

I want to extract only images from a zip file but i also want it to extract images that are found in subfolders as well.How can i achieve this based on my code below.Note: i am not trying to preserve directory structure here , just want to extract any image found in zip.
//extract files in zip
for ($i = 0; $i < $zip->numFiles; $i++) {
$file_name = $zip->getNameIndex($i);
$file_info = pathinfo($file_name);
//if ( substr( $file_name, -1 ) == '/' ) continue; // skip directories - need to improve
if (in_array($file_info['extension'], $this->config->getValidExtensions())) {
//extract only images
copy("zip://" . $zip_path . "#" . $file_name, $this->tmp_dir . '/images/' . $file_info['basename']);
}
}
$zip->close();
Edit
My code works fine all i need to know is how to make ziparchive go in subdirectories as well
Your code is correct. I have created a.zip with files a/b/c.png, d.png:
$ mkdir -p a/b
$ zip -r a.zip d.png a
adding: d.png (deflated 4%)
adding: a/ (stored 0%)
adding: a/b/ (stored 0%)
adding: a/b/c.png (deflated 8%)
$ unzip -l a.zip
Archive: a.zip
Length Date Time Name
--------- ---------- ----- ----
122280 11-05-2016 14:45 d.png
0 11-05-2016 14:44 a/
0 11-05-2016 14:44 a/b/
36512 11-05-2016 14:44 a/b/c.png
--------- -------
158792 4 files
The code extracted both d.png and c.png from a.zip into the destination directory:
$arch_filename = 'a.zip';
$dest_dir = './dest';
if (!is_dir($dest_dir)) {
if (!mkdir($dest_dir, 0755, true))
die("failed to make directory $dest_dir\n");
}
$zip = new ZipArchive;
if (!$zip->open($arch_filename))
die("failed to open $arch_filename");
for ($i = 0; $i < $zip->numFiles; ++$i) {
$path = $zip->getNameIndex($i);
$ext = pathinfo($path, PATHINFO_EXTENSION);
if (!preg_match('/(?:jpg|png)/i', $ext))
continue;
$dest_basename = pathinfo($path, PATHINFO_BASENAME);
echo $path, PHP_EOL;
copy("zip://{$arch_filename}#{$path}", "$dest_dir/{$dest_basename}");
}
$zip->close();
Testing
$ php script.php
d.png
a/b/c.png
$ find ./dest -type f
./dest/d.png
./dest/c.png
So the code is correct, and the issue must be somewhere else.
Based upon file extension ( not necessarily the most reliable method ) you might find the following helpful.
/* source zip file and target location for extracted files */
$file='c:/temp2/experimental.zip';
$destination='c:/temp2/extracted/';
/* Image file extensions to allow */
$exts=array('jpg','jpeg','png','gif','JPG','JPEG','PNG','GIF');
$files=array();
/* create the ZipArchive object */
$zip = new ZipArchive();
$status = $zip->open( $file, ZIPARCHIVE::FL_COMPRESSED );
if( $status ){
/* how many files are in the archive */
$count = $zip->numFiles;
for( $i=0; $i < $count; $i++ ){
try{
$name = $zip->getNameIndex( $i );
$ext = pathinfo( $name, PATHINFO_EXTENSION );
$basename = pathinfo( $name, PATHINFO_BASENAME );
/* store a reference to the file name for extraction or copy */
if( in_array( $ext, $exts ) ) {
$files[]=$name;
/* To extract files and ignore directory structure */
$res = copy( 'zip://'.$file.'#'.$name, $destination . $basename );
echo ( $res ? 'Copied: '.$basename : 'unable to copy '.$basename ) . '<br />';
}
}catch( Exception $e ){
echo $e->getMessage();
continue;
}
}
/* To extract files, with original directory structure, uncomment below */
if( !empty( $files ) ){
#$zip->extractTo( $destination, $files );
}
$zip->close();
} else {
echo $zip->getStatusString();
}
This will allow for you traverse all of the directories in a path and will search for anything that is an image/has the extensions that you have defined. Since you told the other use that you have the ziparchive portion done I have omitted that...
<?php
function traverse($path, $images = [])
{
$files = array_diff(scandir($path), ['.', '..']);
foreach ($files as $file) {
// check if the file is an image
if (in_array(strtolower(pathinfo($file, PATHINFO_EXTENSION)), ['jpg', 'jpeg', 'png', 'gif'])) {
$images[] = $file;
}
if (is_dir($path . '/' . $file)) {
$images = traverse($path . '/' . $file, $images);
}
}
return $images;
}
$images = traverse('/Users/kyle/Downloads');
You want to follow this process:
Get all of the files in the current working directory
If a file in the CWD is an image add it to the images array
If a file in the CWD is a directory, recursively call the traverse function and looking for images in the directory
In the new CWD look for images, if the file is a directory recurse, etc...
It is important to keep track of the current path so you're able to call is_dir on the file. Also you want to make sure not to search '.' or '..' or you will never hit the base recursion case/it will be infinite.
Also this will not keep the directory path for the image! If you want to do that you should do $image[] = $path . '/' . $file;. You may want to do that and then get all of the file contents wants the function finishes running. I wouldn't recommend sorting the contents in the $image array because it could use an absurd amount of memory.
First thing to follow a folder is to regard it - your code does not do this.
There are no folders in a ZIP (in fact, even in the file system a "folder" IS a file, just a special one). The file (data) has a name, maybe containing a path (most likely a relative one). If by "go in subdiectories" means, that you want the same relative folder structure of the zipped files in your file system, you must write code to create these folders. I think copy won't do that for you automatically.
I modified your code and added the creation of folders. Mind the config variables I had to add to make it runable, configure it to your environment. I also left all my debug output in it. Code works for me standalone on Windows 7, PHP 5.6
error_reporting(-1 );
ini_set('display_errors', 1);
$zip_path = './test/cgiwsour.zip';
$write_dir = './test'; // base path for output
$zip = new ZipArchive();
if (!$zip->open($zip_path))
die('could not open zip file '.PHP_EOL);
$valid_extensions = ['cpp'];
$create_subfolders = true;
//extract files in zip
for ($i = 0; $i < $zip->numFiles; $i++) {
$file_name = $zip->getNameIndex($i);var_dump($file_name, $i);
$file_info = pathinfo($file_name);//print_r($file_info);
//if ( substr( $file_name, -1 ) == '/' ) continue; // skip directories - need to improve
if (isset($file_info['extension']) && in_array(strtolower($file_info['extension']), $valid_extensions)) {
$tmp_dir = $write_dir;
if ($create_subfolders) {
$dir_parts = explode('/', $file_info['dirname']);
print_r($dir_parts);
foreach($dir_parts as $folder) {
$tmp_dir = $tmp_dir . '/' . $folder;
var_dump($tmp_dir);
if (!file_exists($tmp_dir)) {
$res = mkdir($tmp_dir);
var_dump($res);
echo 'created '.$tmp_dir.PHP_EOL;
}
}
}
else {
$tmp_dir .= '/' . $file_info['dirname'];
}
//extract only images
$res = copy("zip://" . $zip_path . "#" . $file_name, $tmp_dir . '/' . $file_info['basename']);
echo 'match : '.$file_name.PHP_EOL;
var_dump($res);
}
}
$zip->close();
Noticeable is, that mkdir() calls may not work flawlessly on all systems due to access/rights restrictions.

Auto download CSV file after link is clicked

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.

Don't want directory structure with ZipArchive

I am trying to make file download script that collection all the files and download a zip file that has that collection of files not all the directory structure..
i have the file in download/folder1/folder1/filename.extension
here is my PHP codes:
if( !extension_loaded('zip') ){
echo "<script>alert('Error: Please contact to the Server Administrator!');</script>";
exit;
}
$zip = new ZipArchive;
if( $zip->open($zipname, ZipArchive::OVERWRITE) === TRUE ){
foreach( $files as $file ){
$zip->addFile( BASE_PATH.$file_path.'/'.$file, $file );
}
$zip->close();
} else {
echo "<script>alert('Error: problem to create zip file!');</script>";
exit;
}
this code gives me the structure like this:
it gives the complete path of wamp(including the path director and files) and the files, i just want to add the files not the directory..
Can someone tell me what i missed??
Every time download link comes with the unique download key, i just add the unique_key with the name of download.zip file and its working...
// $db_secret_key Random Unique Number
$zipname = $db_secret_key."_download.zip";
if( !extension_loaded('zip') ){
echo "<script>alert('Error: Please contact to the Server Administrator!');</script>";
exit;
}
$zip = new ZipArchive;
if( $zip->open($zipname, ZipArchive::CREATE) === TRUE ){
foreach( $files as $file ){
$zip->addFile( BASE_PATH.$file_path.'/'.$file, $file );
}
$zip->close();
// Force Download
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;
} else {
echo "<script>alert('Error: problem to create zip file!');</script>";
exit;
}

Categories