readfile () funktsiyasini yuklab olish o'rniga zip faylini o'qing (Zend)

Zip faylini yuklab olishni boshlashim kerak (Zip fayli mening ma'lumotlarim papkasida). Buning uchun kodni ishlataman,

$file = 'D:\php7\htdocs\Project\trunk\api\data\file.zip';
header('Content-Description: File Transfer');
header('Content-type: application/zip');
header('Content-disposition: attachment; filename=' . basename($file) );
readfile($file);`

Bu men kutganimdek asosiy php-da ishlaydi. Ammo Zendda xuddi shu kodni ishlatganimda, quyida ko'rsatilgan kontentni yozishda,

PKYsVJ) ~ Study.xlsPKYsVJs + tutorial-point-Export.xlsPKYsVJn 8 Zabc.xlsP

Tarkib o'rtasida zipdagi barcha fayllarning nomini ko'rsam bo'ladi. Lekin yuklab olinmaydi.

Men bu ishlamayotganini tushunib etgach, bu haqda qidirishni boshladim va oqim ustida suyak to'plamini topdim

Try 1: Adding different header element and ob functions in every random lines

  • sarlavhasi ("Content-Transfer-Encoding: ikkilik");
  • sarlavhasi ('Muddati: 0');
  • sarlavhasi ('Kesh-nazorati: tekshirishni bekor qilish, nazoratdan o'tish = 0, oldindan tekshirish = 0');
  • sarlavhasi («Pragma: ommaviy»);
  • sarlavhasi ('Content-Length:'. $ file_size);
  • ob_start ();
  • ob_clean ();
  • flush ();

Bularning barchasi turli-tuman suyuqlikdan savol va javoblar bilan sinab ko'rilgan va bir xil natijaga ega

Try 2:PHP is reading file instead of downloading . This question do not have any accepted answer (He was asking about the core PHP but i have the same issue with zend only) . I tried all of this but it was not working.

Try 3:Changing the .htaccess . After that i thought it was a problem with my .htaccess and found this answer for changing the .htaccess file.


        ForceType application/octet-stream
        Header set Content-Disposition attachment

Bu ham menga bir xil natija berdi.

Try 4:Using download functions in Zend . I have tried the all the zend functions in the answer of this question. But given me an empty output even the file was not read.

Try 5: Remove all the unwanted spaces before and after the PHP tag as per the answer

ZF2 formatidagi downloadni ishga tushirishning boshqa usullari bormi?

EDIT -ni tanlang

Quyida mening aniq vazifam bor. Bu GET (API) funktsiyasi,

public function getList(){
    try{
       //here i am getting the zip file name.
       $exportFile = $this->getRequest()->getQuery('exportid','');
       $file = 'D:\php7\htdocs\Project\trunk\api\data\\' . $exportFile . '.zip';
       header('Content-Description: File Transfer');
       header('Content-type: application/zip');
       header('Content-disposition: attachment; filename=' . basename($file) );
       readfile($file);
       return new JsonModel(["status"=>"Success"]);
    } catch(\Exception $e){
       return new JsonModel(["status"=>"Failed"]);
    }
}
8
Yub, chop etilgan kod ishlashi kerak, shuning uchun boshqa hech narsa qilinmaydi. Buni ishlatadigan usulni yuboring.
qo'shib qo'ydi muallif yivi, manba
ZF-da to'liq yozgan funktsiyangiz kodini yubora olasizmi?
qo'shib qo'ydi muallif Chetan Ameta, manba
Xato hisobotlarini yoqish bilan ishlashni tekshirib ko'ring va ob-havo sarlavhasini yuborilganmi?
qo'shib qo'ydi muallif Chetan Ameta, manba
readfile ($ file); qatoridan so'ng exit (); ni qo'yishga harakat qildingizmi?
qo'shib qo'ydi muallif Kodos Johnson, manba
Faqat tekshirib ko'ring, siz bu erda qabul qilingan javobni sinab ko'rdingizmi: stackoverflow.com/questions/7263923/…
qo'shib qo'ydi muallif Kodos Johnson, manba
D kodi bilan sarlavhasi ("Kontent-turi: dastur/oktet-oqim") va Content-Disposition
qo'shib qo'ydi muallif ETech, manba
@ETech ham kapitallashtirishni sinab ko'rdi :(
qo'shib qo'ydi muallif Kuttoozz, manba
@ChetanAmeta Men vazifani o'zim bilan tahrirladim
qo'shib qo'ydi muallif Kuttoozz, manba
@KodosJohnson Men bu ishni birinchi marta sinab ko'rdim. Hozir bu PHP da yaxshi ishlamoqda, lekin faylni ZF2 Framework da o'qing. Va hozirda yuklab olish uchun PHP kodi o'rniga JavaScript-ni qayta yo'naltirishni ishlatmoqdaman (Hozirda).
qo'shib qo'ydi muallif Kuttoozz, manba
readfile() dan keyin exit() va die() kodini sinab ko'rdim, u erda fayl mazmunini ham chop etdi.
qo'shib qo'ydi muallif Kuttoozz, manba
@Chris javobingiz uchun rahmat. charset = utf-8 Content-Type bilan sarlavhasi ('Content-type: application/zip; charset = utf-8') sifatida sinab ko'rdim; Lekin men o'qigan faylni ekranimga qo'ydim. Charset-da qidirish charset odatda matn fayllari uchun ishlatiladi, deydi. Tahrir bormi?
qo'shib qo'ydi muallif Kuttoozz, manba
Men o'rtada shunday deb o'yladim va buni tekshirib oldim, ammo sarlavha yuborilgan edi. Hatto keyin ob_ funktsiyalaridan foydalanganimda (1-sinab), lekin kod xuddi shu tarzda ishlagan.
qo'shib qo'ydi muallif Kuttoozz, manba
@Chris ham buni sinab ko'rdim, natija bir xil edi :(
qo'shib qo'ydi muallif Kuttoozz, manba
Ishonchim komilki, yordam berishi mumkin, lekin odatda charsetni sarlavhalarimga yuboraman. Buni sinash mumkin.
qo'shib qo'ydi muallif Chris, manba
Agar siz allaqachon charset ma'lumotini ham sinab ko'rishni sinab ko'rgan bo'lsangiz, u holda bu butunlay boshqacha. Eng oxirgi narsa: Kontent-disposition sarlavhasi odatda tirnoqlarda fayl nomini yuboradi: Content-Disposition: attachment; filename = "filename.jpg"
qo'shib qo'ydi muallif Chris, manba

6 javoblar

You can try this for downloading the file instead of readfile(); Server side - file_put_contents("file.zip", fopen("http://someurl/file.zip", 'r'));

Client side - <button>download file</button> download file

1
qo'shib qo'ydi
Men ko'rsatadigan oldingi tugmacham yo'q. Foydalanuvchi faqat yuklab olish uchun foydalanadigan URL manziliga ega
qo'shib qo'ydi muallif Kuttoozz, manba
file_put_content server tomonida ishlaydi, to'g'rimi? Keyin uni mijoz tomondan qanday yuklab olaman?
qo'shib qo'ydi muallif Kuttoozz, manba
agar siz mijoz tomoniga faylni yuklab olishni istasangiz, shunchaki buni amalga oshirishingiz mumkin <button> yuklab olish fayli
qo'shib qo'ydi muallif Rishabh Chaudhary, manba
0
qo'shib qo'ydi
muqobil @Kuttoozz tahririni joylashtiraman
qo'shib qo'ydi muallif Peter Darmis, manba
@Kuttoozz yangilashni sinab ko'ring
qo'shib qo'ydi muallif Peter Darmis, manba
o'rniga yangi JsonModel (["status" => "muvaffaqiyat"]); return $ javob yozish; @Kuttoozz
qo'shib qo'ydi muallif Peter Darmis, manba
qo'shib qo'ydi muallif Kuttoozz, manba
Bu ajoyib ish bo'ldi, lekin afsuski, kontentni yuklab olish o'rniga chop etish edi :(
qo'shib qo'ydi muallif Kuttoozz, manba
kod oddiygina {"status": "Success"} () ni boshqa hech qanday harakat qilmasdan bosib chiqaradi (fayl mazmuni hozir chop etilmaydi va yuklab olish tetiklantirilmaydi)
qo'shib qo'ydi muallif Kuttoozz, manba
Fatal xatolik yuzaga keladi: Unchaught error: undefined method Zend \ Http \ PhpEnvironment \ Response :: setHeader() ga qo'ng'iroq qiling. Men buni oldin ham sinab ko'rdim, lekin xato tufayli boshqa echimni qidirdim.
qo'shib qo'ydi muallif Kuttoozz, manba

Bu erda ikkita muammo bor:

  • Sizning brauzeringiz uni yuklab olish o'rniga faylni ochishga harakat qilmoqda.
  • Bundan tashqari, faylni to'g'ri ochib bo'lmaydi.

Ham tarkib-turi xatoligini bildiradi. Brauzer tomonidan Tarkibiy-To'r qabul qilingan to'g'ri ekanligini tasdiqlang (masalan, text/html ).

Agar shunday bo'lsa, uni application/x-download ga o'zgartiring. Internet Explorer-da ishlamasligi mumkin, bu ba'zi bir tajovuzkor Kontent-toifa kukunlarini bajaradi. nosniff direktivasini qo'shishga harakat qilib ko'rishingiz mumkin.

Bundan tashqari, readfile dan keyin (va mazmunini faylga qaytarishingiz kerak ), filefile() 'ing - file_get_contents ($ filename); ), siz barcha chiqishni return null; bilan to'xtatishingiz kerak. ZIP fayl katalogi eng oxirida bo'ladi, shuning uchun u erda JSON xabarini qo'shsangiz, brauzer nima faylni yuklab olish, na to'g'ri ko'rsatmasligi kerak.

Oxirgi chora sifatida, siz yadroga borishingiz va o'zingizni hamma narsalarni qilishingiz mumkin. Juda chiroyli bo'lmagan va barcha sharoitlar muqobillashtirishi kerak, ammo ...

// Stop *all* buffering
while (ob_get_level()) {
    ob_end_clean();
}
// Set headers using PHP functions instead of Response
header('Content-Type: application/x-download');
header('X-Content-Type-Options: nosniff');
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename="whatever.zip"');
die(readfile($filename));

mumkin , ateşit işleyicilerinin yoki yıkıcı kancaların ba'zi bir ijodiy foydalanishlari, bu oxirgi variantni ham buzishi mumkin, lekin men buni bilmayman.

0
qo'shib qo'ydi
Yuqoridagi @ LSerni tomonidan berilgan javobga binoan brauzerda qabul qilingan kontent turini (masalan, Chrome brauzeridan foydalanish, yuklab olish uchun tarmoq so'rovining sarlavhalarini qarab) tekshirdingizmi? Sarlavha nima kutmoqdasiz? Ehtimol, sozlamangizdagi biror narsa zend kodi nomlarni juda kech (masalan, kontentni boshlaganidan keyin) o'rnatishga harakat qilish deganidir.
qo'shib qo'ydi muallif James Fry, manba
Hali ham xuddi shu kontent chop etiladi. Nima uchun u yadro PHP da ishlayotganini va nima uchun zendda ishlamasligini topa olmayapman. Shuning uchun, men bu Javascriptdan foydalanishga qaror qildim: (.
qo'shib qo'ydi muallif Kuttoozz, manba

Agar siz sarlavhalarni sarlavhasini tuzatmoqchi bo'lsangiz, u ishlaydi? Kontent-disposition va kontent-kontentni Content-disposition va Content-type orqali ishlatish kerakmi?

Nima bo'lishidan qat'iy nazar, standart disk raskadrovka uslubi sifatida sizning brauzeringizning dev vositalaridan foydalanib, talab qilinadigan so'rovlarni tekshirish va serverlar kodida qanday natija bilan solishtirishni taklif qilishni taklif qilaman va server tomonida javob nima va nimalar tugaydi mijozlar ichida. Bundan tashqari, buni maxsus-sessiya (Chrome-da inkognito rejimi va boshqalar) yordamida yoki boshqa narsalarni yo'q qilish uchun yangi profil/VM-ni o'rnatish orqali tasdiqlashim mumkin.

Bundan tashqari, nega xsendfile dan foydalaning va faylni veb-serverga jo'natish mas'uliyatini topshiring, shuning uchun siz PHP kodingizda javobgarlikni o'zingizdan soqit qilasizmi? Buni tegishli server konfiguratsiyasi bilan (ba'zan .htaccess orqali amalga oshirish mumkin, ammo bu kun va yoshda, albatta, siz ham to'liq nazoratga ega bo'lasiz) va keyin yuqoridagi misol bo'yicha X-Sendfile havola:

header("X-Sendfile: $path_to_somefile");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$somefile\"");
0
qo'shib qo'ydi
Men sarlavhalar sarlavhalarini kattalashtirishni sinab ko'rdim va endi X-Sendfilni sinab ko'rdim, ikkovingiz ham men uchun biron-bir tarzda yordamingiz uchun minnatdor emas.
qo'shib qo'ydi muallif Kuttoozz, manba

Siz JsonModel ga qaytib kelganingiz uchun chiqishingiz buferlash o'rniga sizning xabaringiz bilan json bo'ladi.

O'zgartirishlar: Men sizning os x - php5.6 envda sinab ko'rilgan Content-Transfer-Encoding: Binary

Buni sinash kerak

public function getList(){
    try{
       //here i am getting the zip file name.
       $exportFile = $this->getRequest()->getQuery('exportid','');
       $file = 'D:\php7\htdocs\Project\trunk\api\data\\' . $exportFile . '.zip';
       header('Content-Description: File Transfer');
       header('Content-type: application/zip');
       header('Content-disposition: attachment; filename=' . basename($file));

       header("Content-Transfer-Encoding: Binary");
       header("Content-length: " . filesize($file));
       header("Pragma: no-cache"); 
       header("Expires: 0"); 
       readfile("$file");
    } catch(\Exception $e){
       return new JsonModel(["status"=>"Failed"]);
    }
}

JSonModelni javobdan olib tashlang.

0
qo'shib qo'ydi
Shunday bo'lsa-da, fayllar tarkibi chop etiladi: (PHP 7 o'rnatishga ega ekanligimni unutmang.
qo'shib qo'ydi muallif Kuttoozz, manba
Men ham shunga o'xshash natijani oldindan sinab ko'rdim :(
qo'shib qo'ydi muallif Kuttoozz, manba
ogohlantirish olish: filesize (): stat holatlarida va tarkib hozir bosilgan
qo'shib qo'ydi muallif Kuttoozz, manba
Kechirasiz, mening xatolarim fayl hajmi bilan bog'liq emas. Biroq, kontent mening ekranda chop etiladi va fayl yuklab olinmaydi
qo'shib qo'ydi muallif Kuttoozz, manba
Ehtimol siz ham fayllarni tuzishingiz kerak. Yana bir bor urinib ko'rsangiz, afsuski, uni env bilan sinab ko'ra olmayman.
qo'shib qo'ydi muallif Đào Minh Hạt, manba
Bundan oldin file_exist faylini tekshirib ko'rsangiz, ehtimol window uchun bu izoh bo'limiga murojaat qiling.
qo'shib qo'ydi muallif Đào Minh Hạt, manba
Content-Transfer-Encoding: Ikkilik funktsiyasini yo'qotib qo'ydingiz, ilova qilib, tahrir qilishimga harakat qilib ko'ring.
qo'shib qo'ydi muallif Đào Minh Hạt, manba

Bu men uchun ishladi!

        ob_clean();//Clear any previously written headers in the output buffer

        $filepath = "some_file.zip";
        $content_type = 'application/octet_stream';
        $filetype = filetype($filepath);
        $filename =$filepath;
        if($filetype=='application/zip')
        {
            if(ini_get('zlib.output_compression'))
                ini_set('zlib.output_compression', 'Off');
            $fp = @fopen($filepath, 'rb'); 
            if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
            {
                header('Content-Type: '.$content_type);
                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(trim($filepath)));
            }
            else
            {
                header('Content-Type: '.$content_type);
                header('Content-Disposition: attachment; filename="'.$filename.'"');
                header("Content-Transfer-Encoding: binary");
                header('Expires: 0');
                header('Pragma: no-cache');
                header("Content-Length: ".filesize(trim($filepath)));
            }

            fpassthru($fp);
            fclose($fp);
        }
0
qo'shib qo'ydi
if ($ filetype == 'application/zip') kodini o'chirib tashladim va fayl mazmuni tekshirilgandagini tekshirdim. filetype (): Lstat muvaffaqiyatsiz tugadi
qo'shib qo'ydi muallif Kuttoozz, manba
Bu, albatta, ishlaydi: <? PHP header ('Content-Type: application/octet_stream'); header ('Content-Disposition: file name = "'. $ _ REQUEST [" fayl "]. ''); echo file_get_contents ($ _ REQUEST ["fayl"]); Chiqish; ?>
qo'shib qo'ydi muallif Muhammad Athar, manba
yoki header ("Content-Type: application/zip") dan foydalaning; echo file_get_contents ("filename.zip"); chiqish;
qo'shib qo'ydi muallif Muhammad Athar, manba
header ("Content-Type: application/octet_stream") harakat qilib ko'ring; echo file_get_contents ("filename.zip"); chiqish;
qo'shib qo'ydi muallif Muhammad Athar, manba
PhP |BotsUz
PhP |BotsUz
93 ishtirokchilar

Phpni o'rganishni Hohlasangiz https://t.me/joinchat/AAAAAE-KRc5dd5tPMmGmWA A'zo bo'lin