2013-08-23 17 views
7

lập trình viên:ZipArchive PHP chỉ thêm tập tin mà không thư từ toàn bộ con đường

Ghét hỏi câu hỏi này, vì nó là, I belive trả lời đúng hai lần:

  1. Here

  2. And here

Vì vậy, pr biểu tượng là: khi giải nén tập tin 'download.zip' đã tải xuống, sau khi giải nén, nó chứa tất cả các thư mục từ đường dẫn, thậm chí khó khăn tôi đã chỉ định tệp cục bộ trong hàm addFile. Tôi muốn tệp zip không chứa bất kỳ thư mục con nào, chỉ là các tệp.

$zipname = str_replace(' ', '_', $obj['Name']) . '.zip'; 

$zip = new ZipArchive(); 

$zip->open($zipname, ZipArchive::CREATE); 
foreach ($files as $file) { 
    // $file looks like this: webroot/uploadify/files/file.jpg 
    $zip->addFile($file, pathinfo($file, PATHINFO_BASENAME)); 
} 

$zip->close(); 

header('Content-Description: File Transfer'); 
header('Content-Transfer-Encoding: binary'); 
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
header("Content-type: application/zip"); 
header("Content-Disposition: attachment; filename=" . $zipname); 
header("Pragma: no-cache"); 
header("Expires: 0"); 
header('Content-Length: ' . filesize($zipname)); 

readfile($zipname); 

Có ai có thể xem vấn đề với mã này là gì?

Thông tin thêm:

I, OFC, sử dụng con đường tương đối so với webroot, nhưng hệ thống phân cấp thư mục trong thư mục giải nén sau: trích nộp -> 'my_file.zip' là C-> xampp -> htdocs-> my_cakephp_web_app-> cấp ứng dụng> webroot-> file mà không phải là chính xác những gì tôi muốn đạt được :)

PHP 5.4.4

Windows XP, XAMPP

EDIT

Đã thử sử dụng thư viện http://www.phpconcept.net/pclzip/ và gặp sự cố tương tự. Cũng trên PC của tôi (win7) mã này hoạt động tốt.

Điều này sẽ trả lời một câu hỏi: Có bất kỳ cài đặt nào tôi phải đáp ứng mà tôi không biết?

Trả lời

2

Bạn cần phải kiểm tra mỗi tập tin để xem nếu nó là một tập tin (chứ không phải là một thư mục, liên kết tượng trưng, ​​vv):

foreach ($files as $file) 
{ 
    if(filetype($file) == 'file') { 
     $zip->addFile($file, pathinfo($file, PATHINFO_BASENAME)); 
    } 
} 

này được sử dụng filetype, nhưng bạn cũng có thể sử dụng is_file.

+0

không giúp đỡ, vẫn hoạt động theo cùng một cách .. –

+0

Nếu bạn đã có thời gian, hãy xem câu trả lời của tôi và cho tôi biết lý do tại sao nó hoạt động :) –

4

Tôi đã chạy mã của bạn và mã hoạt động như mong đợi. Vì vậy, có 3 điều có thể đi sai từ những gì tôi có thể nhìn thấy.

Hãy thử sử dụng các cờ này trong trường hợp tệp cũ vẫn tồn tại và nó không bị ghi đè (không rõ $ obj ['Name'] nào được đặt thành) Nếu bạn đọc nhận xét trong hướng dẫn sử dụng php, ở đó là mức độ thành công khác nhau bằng cách sử dụng ZIPARCHIVE :: CREATE so với ZIPARCHIVE :: OVERWRITE, vì vậy có lẽ việc sử dụng cả hai đều sẽ hoạt động.

$zip->open($zipname, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE); 

Pathinfo có thể thất bại và trả lại toàn bộ đường dẫn hoặc null cho một số lý do

Có thể làm một var_dump trên đầu ra pathinfo, chỉ để xác nhận nó là những gì bạn mong đợi nó sẽ?

foreach ($files as $file) 
{ 
    var_dump(pathinfo($file, PATHINFO_BASENAME)); 

    // $file looks like this: webroot/uploadify/files/file.jpg 
    // $zip->addFile($file, pathinfo($file, PATHINFO_BASENAME)); 
} 

Có thể có một lỗi với os/php phiên bản của bạn với chức năng addFile (khó, nắm bắt tại ống hút ở đây như tôi không thể nhìn thấy bất kỳ lời giải thích khác)

+0

Nếu bạn có thời gian, hãy xem câu trả lời của tôi xin vui lòng và cho tôi biết lý do tại sao nó làm việc :) –

1

Tôi hoàn toàn không có ý tưởng tại sao điều này là làm việc :)

tôi thực sự muốn tin rằng, đó máy tính của tôi bước vào một chế độ Skynet và có phương pháp addFile để làm việc bằng cách nào đó :)

Bất cứ ai plausibly có thể giải thích những gì đã xảy ra sẽ nhận được tiền thưởng 50 :)

$zipname = str_replace(' ', '_', $obj['Name']) . '.zip'; 

    $zip = new ZipArchive; 

    $zip->open($zipname, ZipArchive::CREATE); 

    foreach ($files as $file) 
    { 
     // the str_replace made it work??? 
     $zip->addFile(str_replace('/webroot', '', getcwd() . '/' . $file), pathinfo($file, PATHINFO_BASENAME)); 
    } 

    $zip->close(); 

    header("Content-type: application/zip"); 
    header("Content-Disposition: attachment; filename=" . $zipname); 
    header('Content-Length: ' . filesize($zipname)); 

    readfile($zipname); 

EDIT:

Ngoài ra, sau khi có một số rắc rối hơn với các tập tin tạm thời không deleteing bản thân, tôi chuyển sang http://www.phpconcept.net/pclzip/, mà hoạt động tốt.

Ngoài ra, Alix Axel nêu PharData dưới đây, do số lượng điểm anh ấy kiếm được ở đây, tôi đang xem xét cách tiếp cận của mình cũng ..

+0

Chỉ cần tò mò như những gì giá trị của getcwd() là. Có vẻ như bạn đang dịch một đường dẫn tương đối thành đường dẫn tuyệt đối. – bumperbox

+0

Đây là từ bình luận đầu tiên về hướng dẫn sử dụng php cho $ zip-> addFile. Cẩn thận: gọi $ zip-> addFile() trên một tệp không tồn tại sẽ thành công và trả về TRUE, trì hoãn lỗi cho đến khi bạn thực hiện cuộc gọi $ zip-> close() cuối cùng, sẽ trả về FALSE và có khả năng khiến bạn gãi đầu của bạn. Nếu bạn đang thêm nhiều tệp vào mã zip và lệnh gọi $ zip-> close() của bạn trả về FALSE, hãy đảm bảo rằng tất cả các tệp bạn đã thêm thực sự tồn tại. Bạn cũng nên kiểm tra từng tệp bằng file_exists() hoặc is_readable() trước khi gọi $ zip-> addFile() trên đó. – bumperbox

+0

getcwd() trả về "C: \ xampp \ htdocs \ test_tool \ app \ webroot". Cũng đọc nhận xét đó và nhận thấy rằng kể từ khi lưu trữ zip đang được tạo, nó hoạt động (nên đã in $ zip-> close() ra, sẽ biết thời gian tiếp theo khi gặp sự cố). –

2

Trong PHP 5.3 này nên làm điều đó:

$phar = new PharData('file.zip'); 

// add all files in the folder, only include files with extensions 
$phar->buildFromDirectory('/directory', '~[.][0-9a-z]+$~i'); 

Bạn cũng có thể sử dụng PharData::buildFromIterator với cờ LEAVES_ONLY.

+0

Xin chào, tôi đã thử mã của bạn như sau: '$ phar = PharData mới ('tmp_zips/file.zip'); $ phar-> buildFromDirectory ('/ uploadify/files/test1', '~ [.] [0-9a-z] + $ ~ i'); ' Tôi gặp lỗi này: 'RecursiveDirectoryIterator :: __ construct (/ uploadify/files/test1,/uploadify/files/test1): Hệ thống không thể tìm thấy đường dẫn được chỉ định. (mã: 3) ' –

+0

@IgorLacik: Dường như đề nghị bạn nhập sai đường dẫn của mình. –