Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Zwrócenie pliku pobranego cURL-em
trollman
post 20.08.2015, 21:55:02
Post #1





Grupa: Zarejestrowani
Postów: 23
Pomógł: 0
Dołączył: 14.12.2012

Ostrzeżenie: (0%)
-----


Witam,
Mam taki problem, otóż pobrałem sobie cURL'em plik z serwera, jednakże zapisuje mi się on na razie na moim serwerze.
Macie Panowie jakieś sposoby jak wymusić aby otwrzyło się nam normalnie okno w przeglądarce gdzie zapisać plik gdy klient otworzy skrypt?

Poniżej ten skrypt co napisałem, zapisuje on pobrany plik do katalogu w którym znajduje sie skrypt php. A teraz jak uczynić jak ktoś otworzy np. www.mojastrona.pl/skrypt.php aby otworzyło mu sie okno z pobieraniem (te domyślne).

  1. $temp_file_contents = downloadPage($url);
  2. write_to_file($temp_file_contents,$title);
  3.  
  4. function downloadPage($url, $ref = ''){
  5.  
  6. $ch = curl_init();
  7. $userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
  8. curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
  9. curl_setopt($ch, CURLOPT_URL, $url);
  10. curl_setopt($ch, CURLOPT_VERBOSE, 1);
  11. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  12. curl_setopt($ch, CURLOPT_AUTOREFERER, false);
  13. curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
  14. curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
  15. curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  16. curl_setopt($ch, CURLOPT_HEADER, 1);
  17. $result = curl_exec($ch);
  18. curl_close($ch);
  19. return($result);
  20. }
  21.  
  22. function write_to_file($text,$new_filename){
  23. $fp = fopen($new_filename, 'w');
  24. fwrite($fp, $text);
  25. fclose($fp);
  26. }
Go to the top of the page
+Quote Post
kartin
post 20.08.2015, 22:18:46
Post #2





Grupa: Zarejestrowani
Postów: 246
Pomógł: 79
Dołączył: 25.05.2010

Ostrzeżenie: (0%)
-----


Jeśli nie masz zamiaru wykorzystywać pliku później to nie potrzebnie go zapisujesz. Możesz od razu wysłać go do użytkownika:
  1. header('Content-Type: ' . $mime); //typ pliku, ostatecznie można dać application/octet-stream
  2. header('X-Content-Type-Options: nosniff');
  3. header('Content-Length: ' . $fileSize); //rozmiar wysyłanego pliku, ostatecznie można pominąć
  4. header('Content-Disposition: attachment; filename="' . $title . '"');
  5. echo $temp_file_contents;


--------------------
Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ...
Go to the top of the page
+Quote Post
trollman
post 21.08.2015, 06:19:14
Post #3





Grupa: Zarejestrowani
Postów: 23
Pomógł: 0
Dołączył: 14.12.2012

Ostrzeżenie: (0%)
-----


Faktycznie działa, najlepsze jest to, że to rozwiązanie już testowałem wcześniej ale nie działało.
Wiecie co było powodem? Podanie rozmieru pliku jakos

  1. header('Content-Length: '.filesize($temp_file_contents));


Automatycznie plik sie zapisywał z rozmiarem 0kb ... gdy nie podaje wgl rozmiaru, działa perfekto.

edit:
Jeszcze taki problem zauważyłem, że jeżeli plik na serwerze jest duży (powyżej 20-50mb) to uruchomienie okna pobierania trwa bardzo długo, wrażenie jest takie jakby najpierw skrypt pobierał sobie plik, żeby następnie go wyświetlić użytkownikowi do pobrania. Idzie jakoś to obejść tak aby użytkownik miał od razu popup z pobieraniem?

Ten post edytował trollman 21.08.2015, 18:36:48
Go to the top of the page
+Quote Post
kartin
post 22.08.2015, 14:14:13
Post #4





Grupa: Zarejestrowani
Postów: 246
Pomógł: 79
Dołączył: 25.05.2010

Ostrzeżenie: (0%)
-----


Cytat(trollman @ 21.08.2015, 07:19:14 ) *
  1. header('Content-Length: '.filesize($temp_file_contents));

Nic dziwnego, że nie zadziałało bo filesize() jako parametr przyjmuje nazwę pliku a nie jego zawartość. Możesz przetestować strlen():
  1. header('Content-Length: ' . strlen($temp_file_contents) * 8);

Cytat
strlen() returns the number of bytes rather than the number of characters in a string.


Cytat(trollman @ 22.08.2015, 13:37)
  1. function downloadPage2($url) {
  2. // ...
  3. curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $buffer) {
  4. header('Content-Type: application/octet-stream'); //typ pliku, ostatecznie można dać application/octet-stream
  5. header('X-Content-Type-Options: nosniff');
  6. // header("Content-Transfer-Encoding: binary");
  7. // header("Content-Length: $fileSize"); //rozmiar wysyłanego pliku, ostatecznie można pominąć
  8. header('Content-Disposition: attachment; filename="mp3.mp3"');
  9. echo $buffer;
  10. return strlen($buffer);
  11. });
  12.  
  13. curl_exec($ch);
  14. curl_close($ch);
  15. }
Nagłówki musisz wyciągnąć z funkcji wywoływanej przez CURL i dać np. przed curl_exec($ch); Funkcja jest wywoływana wielokrotnie, co pewną porcję danych, więc nagłówki pojawiają się przed przed każdą przetwarzaną częścią pliku powiększa to rozmiar pliku i powoduje, że jest uszkodzony. Chociaż mp3 może i będzie grało.

Ten post edytował kartin 22.08.2015, 14:17:14


--------------------
Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ...
Go to the top of the page
+Quote Post
trollman
post 22.08.2015, 15:57:22
Post #5





Grupa: Zarejestrowani
Postów: 23
Pomógł: 0
Dołączył: 14.12.2012

Ostrzeżenie: (0%)
-----


Dodałem
  1. curl_setopt($ch, CURLOPT_HEADER, 0);

Aby nie barał nagłówków do ściagnego mp3 jednak to nie pomogło, ciągle plik jest wiekszy niż faktycznie powinien być (przez te nagłówki chyba).
A jak idzie ustawić wielkość pliku przez jego całkowitym pobraniem tak by Content-Length ustawić?
Go to the top of the page
+Quote Post
kartin
post 22.08.2015, 16:23:41
Post #6





Grupa: Zarejestrowani
Postów: 246
Pomógł: 79
Dołączył: 25.05.2010

Ostrzeżenie: (0%)
-----


CURLOPT_HEADER ma się nijak do tego, że przed każdym wysłaniem bufora wysyłasz również swoje nagłówki. Powinny być wysłane wyłącznie jeden raz, przed rozpoczęciem wysyłania treści pliku, a nie wielokrotnie co każdą cześć pliku.
Czepiając się szczegółów to
Cytat
value should be a bool for the following values of the option parameter: (…) CURLOPT_HEADER
ale to akurat tu nie ma znaczenia.

Funkcja używana w CURLOPT_WRITEFUNCTION w tym przypadku powinna mieć tylko dwie linijki kodu:
  1. echo $buffer;
  2. return strlen($buffer);
Nagłówki musisz wyciągnąć z funkcji i dać np. przed curl_exec($ch);


--------------------
Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ...
Go to the top of the page
+Quote Post
trollman
post 22.08.2015, 16:35:22
Post #7





Grupa: Zarejestrowani
Postów: 23
Pomógł: 0
Dołączył: 14.12.2012

Ostrzeżenie: (0%)
-----


Jest już lepiej, mp3 się sciąga nie ma błędów ale jeżeli jest to dużej mp3/set który ma ponad godzine muzyki to pobrało tylko 49min biggrin.gif
Kod wygląda teraz tak

  1. function downloadPage2($url){
  2. $ch = curl_init();
  3. $userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
  4. curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
  5. curl_setopt($ch, CURLOPT_URL, $url);
  6. curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
  7. curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
  8. curl_setopt($ch, CURLOPT_HEADER, 0);
  9. curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $body) {
  10. echo $body;
  11. return strlen($body);
  12. });
  13.  
  14. header('Expires: 0'); // no cache
  15. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  16. header('Cache-Control: private', false);
  17. header('Content-Type: application/force-download');
  18. header('Content-Disposition: attachment; filename="mp3.mp3"');
  19. header('Content-Transfer-Encoding: binary');
  20. // header('Content-Length: '. $fileSize*8); // provide file size
  21. header('Connection: close');
  22.  
  23. curl_exec ($ch);
  24. curl_close($ch);
  25.  
  26.  
  27. }

Dziwne bo nie pobrało całego a mp3 działa .. jakieś pomysły czasmu nie pobrało do końca całego?

Dobra ..
  1. curl_setopt($curl, CURLOPT_TIMEOUT, 0);]
załatwił wszystko.
Kartin, dzięki za pomoc raz jeszcze . Piwo dla Ciebie za wgl obecność na tym forum biggrin.gif

Ten post edytował trollman 22.08.2015, 16:53:15
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 12.06.2024 - 17:35