메뉴 건너뛰기

프로그램언어

조회 수 617 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
<?php
class DirectZip
{
    private static $BUFFER_SIZE = 4194304; // 4MiB

    private $currentOffset;
    private $entries;

    public function open($filename)
    {
        set_time_limit(0);
        ini_set('zlib.output_compression', 'Off');
        header('Pragma: no-cache');
        header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
        header('Cache-Control: no-store');
        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; '
            . 'filename="' . rawurlencode($filename) . '"; '
            . 'filename*=UTF-8\'\'' . rawurlencode($filename));
        $this->currentOffset = 0;
        $this->entries = array();
    }

    public function addEmptyDir($dirname)
    {
        if ($this->addFile('php://temp', $dirname.'/') === false) {
            return false;
        }
    }

    public function addFromString($localname, $contents)
    {
        $tmp = tempnam(sys_get_temp_dir(), __CLASS__);

        $pointer = @fopen($tmp, 'wb');
        if ($pointer === false) {
            @unlink($tmp);
            return false;
        }

        fwrite($pointer, $contents);
        $result = $this->addFile($tmp, $localname);

        fclose($pointer);
        @unlink($tmp);

        if ($result === false) {
            return false;
        }
    }

    public function addFile($filename, $localname = null)
    {
        $entry = new DirectZipEntry($localname ?: basename($filename), $this->currentOffset);
        if ($entry->open($filename) === false) {
            return false;
        }

        $this->entries[] = $entry;

        ob_start();

        self::write(0x504B0304, 'N'); // sig entry
        self::writeEntryStat($entry);
        echo $entry->name;

        $this->currentOffset += strlen(ob_get_flush());

        while (!feof($entry->pointer)) {
            $buffer = @fread($entry->pointer, self::$BUFFER_SIZE);
            echo $buffer;
            flush();
            $this->currentOffset += strlen($buffer);
        }

        $entry->close();
    }

    public function close()
    {
        ob_start();

        foreach ($this->entries as $entry) {
            self::write(0x504B0102, 'N'); // sig index
            self::write(0); // os: fat
            self::writeEntryStat($entry);
            self::write(0); // comment len
            self::write(0); // disk # start
            self::write(0); // internal attr
            self::write(0, 'V'); // external attr
            self::write($entry->offset, 'V');
            echo $entry->name;
        }

        $length = strlen(ob_get_flush());

        self::write(0x504B0506, 'N'); // sig end
        self::write(0); // disk number
        self::write(0); // disk # index start
        self::write(count($this->entries)); // disk entries
        self::write(count($this->entries)); // total entries
        self::write($length, 'V');
        self::write($this->currentOffset, 'V');
        self::write(0); // comment len
        flush();
    }

    private static function writeEntryStat($entry) {
        self::write(substr($entry->name, -1) == '/' ? 20 : 10);
        self::write(2048); // flags: unicode filename
        self::write(0); // compression: store
        self::write($entry->mtime, 'V');
        self::write($entry->crc, 'V');
        self::write($entry->size, 'V'); // compressed size
        self::write($entry->size, 'V'); // uncompressed size
        self::write(strlen($entry->name));
        self::write(0); // extra field len
    }

    private static function write($binary, $format = 'v')
    {
        echo pack($format, $binary);
    }
}

class DirectZipEntry
{
    public $offset;
    public $pointer;

    public $name;
    public $crc;
    public $size;
    public $mtime;

    public function __construct($name, $offset)
    {
        $this->offset = $offset;
        $this->name = $name;
    }

    public function open($filename)
    {
        $this->pointer = @fopen($filename, 'rb');
        if ($this->pointer === false) {
            return false;
        }

        list(, $this->crc) = unpack('N', hash_file('crc32b', $filename, true));

        $fstat = fstat($this->pointer);
        $this->size = $fstat['size'];

        $mtime = $filename == 'php://temp' ? time() : $fstat['mtime'];
        $this->mtime = self::toFAT32Timestamp($mtime);
    }

    public function close()
    {
        fclose($this->pointer);
    }

    private static function toFAT32Timestamp($unixTimestamp)
    {
        list($y, $m, $d, $h, $i, $s) = explode('-', @date('Y-m-d-H-i-s', $unixTimestamp));
        return ($y - 1980) << 25 | $m << 21 | $d << 16
            | $h << 11 | $i << 5 | $s >> 1;
    }
}



<?php
require 'cla_directzip.php';
$zip = new DirectZip();
$zip->open('브라우저로 보낼 압축파일 이름.zip');
$zip->addFile('/tmp/추가할 파일.jpg', '압축파일 내 파일 이름.jpg');
$zip->addEmptyDir('압축파일 내 폴더 이름'); // 안 해도 상관없음.
$zip->addFile('/tmp/추가할 파일2.png', '압축파일 내 폴더 이름/압축파일 내 파일 이름.png');
$zip->addFile('/tmp/추가할 파일3.jpg'); // 압축파일에 파일을 '추가할 파일3.jpg'로 추가
$zip->addFromString('바로 글쓰기.txt', '파일 내용'); // 압축파일에 '파일 내용'을 '바로 글쓰기.txt'로 추가
$zip->close();

/*
브라우저로 보낼 압축파일 이름.zip
│  바로 글쓰기.txt
│  압축파일 내 파일 이름.jpg
│  추가할 파일3.jpg
│
└─압축파일 내 폴더 이름
        압축파일 내 파일 이름.png
*/



List of Articles
번호 제목 날짜 조회 수
80 파일을 변수에 담기(ob_start를 이용한 방법) 2021.03.26 676
79 13자리 timestamp 생성하기 file 2020.09.28 649
78 PHP 버전이 낮아 imagerotate() 함수가 없을때 대신 사용하는 함수 2019.12.31 644
77 while, for, foreach 속도 비교 2021.03.26 623
76 파일 다운로드 함수(멀티 이어받기/속도제한) 2020.06.19 618
» 다중 파일을 zip으로 묶어받기 2020.06.19 617
74 알파벳 순서대로 출력하기 ord(), chr() 2021.03.26 583
73 substr(), mb_substr(), iconv_substr() 2021.03.26 564
72 csv파일 다루기. fputcsv(), fgetcsv() 2021.03.26 558
71 서브도메인 세션 공유 2021.03.26 542
70 Javascript 두 좌표 사이의 거리 구하기, 두 좌표의 중앙 좌표 구하기 file 2020.09.23 535
69 네이버 지도 API를 이용한 주소를 좌표로 변환하기 (PHP) 2020.09.22 495
68 CodeIgniter - DB오류체크, 디버깅 여부 설정 2021.03.29 494
67 사업자등록번호 유효성 체크 2020.08.24 470
66 PHP 쉘 스크립트 2021.03.26 457
65 배열 더하기 (+ 를 이용한 배열 합치기 ) 2021.03.26 451
64 멀티 파일다운로드 꽁수로 구현하기 2020.06.19 437
63 주차 , 요일, 해당주의 시작일, 해당주의 종료일 date() 2021.07.08 432
62 DAUM 지도 API 좌표→주소(주소->좌표) 변환 2020.10.05 431
61 경로 제외한 파일 이름만 선택하는 방법, Basename() 2020.11.23 429
Board Pagination Prev 1 ... 8 9 10 11 12 13 14 15 16 17 Next
/ 17

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved