简体   繁体   English

如何使用Codeigniter和PHP从大文件夹创建zip文件?

[英]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. 我正在尝试从一个大小接近2GB的大文件夹创建zip文件。 My code is working well on the localhost but it's not working on the server(Cpanel). 我的代码在localhost上运行良好,但在服务器(Cpanel)上却无法运行。 In server, it's creating a zip file which size is only 103 MB out of 2GB. 在服务器中,它正在创建一个zip文件,其大小仅为2GB中的103 MB。 According to my strategy, first of all, I'm creating a backup folder recursively named "system_backup". 根据我的策略,首先,我将递归创建一个名为“ 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. 接下来是通过调用函数ZipData创建“ system_backup”文件夹的zip文件并将其存储到另一个文件夹。 In this time, it's not creating the zip file properly. 目前,它无法正确创建zip文件。

After that, the function rrmdir will be called. 之后,将调用函数rrmdir And it will delete the 'system_backup' folder recursively. 并且它将递归删除“ system_backup”文件夹。 And the deletion is not working properly as well. 并且删除也无法正常工作。 And, in localhost, it works well. 而且,在localhost中,它运行良好。

Then, when I'm trying to download the created zip file by the function download_file , it also not download properly. 然后,当我尝试通过功能download_file下载创建的zip文件时,它也无法正确下载。 It's downloaded as a broken zip file. 它已下载为损坏的zip文件。 And, in localhost, it also works well. 而且,在localhost中,它也可以正常工作。

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 :- 这是自定义的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: 下面的代码使用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 第1行创建ZipArchive类的对象

Line 2 opens a file with filename as test_new.zip so that we can add files to it. 第2行打开一个文件名为test_new.zip的文件,以便我们可以向其中添加文件。 The flag ZipArchive::CREATE specifies that we want to create a new zip file 标志ZipArchive :: CREATE指定我们要创建一个新的zip文件。

Lines 5 & 6 are used to add files to the zip file 第5和6行用于将文件添加到zip文件中

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 第9行用于将名称为random.txt的文件添加到zip文件中,并在zip文件中将其重命名为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' 第12行用于添加新文件new.txt,该文件的内容为“要添加到new.txt文件的文本”

Line 15 closes and saves the changes to the zip file 第15行关闭,并将更改保存到zip文件中

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 覆盖现有的zip文件

If you want to overwrite an existing zip file then we can use code similar to following. 如果您想覆盖现有的zip文件,那么我们可以使用类似于以下代码。 The flag ZipArchive::OVERWRITE overwrites the existing zip file. 标志ZipArchive :: OVERWRITE覆盖现有的zip文件。

            $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 此代码将创建一个文件test_overwrite.zip(如果已存在),该文件将被新文件覆盖。

Create a new zip file and add files to be inside a folder 创建一个新的zip文件并将文件添加到文件夹中

            $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 上面的代码会将zip文件中的不同文件添加到文件夹demo_folder中

The 2nd parameter to addfile function can be used to store the file in a new folder addfile函数的第二个参数可用于将文件存储在新文件夹中

The 1st parameter in the addFromString function can be used to store the file in a new folder addFromString函数中的第一个参数可用于将文件存储在新文件夹中

Create a new zip file and move the files to be in different folders 创建一个新的zip文件并将文件移动到其他文件夹中

            $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 我们将文件test.txt存储到demo_folder中,将test.pdf存储到demo_folder1中

Create a zip file with all files from a directory 使用目录中的所有文件创建一个zip文件

                $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 第5-16行打开一个目录,并创建一个zip文件,其中包含该目录中的所有文件

Line 5 opens the directory 第5行打开目录

Line 7 gets the name of each file in the dir 第7行获取目录中每个文件的名称

Line 9 skips the “.” and “..” and any other directories 第9行跳过“。”和“ ..”以及任何其他目录

Line 11 adds the file into the zip file 第11行将文件添加到zip文件中

Line 14 closes the directory 第14行关闭目录

Line 17 closes the zip file 第17行关闭zip文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM