【问题标题】:I cant set filename to a generated zip file from remote files and is too slow我无法将文件名设置为从远程文件生成的 zip 文件,而且速度太慢
【发布时间】:2015-06-20 22:25:03
【问题描述】:

我创建了一个网站,允许用户从远程站点zip 多个文件,将它们组合成一个zip 文件,然后下载它们。这部分工作得很好。

我遇到的问题:

1) 合并多个文件时,zip 生成时间过长

2) 我无法将zip 文件名设置为$name

这就是我所拥有的:

<?php

$files = unserialize($_POST['filesend']);
$name = $_POST['name'];

$zip = new ZipArchive();

$tmp_file = tempnam('.','');
$zip->open($tmp_file, ZipArchive::CREATE);

foreach($files as $file){
  $download_file = file_get_contents($file);
  $zip->addFromString(basename($file),$download_file);
}

$zip->close();

function downloadfile ($file, $contenttype = 'application/octet-stream') {
    @error_reporting(0);

    if (!file_exists($file)) {
        header("HTTP/1.1 404 Not Found");
        exit;
    }

    if (isset($_SERVER['HTTP_RANGE'])) $range = $_SERVER['HTTP_RANGE']; 
    else if ($apache = apache_request_headers()) { 
        $headers = array();
        foreach ($apache as $header => $val) $headers[strtolower($header)] = $val;
  if (isset($headers['range'])) $range = $headers['range'];
  else $range = FALSE; 
} else $range = FALSE; 

$filesize = filesize($file);
if ($range) {
  $partial = true;
  list($param,$range) = explode('=',$range);
  if (strtolower(trim($param)) != 'bytes') { 
    header("HTTP/1.1 400 Invalid Request");
    exit;
  }
  $range = explode(',',$range);
  $range = explode('-',$range[0]); 
  if (count($range) != 2) { 
    header("HTTP/1.1 400 Invalid Request");
    exit;
  }
  if ($range[0] === '') { 
    $end = $filesize - 1;
    $start = $end - intval($range[0]);
  } else if ($range[1] === '') { 
    $start = intval($range[0]);
    $end = $filesize - 1;
  } else { 
    $start = intval($range[0]);
    $end = intval($range[1]);
    if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) $partial = false; 
  }      
  $length = $end - $start + 1;
} else $partial = false;

header("Content-Type: $contenttype");
header("Content-Length: $filesize");
header("Content-Disposition: attachment; filename= $name .zip");
header('Accept-Ranges: bytes');

if ($partial) {
  header('HTTP/1.1 206 Partial Content'); 
  header("Content-Range: bytes $start-$end/$filesize"); 
  if (!$fp = fopen($file, 'r')) { 
    header("HTTP/1.1 500 Internal Server Error");
    exit;
  }
  if ($start) fseek($fp,$start);
  while ($length) { 
    $read = ($length > 8192) ? 8192 : $length;
    $length -= $read;
    print(fread($fp,$read));
  }
  fclose($fp);
} else readfile($file); 

exit;

}
downloadfile ($tmp_file, $contenttype = 'application/octet-stream');
?>

示例输入:

$files = array("http://img3.wikia.nocookie.net/__cb20100520131746/logopedia/images/5/5c/Google_logo.png","http://www.logobird.com/wp-content/uploads/2011/03/new-google-chrome-logo.jpg","http://steve-lovelace.com/wordpress/wp-content/uploads/2013/06/google-logo-in-chicago-font.png","http://fc08.deviantart.net/fs70/f/2013/111/d/6/applejack_google_logo__install_guide___by_thepatrollpl-d62gui3.png","http://www.sfweekly.com/binary/fb4a/go.jpg","https://www.google.com/logos/doodles/2014/world-cup-2014-16-5975619640754176.3-hp.gif");
$name = "Google Logo's 33";

【问题讨论】:

    标签: php html zip simple-html-dom file-management


    【解决方案1】:

    解决您的两个问题:

    1) 文件处理速度慢。 我不知道你能帮上忙。就是这样。

    2) 保存名称。 我已将其格式化为一个类,只是为了保持工作分开。我发现一门课在这种情况下效果更好,因为它更容易阅读。话虽这么说,因为每个方法都可能使用受保护的$filename,所以你应该在这里复制所有内容,而不是把这段代码分解出来,把你的程序和这个类混合起来:

    class   DownloadFiles
        {
            protected   $filename;
            protected   $Zipper;
    
            public  function Initialize($filename = false)
                {
                    // Set the file name in the construct
                    $this->filename =   ($filename != false)? $filename:"file".date("YmdHis");
    
                    // New ZipArchive instance
                    $this->Zipper   =   new ZipArchive();   
                    // Drop the filename here
                    $this->Zipper->open($this->filename, ZipArchive::CREATE);
                    // Return the method for optional chaining.
                    return $this;
                }
    
            public  function AddFiles($array = array())
                {
                    if(!isset($this->Zipper))
                        return $this;
    
                    // This is just if you wanted to also use a string
                    // separated by commas, it will convert to array
                    if(!is_array($array) && strpos($array,",") !== false)
                        $array  =   explode(",",$array);
    
                    // Loop through files (as you have it already)
                    if(is_array($array) && !empty($array)) {
                            foreach($array as $url) {
                                        // Add Contents (as you have it)                                
                                        $this->Zipper->addFromString(basename($url),file_get_contents($url));
                                }
                        }
                    // Close zip file
                    $this->Zipper->close();
                    // Return for method chaining
                    return $this;
                }
    
            public  function DownloadZip($contenttype = 'application/octet-stream')
                {
                    if(!isset($this->filename))
                        return $this;
    
                    // Nothing really changes in this function except
                    // you don't need the name as an option in this function
                    error_reporting(0);
                    if (!file_exists($this->filename)) {
                            header("HTTP/1.1 404 Not Found");
                            exit;
                        }
    
                    $range  =   false; 
    
                    if(isset($_SERVER['HTTP_RANGE']))
                        $range = $_SERVER['HTTP_RANGE']; 
                    elseif($apache = apache_request_headers()) { 
                            $headers = array();
    
                            foreach ($apache as $header => $val)
                                $headers[strtolower($header)] = $val;
    
                            $range = (isset($headers['range']))? $headers['range']:false;
                        }
    
                    $filesize   =   filesize($this->filename);
                    $partial    =   false;
    
                    if($range) {
                            $partial = true;
                            list($param,$range) = explode('=',$range);
    
                            if(strtolower(trim($param)) != 'bytes') { 
                                    header("HTTP/1.1 400 Invalid Request");
                                    exit;
                                }
    
                            $range  =   explode(',',$range);
                            $range  =   explode('-',$range[0]); 
    
                            if(count($range) != 2) { 
                                    header("HTTP/1.1 400 Invalid Request");
                                    exit;
                                }
    
                            if($range[0] === '') { 
                                    $end    =   $filesize - 1;
                                    $start  =   $end - intval($range[0]);
                                }
                            elseif($range[1] === '') { 
                                    $start  =   intval($range[0]);
                                    $end    =   $filesize - 1;
                                }
                            else { 
                                    $start  =   intval($range[0]);
                                    $end    =   intval($range[1]);
    
                                    if($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1))))
                                        $partial = false; 
                                }      
                                    $length = $end - $start + 1;
                        }
    
                    header("Content-Type: $contenttype");
                    header("Content-Length: $filesize");
                    header('Content-Disposition: attachment; filename='.$this->filename.'.zip');
                    header('Accept-Ranges: bytes');
    
                    if($partial) {
                            header('HTTP/1.1 206 Partial Content'); 
                            header("Content-Range: bytes $start-$end/$filesize"); 
    
                            if(!$fp = fopen($this->filename, 'r')) { 
                                    header("HTTP/1.1 500 Internal Server Error");
                                    exit;
                                }
    
                            if($start)
                                fseek($fp,$start);
    
                            while($length) { 
                                    $read   =   ($length > 8192) ? 8192 : $length;
                                    $length -= $read;
                                    print(fread($fp,$read));
                                }
    
                            fclose($fp);
                        }
                    else
                        readfile($this->filename); 
    
                    exit;
                }
        }
    ?>
    

    使用方法:

    $files[] = "http://img3.wikia.nocookie.net/__cb20100520131746/logopedia/images/5/5c/Google_logo.png";
    $files[] = "http://www.logobird.com/wp-content/uploads/2011/03/new-google-chrome-logo.jpg";
    $files[] = "http://steve-lovelace.com/wordpress/wp-content/uploads/2013/06/google-logo-in-chicago-font.png";
    $files[] = "http://fc08.deviantart.net/fs70/f/2013/111/d/6/applejack_google_logo__install_guide___by_thepatrollpl-d62gui3.png";
    $files[] = "http://www.sfweekly.com/binary/fb4a/go.jpg";
    $files[] = "https://www.google.com/logos/doodles/2014/world-cup-2014-16-5975619640754176.3-hp.gif";
    
    $name    = "Google Logo's 33";
    // Initialize
    $ZDownload  =   new DownloadFiles();
    // Run downloader
    $ZDownload->Initialize($name)->AddFiles($files)->DownloadZip();
    

    【讨论】:

    • 是的,我不知道,因为必须先下载文件,这取决于与服务器的连接速度,所以我不知道你能下载多少影响那个。我尝试了一系列代码,它有不同的速度,有些慢有些快。
    • 是否可以通过获取标题??
    • 或者我可以在生成 zip 时显示进度条
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 2018-11-05
    • 1970-01-01
    • 2016-09-29
    • 2016-08-26
    • 2013-09-22
    相关资源
    最近更新 更多