[英]How to create zip file from a large folder using Codeigniter and PHP?
我正在尝试从一个大小接近2GB的大文件夹创建zip文件。 我的代码在localhost上运行良好,但在服务器(Cpanel)上却无法运行。 在服务器中,它正在创建一个zip文件,其大小仅为2GB中的103 MB。 根据我的策略,首先,我将递归创建一个名为“ system_backup”的备份文件夹。 备份文件夹创建良好,没有任何问题。 接下来是通过调用函数ZipData创建“ system_backup”文件夹的zip文件并将其存储到另一个文件夹。 目前,它无法正确创建zip文件。
之后,将调用函数rrmdir 。 并且它将递归删除“ system_backup”文件夹。 并且删除也无法正常工作。 而且,在localhost中,它运行良好。
然后,当我尝试通过功能download_file下载创建的zip文件时,它也无法正确下载。 它已下载为损坏的zip文件。 而且,在localhost中,它也可以正常工作。
我已经检查了文件夹和文件的读写权限。
代码如下:
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);
}
这是自定义的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 */
下面的代码使用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();
}
代码说明
第1行创建ZipArchive类的对象
第2行打开一个文件名为test_new.zip的文件,以便我们可以向其中添加文件。 标志ZipArchive :: CREATE指定我们要创建一个新的zip文件。
第5和6行用于将文件添加到zip文件中
第9行用于将名称为random.txt的文件添加到zip文件中,并在zip文件中将其重命名为newfile.txt
第12行用于添加新文件new.txt,该文件的内容为“要添加到new.txt文件的文本”
第15行关闭,并将更改保存到zip文件中
注意:有时在使用文件的相对路径时可能会出现问题。 如果使用路径有任何问题,那么我们也可以使用文件的绝对路径
覆盖现有的zip文件
如果您想覆盖现有的zip文件,那么我们可以使用类似于以下代码。 标志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();
}
代码说明
此代码将创建一个文件test_overwrite.zip(如果已存在),该文件将被新文件覆盖。
创建一个新的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();
}
代码说明
上面的代码会将zip文件中的不同文件添加到文件夹demo_folder中
addfile函数的第二个参数可用于将文件存储在新文件夹中
addFromString函数中的第一个参数可用于将文件存储在新文件夹中
创建一个新的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();
}
代码说明
我们将文件test.txt存储到demo_folder中,将test.pdf存储到demo_folder1中
使用目录中的所有文件创建一个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();
}
代码说明
第5-16行打开一个目录,并创建一个zip文件,其中包含该目录中的所有文件
第5行打开目录
第7行获取目录中每个文件的名称
第9行跳过“。”和“ ..”以及任何其他目录
第11行将文件添加到zip文件中
第14行关闭目录
第17行关闭zip文件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.