Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Wysyłanie plików użytkownikowi - Problem
Forum PHP.pl > Forum > Przedszkole
maxil
Witam. Mam mam skrypt na wysyłanie plików użytkownikowi, ale gdy one docierają do klienta są one tak jak by uszkodzone i nie da się ich otworzyć.
Przedstawię kawałek kodu, który odpowiada za wysłanie plików.

  1. if (file_exists($target) && is_file($target))
  2. {
  3. header('Content-Type: application/force-download');
  4. header('Content-Disposition: attachment; filename="'.$file.'";');
  5. header('Content-Transfer-Encoding: binary');
  6. header('Content-Length: '.filesize($target));
  7. readfile($target);
  8. }


Proszę o sprawdzenie kodu i o pomoc w naprawieniu go.
Z góry dzięki. smile.gif
maxil
Cytat(Grzesie.k @ 8.08.2011, 11:49:42 ) *


co przez to sugerujesz?
manuala czytałem według mnie jest wszystko dobrze.
mortus
Kolega tylko odesłał do przykładu funkcji, która podobno zawsze działa. To tylko jej przerobiony fragment, przy czym pozostawiłem komentarze:
  1. header("Pragma: public"); // required
  2. header("Expires: 0");
  3. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  4. header("Cache-Control: private",false); // required for certain browsers
  5. header("Content-Type: application/force-download");
  6. header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" );
  7. header("Content-Transfer-Encoding: binary");
  8. header("Content-Length: ".filesize($fullPath));
  9. flush();
  10. readfile( $fullPath );

Zauważ, że niektóre nagłówki są required, czyli wymagane. $fullPath to u Ciebie $target.
Swoją drogą, czym u Ciebie jest zmienna $file?
thek
A ja chciałbym Ci zwrócić uwage na jedna rzecz... Czy to JEDYNE rzeczy wysyłane przy okazji przez przeglądarkę. Sam kiedyś przypadkiem pisząc kontroler do tego samego celu nie zauwazyłem jednej rzeczy: zanim zaczął przesyłać plik, próbował dopchnąć jeszcze kawałek widoku, który byl dla tego kontrolera bazowym. Wywołując więc metodę renderującą do przegladarki zrobiłem wysyłkę kawałka layoutu + tyle danych z pliku by się length zgadzał, więc nie było szansy się połapać, że posłałem nie to co trzeba bo wielkościowo pliki się zgadzały smile.gif Dopiero po bliższej analizie doszedłem, że błąd powodowało niepełne odseparowanie wysyłki pliku i renderu layoutu, który przykładowo informował, że wysyłanie zostało rozpoczęte.
maxil
Cytat(mortus @ 8.08.2011, 12:09:41 ) *
Kolega tylko odesłał do przykładu funkcji, która podobno zawsze działa. To tylko jej przerobiony fragment, przy czym pozostawiłem komentarze:
  1. header("Pragma: public"); // required
  2. header("Expires: 0");
  3. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  4. header("Cache-Control: private",false); // required for certain browsers
  5. header("Content-Type: application/force-download");
  6. header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" );
  7. header("Content-Transfer-Encoding: binary");
  8. header("Content-Length: ".filesize($fullPath));
  9. flush();
  10. readfile( $fullPath );

Zauważ, że niektóre nagłówki są required, czyli wymagane. $fullPath to u Ciebie $target.
Swoją drogą, czym u Ciebie jest zmienna $file?


zmienna $file to nic innego jak nazwa pliku który ma być wysłany

(edit)
@thek

Właśnie zauważyłem, że mam podobny problem jak Ty miałeś.
Odpaliłem pliczek w HEX EDITOR i zauważyłem piękny kod mojego layoutu.
Jak Ci się udało odseparować wysyłkę pliku od renderu layouta?
Czy mógłbyś naprowadzić mnie na odpowiednie działania?

P.S Nie oczekuję gotowca tylko pomoc w naprawie mojego kodu.
thek
Musisz wyskoczyć z szablonu swojego frameworka, tak by nie korzystało z jego widoku lub dziedziczyć po najbardziej bazowej klasie, która nie korzysta z własnego widoku jeszcze. Ja pracowałem wtedy w Kohanie i dziedziczyłem po Controller. Dopiero z niego bowiem dziedziczą wszystkie inne, w tym Template_Controller, który jest bazowym dla większości aplikacji.
eccocce
Sorry za podpięcie, ale może ktoś wytłumaczyć, po co korzystać z takiego "downloadera"? Jedyny sensowny powód jaki w tej chwili mi się nasuwa, to próba ukrycia bezpośredniej ścieżki do pliku...
erix
Chociażby kontrola pobrań?
thek
@eccocce: Ukrycie ścieżki? Na jeden raz smile.gif Zaraz potem i tak ścieżkę pozna. Ten skrypt, jak wspomniał erix, łączy się z katalogami gdzie htaccess nie daje dostępu. Dzięki jednak połączeniu dodatkowo z ACL możemy w określonych wypadkach zezwolić userom na pobieranie z nich za pomocą właśnie tegoż skryptu.
Podam przykład. Każdy user ma na serwerze swój "katalog domowy". Pewne z katalogów są publiczne (obrazki czy jakieś pliki), ale pewne ma do dostępu tylko on i nikt więcej. Taki schowek. Pograć z niego można pliki tylko takim skryptem i tylko jeśli skrypt wykryje, że próbuje go użyć osoba, która ma do tego uprawnienia. User A więc może tylko swoje pliki przeglądać i nie ma dostępu do plików usera B, nawet jeśli zna dokładną ścieżkę na serwerze. Dostanie Access Forbidden i po zabawie.

Poza tym można użyć do zliczania pobrań czy tego typu kombinacji, gdy chcesz mieć jakieś statystyki proste
eccocce
No fakt, przy pobieraniu od razu poznamy ścieżkę. Czyli dajmy na to zdobyliśmy bezpośrednią ścieżkę do chronionego pliku, próbujemy użyć jej w przeglądarce, żeby pobrać plik, ale w tym momencie nie przepuszcza nas htaccess. Z kolei sam ten skrypt nie daje nam kontroli pobrań, tzn. wymaga dodatkowego mechanizmu autoryzacji i uwierzytelniania, prawda? W końcu skąd skrypt ma wiedzieć, że Ty to Ty i że nawet jeśli to Ty, to czy masz prawo obejrzeć wywoływany plik. Mam tutaj na myśli np. logowanie + właśnie jakiś prosty ACL. O to chodzi?
maxil
dzięki thek za pomoc.
już udało mi się odseparować wysyłkę od renderu layouta i wszystko śmiga pięknie.
thek
@eccocce: prawda. Blokada htacessem i nie dostanie się rzez ściezkę bezpośrednią. Znajomość pliku dostępowego - brak dostepu bo brak uprawnień przez niego wymaganych. Klasyka tego typu skryptów.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.