I am trying to take heavy files backup with PHP but for more then 1 GB files I am getting PHP timeout error how I can resolve this please help me with complete code. below is my complete code.
please check my code and suggest code change that can help me. I have tried number of code and functions but nothing happen. I am very frustrated for this task
#ini_set('max_execution_time', 60000000);
#ini_set('memory_limit', '10000M');
function zipData($source, $destination, $ignores = [])
{
if (extension_loaded('zip') === true) {
if (file_exists($source) === true) {
$zip = new ZipArchive();
if ($zip->open($destination, ZIPARCHIVE::CREATE) === true) {
$source = realpath($source);
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = realpath($file);
$ignored = false;
foreach ($ignores as $ignore) {
if (strpos($file, $ignore)) {
$ignored = true;
break;
}
}
if ($ignored) {
continue;
}
if (is_dir($file) === true) {
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
} else if (is_file($file) === true) {
// $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
$zip->addFile($file, str_replace($source . DIRECTORY_SEPARATOR, '', $file));
}
}
} else if (is_file($source) === true) {
//$zip->addFromString(basename($source), file_get_contents($source));
$zip->addFile($source, basename($source));
}
}
return $zip->close();
}
}
return false;
}
$backup_path = 'create_backup_site/site_backup_' . date('Y-m-d');
if (!file_exists($backup_path)) {
mkdir($backup_path, 0777, true);
}
$name_zip_file = $backup_path . '/' . date("j-n-Y") . '-backup.zip';
$ignorearray = array('create_backup');
$dir = '../../test/wp-content/uploads';
function listFolderFiles($dir, $backup_path)
{
$fileInfo = scandir($dir);
$allFileLists = [];
$allpathname = [];
foreach ($fileInfo as $folder) {
if ($folder !== '.' && $folder !== '..') {
if (is_dir($dir . DIRECTORY_SEPARATOR . $folder) === true) {
$allFileLists[$folder] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder, $backup_path);
//$allFileLists[$folder]['file_path'] = $dir . DIRECTORY_SEPARATOR . $folder;
$allpathname[] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder, $backup_path);
} else {
$filesize = filesize($dir . '/' . $folder);
// if ($filesize < 1073741824) {
// if ($filesize < 536870912) { //512 mb size check
if ($filesize < 1048576) { //512 mb size check
$allFileLists[$folder] = array("file_name" => $folder, "file_path" => $dir . DIRECTORY_SEPARATOR);
$allpathname[] = $folder;
}
}
}
}
return $allFileLists;
$dirlist = listFolderFiles($dir, $backup_path);
$final_array = array();
$final_array_path = array();
foreach ($dirlist as $key => $value) {
if (is_array($value)) {
foreach ($value as $newkey => $newvalue) {
foreach ($newvalue as $key2 => $val2) {
if ($val2['file_name'] != '.') {
if (strlen($val2['file_name']) > 2) {
$final_array[] = array('file_name' => $val2['file_name'], 'file_path' => $val2['file_path']);
$filepatrh = str_replace($val2['file_name'],"",$val2['file_path']);
}
}
}
if ($newvalue['file_name'] != '.') {
if (strlen($newvalue['file_name']) > 2) {
$final_array[] = array('file_name' => $newvalue['file_name'], 'file_path' => $newvalue['file_path']);
$filepatrh = str_replace($newvalue['file_name'],"",$newvalue['file_path']);
}
}
}
} else {
}
if ($value['file_name'] != '.') {
if (strlen($value['file_name']) > 2) {
$final_array[] = array('file_name' => $value['file_name'], 'file_path' => $value['file_path']);
$filepatrh = str_replace($value['file_name'],"",$value['file_path']);
}
}
}
foreach ($final_array as $final_key => $final_value) {
zipData($final_value['file_path'], $backup_path . '/uploads.zip', $ignorearray);
echo 'Finished.';
}
}
Related
I was wondering if it is possible to add timestamp of the file creation/update when using ftp_nlist().
My code right now:
function ftp_get_recursive_paths($conn, $path, $max_level = 0){
$files = array();
if($max_level < 0) return $files;
if($path !== '/' && $path[strlen($path) - 1] !== '/') $path .= '/';
$files_list = ftp_nlist($conn, $path);
foreach($files_list as $f){
if($f !== '.' && $f !== '..' && $f !== $path){
if(strpos($f, '.') === FALSE){
$files[$f] = ftp_get_recursive_paths($conn, $f, $max_level-1);
}else{
$files[] = basename($f);
}
}
}
return $files;
}
And output:
(
[/folder1] => (
[0] => file.php
[1] => file2.php
)
[/folder2] => (
[/folder2/2] => (
)
)
)
Try with the following code:
function ftp_get_recursive_paths($conn, $path, $max_level = 0){
$files = array();
if($max_level < 0) return $files;
if($path !== '/' && $path[strlen($path) - 1] !== '/') $path .= '/';
$files_list = ftp_nlist($conn, $path);
foreach($files_list as $f){
if($f !== '.' && $f !== '..' && $f !== $path){
if(strpos($f, '.') === FALSE){
$files[$f] = ftp_get_recursive_paths($conn, $f, $max_level-1);
}else{
$mdate = ftp_mdtm($conn, $f);
$files[] = basename($f) . " - " . date("m-d-Y H:i:s.", $mdate);
}
}
}
return $files;
}
I am writing a function to recursively copy a specific file type from one folder to the other, but the function copies all the files in the folder.
function recurse_copy($src, $dst) {
$dir = opendir($src);
#mkdir($dst);
while (false !== ( $file = readdir($dir))) {
if (( $file != '.' ) && ( $file != '..' )) {
if (is_dir($src . '/' . $file)) {
if ($file->getExtension() == "pdf") {
recurse_copy($src . '/' . $file, $dst . '/' . $file);
}
} else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
} closedir($dir);
}
// if statements for
$itp = new RecursiveDirectoryIterator("foldername/", > FilesystemIterator::SKIP_DOTS);
$displayp = Array('pdf');
$i = 0;
foreach (new RecursiveIteratorIterator($itp) as $filepop) {
if (in_array(strtolower(array_pop(explode('.', $filepop))), $displayp))
if ($filepop->getExtension() == "pdf") {
echo >
recurse_copy("a", "b");
}
}
$itcopy = new RecursiveDirectoryIterator("foldername/", FilesystemIterator::SKIP_DOTS);
$displayp = Array ( 'pdf' );
foreach(new RecursiveIteratorIterator($itcopy) as $filecopy)
{
if (in_array(strtolower(array_pop(explode('.', $filecopy))), $displayp))
if ($filecopy->getExtension()=="pdf"){
copy($filecopy->getrealPath(),'pdf_folder/'.$filecopy->getFilename()) ;
}
}
I have files in a remote location that I grab through ftp, and I want to zip all files and directory into a zip using php.
I've used this, but it does not work. Does anyone know how to zip files?
The below code doesn't work at all.
<?php
ini_set('max_execution_time', 5000);
class xZip {
public function __construct() {}
private function _rglobRead($source, &$array = array()) {
if (!$source || trim($source) == "") {
$source = ".";
}
foreach ((array) glob($source . "/*/") as $key => $value) {
$this->_rglobRead(str_replace("//", "/", $value), $array);
}
foreach ((array) glob($source . "*.*") as $key => $value) {
$array[] = str_replace("//", "/", $value);
}
}
private function _zip($array, $part, $destination) {
$zip = new ZipArchive;
#mkdir($destination, 0777, true);
if ($zip->open(str_replace("//", "/", "{$destination}/partz{$part}.zip"), ZipArchive::CREATE)) {
foreach ((array) $array as $key => $value) {
$zip->addFile($value, str_replace(array("../", "./"), NULL, $value));
}
$zip->close();
}
}
public function zip($limit = 50000, $source = NULL, $destination = "./") {
if (!$destination || trim($destination) == "") {
$destination = "./";
}
$this->_rglobRead($source, $input);
$maxinput = count($input);
$splitinto = (($maxinput / $limit) > round($maxinput / $limit, 0)) ? round($maxinput / $limit, 0) + 1 : round($maxinput / $limit, 0);
for($i = 0; $i < $splitinto; $i ++) {
$this->_zip(array_slice($input, ($i * $limit), $limit, true), $i, $destination);
}
unset($input);
return;
}
public function unzip($source, $destination) {
#mkdir($destination, 0777, true);
foreach ((array) glob($source . "/*.zip") as $key => $value) {
$zip = new ZipArchive;
if ($zip->open(str_replace("//", "/", $value)) === true) {
$zip->extractTo($destination);
$zip->close();
}
}
}
public function __destruct() {}
}
$zip = new xZip;
$zip->zip(50000, "auto/", "c/");
//$zip->unzip("images_zip/", "images/");
?>
regards
dev
If you are on Linux and not limited by php's safe_mode (use phpinfo() to find out) then you could simply use exec() to run the zip command from a shell like:
Method 1:-
<?php
exec("zip -R public_html.zip /home/username/public_html",$output);
?>
Method 2:-
<?php
$archive = "xyz.zip";
$directory = $_SERVER['DOCUMENT_ROOT'];
exec( "zip -r $archive $directory");
?>
For Local systems you can use this code for zip the specific folders.
<?php
function Zip($source, $destination)
{
echo "called function";
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', $file);
// Ignore "." and ".." folders
if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
continue;
$file = realpath($file);
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
Zip('D:/tmp','D:/tmp/compressed.zip',true);
?>
Hope this helps.
Try with below links ,i think this links are reached your requirement.
Creating .zip file
and another one
http://runnable.com/UnF5GrIOBM91AAAR/create-a-zip-archive-using-php
I have a folder with some files and sub folder inside. How im going to read the directory and zip the main folder?
Ex:
maindirectory
--- file 1
--- file 2
--- subdirectory 1
------ file 3
------ file 4
--- subdirectory 2
------ file 5
------ file 6
I'm using this script:
function Zip($source, $destination, $include_dir = false)
{
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
if (file_exists($destination)) {
unlink ($destination);
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_CHILD);
if ($include_dir) {
$arr = explode("/",$source);
$maindir = $arr[count($arr)- 1];
$source = "";
for ($i=0; $i < count($arr) - 1; $i++) {
$source .= '/' . $arr[$i];
}
$source = substr($source, 1);
$zip->addEmptyDir($maindir);
}
foreach ($files as $file)
{
$file = str_replace('\\', '/', $file);
// Ignore "." and ".." folders
if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
continue;
$file = realpath($file);
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString(basename($source), file_get_contents($source));
}
return $zip->close();
}
and I call the function like this:
Zip('image/data/','aaa.zip',false);
But what I get is it zip the whole C: folder. What I want is to only zip document inside the image/data/ folder.
How can I format the correct directory and it's subdirectories?
try this.
zipFile('image/data/','aaa.zip', true);
/**
* function zipFile. Creates a zip file from source to destination
*
* #param string $source Source path for zip
* #param string $destination Destination path for zip
* #param string|boolean $flag OPTIONAL If true includes the folder also
* #return boolean
*/
function zipFile($source, $destination, $flag = '')
{
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if($flag)
{
$flag = basename($source) . '/';
//$zip->addEmptyDir(basename($source) . '/');
}
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', realpath($file));
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString($flag.basename($source), file_get_contents($source));
}
return $zip->close();
}
I edited the above code since I wasn't able to add empty folders and to avoid the C: drive as well
$otpt = "C:/xampp/htdocs/restricted/abc.zip";
$inpt = "C:/xampp/htdocs/Test/";
zipFile($inpt,$otpt, true); //Call to function
function zipFile($source, $destination, $flag = '')
{
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if($flag)
{
$flag = basename($source) . '/';
}
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', realpath($file));
if (strpos($flag.$file,$source) !== false) { // this will add only the folder we want to add in zip
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
}
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString($flag.basename($source), file_get_contents($source));
}
return $zip->close();
}
Thanks guys...i figure out the problem alr...
if (is_dir($source) === true)
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', realpath($file));
if (is_dir($file) === true)
{
//$zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/')); //this should be commented so it wont include the main path
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
}
}
}
1- You should put all these code in a function
function readfile($source){
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
$file = str_replace('\\', '/', realpath($file));
if (is_dir($file) === true)
{
$zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
}
else if (is_file($file) === true)
{
$zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
}
}
}
else if (is_file($source) === true)
{
$zip->addFromString($flag.basename($source), file_get_contents($source));
}
// here you would use recursive function
else if (is_dir($source) === true)
{
readfile($source);
}
}
summary :
if you find a file then you would do operation which you want and if you find a directory the you would use recursive function for traversing directory more.
You should add:
if(basename($file) === '.' || basename($file) === '..'){
continue;
}
like this:
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
if(basename($file) === '.' || basename($file) === '..'){
continue;
}
$file = str_replace('\\', '/', realpath($file));
if (is_dir($file) === true) {
$zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
} else if (is_file($file) === true) {
$zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
}
}
} else if (is_file($source) === true) {
$zip->addFromString($flag.basename($source), file_get_contents($source));
}
It will be simpler and if you use the addfile method instead of addfromstring
for win
public function ArchiveFile($path)
{
$path=realpath($path);
$zip = new \ZipArchive();
$path= str_replace('/','\\', $path );
$nameFile = $path.'\\'.'letter'.time().'.zip';
if ($zip->open($nameFile,\ZipArchive::CREATE)===TRUE){
if (is_dir($path))
{
$pathSource= $path. '\\';
$directory = new \RecursiveDirectoryIterator($path);
$files = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST );
}
foreach ($files as $name=>$file)
{
if (in_array(substr($name, strrpos($name,'\\')+1), array('.','..')))
{
continue;
}
if (is_file($name)===TRUE) {
$zip->addFile($name, str_replace($pathSource, "", $name));
}
}
$zip->close();
rename($nameFile, $nameFile.'.xlsx');
I need to know how to exclude files/folders from php generated zip. Here is my code:
public function archiveBackup($name = '', $source = '', $destination = '') {
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination.$name, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = str_replace('\\', '/', realpath($file));
if(is_dir($file) === true) {
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if(is_file($file) === true) {
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true) {
$zip->addFromString(basename($source), file_get_contents($source));
}
$zip->close();
return true;
}
Example: I need to exclude folder "themes" and "style.css" file, how to do that?
$exclude = array('themes', 'style.css');
foreach ($files as $file) {
if (!in_array($file, $exclude)) {
$file = str_replace('\\', '/', realpath($file));
if(is_dir($file) === true) {
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if(is_file($file) === true) {
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}