Jak nabídnout soubor ke stažení v Nette

Nabídnout soubor ke stažení je běžná věc a určitě ji musí řešit každý, a jak to udělat elegantně v Nette framework.


Zdrojový kód ke stažení ContentDownloadResponse.php.txt

Pokud chcete nabídnout uživateli soubor ke stažení, potřebujete mu poslat sadu určitých hlaviček, o tom už jsem psal v článku Jak nabídnout soubor ke stažení.

V Nette s MVC to můžete udělat jednoduše a to za pomocí předdefinovaných typů responses. Najdete je v adresáři Nette/Application/Responses, stejné třídy mají na starost vykreslení stránky, přesměrování nebo json response apod.

Stačí na to jeden řádek.

  1. public function actionDownloadFile() {
  2.  $this->terminate(new DownloadResponse('/test.txt', 'jmenosouboru.txt', 'contenttype'));
  3. }

První parametr je cesta k souboru, druhý je název souboru, třetí je content typ, pokud nezadáte zvolí se automaticky application/octet-stream.

Ne vždy však potřebujete poslat ke stažení soubor, ale už vygenerovaný obsah. Aby jste ho nemuseli ukládat do souboru a pak následně načítat, udělal jsem si třídu ContentDownloadResponse.

Asi bude mít spousty chyb a nepřesností, ale funguje a pokud nedostatky najdete, díky za upozornění v diskusi. Celá třída ke stažení v ukázkách.

  1. class ContentDownloadResponse extends Object implements IPresenterResponse {
  2. /** @var string */
  3. private $content;
  4. /** @var string */
  5. private $contentType;
  6. /** @var string */
  7. private $name;
  8. /**
  9. * @param string content
  10. * @param string user name name
  11. * @param string MIME content type
  12. */
  13. public function __construct($content, $name, $contentType = NULL) {
  14. $this->content = $content;
  15. $this->name = $name;
  16. $this->contentType = $contentType ? $contentType : 'application/octet-stream';
  17. }
  18. /**
  19. * Returns the content of downloaded file.
  20. * @return string
  21. */
  22. final public function getContent() {
  23. return $this->content;
  24. }
  25. /**
  26. * Returns the file name.
  27. * @return string
  28. */
  29. final public function getName() {
  30. return $this->name;
  31. }
  32. /**
  33. * Returns the MIME content type of an downloaded file.
  34. * @return string
  35. */
  36. final public function getContentType() {
  37. return $this->contentType;
  38. }
  39. /**
  40. * Sends response to output.
  41. * @return void
  42. */
  43. public function send() {
  44. Environment::getHttpResponse()->setContentType($this->contentType);
  45. Environment::getHttpResponse()->setHeader('Pragma', "public");
  46. Environment::getHttpResponse()->setHeader('Expires', 0);
  47. Environment::getHttpResponse()->setHeader('Cache-Control', "must-revalidate, post-check=0, pre-check=0");
  48. Environment::getHttpResponse()->setHeader('Content-Transfer-Encoding', "binary");
  49. Environment::getHttpResponse()->setHeader('Content-Description', "File Transfer");
  50. Environment::getHttpResponse()->setHeader('Content-Length', mb_strlen($this->content));
  51. Environment::getHttpResponse()->setHeader('Content-Disposition', 'attachment; filename="' . $this->name . '"');
  52. echo $this->content;
  53. }
  54. }

podobné články

31.05.2008Jak nabídnout soubor ke stažení(100%)

komentáře

RSS Komentáře k článku RSS Komentáře   Add to Google
25.11.2009 13:51 | Anonym (v6ak) | Nette extras

Co takhle Nette extras + nějaká licence?

25.11.2009 20:16 | Administrátor | Re: Nette extras

moc mi nejde php fashion a ty komentáře a tak aby to bylo hezké, takže extras … klidně pokud to za to stojí a někdo se koukne na krásu kódu a komentářů

licence? na tohle snad není potřeba licence je to pár řádků kódu, BSD, MIT je něco volnějšího?

29.11.2009 16:31 | Anonym (v6ak) | Re: Re: Nette extras

Teď poté, co jsem projel kód bych měl jednu připomínku: Toto: Environment::get­HttpResponse()->setContentTy­pe($this->contentType); Environment::get­HttpResponse()->setHeader(‚Prag­ma‘, „public“); … se dá zkrátit a vysušit takto: $httpResponse = Environment::get­HttpResponse(); $httpResponse->setContentTy­pe($this->contentType); $httpResponse->setHeader(‚Prag­ma‘, „public“); …

Jinak bych připomínky neměl.

Volba licence je právo autora. Je zde samozřejmě vhodná nějaká volnější opensource licence (BSD i MIT/X11 sem patří).

Přidat to jde na http://addons.nettephp.com/cs/ – je to wiki, takže to může přidat každý.

25.11.2009 16:25 | Anonym (Tomáš Fejfar) | Drobná fintička

Tohle je moc fajn, ale zásadní problém je načtení celého souboru do paměti, což je OK, když máte vlastní server s 64MB paměti pro PHP, ale ne na sdíleném hostingu s 8MB :) řešení jsem shrnul v blogpostu… http://blog.red-pill.cz/…ani-souboru/

25.11.2009 20:18 | Administrátor | Re: Drobná fintička

rozhodně to stojí za zmínku, ale vzhledem k tomu, že článek je spíše jak nabídnout ke stažení obsah v paměti tak sem nic takového neřešil, ale určitě je to potřeba zmínit

Jméno
Název
Text
Lze používat Texy! syntax. Příklad syntaxe: "text odkazu":odkaz, **tučně**, *kurzíva*, `code`. PHP kód uzavírejte do <?php ... ?> a JavaScript do <script> ... </script>