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.
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.
- public function actionDownloadFile() {
- $this->terminate(new DownloadResponse('/test.txt', 'jmenosouboru.txt', 'contenttype'));
- }
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.
- class ContentDownloadResponse extends Object implements IPresenterResponse {
- /** @var string */
- private $content;
- /** @var string */
- private $contentType;
- /** @var string */
- private $name;
- /**
- * @param string content
- * @param string user name name
- * @param string MIME content type
- */
- public function __construct($content, $name, $contentType = NULL) {
- $this->content = $content;
- $this->name = $name;
- $this->contentType = $contentType ? $contentType : 'application/octet-stream';
- }
- /**
- * Returns the content of downloaded file.
- * @return string
- */
- final public function getContent() {
- return $this->content;
- }
- /**
- * Returns the file name.
- * @return string
- */
- final public function getName() {
- return $this->name;
- }
- /**
- * Returns the MIME content type of an downloaded file.
- * @return string
- */
- final public function getContentType() {
- return $this->contentType;
- }
- /**
- * Sends response to output.
- * @return void
- */
- public function send() {
- Environment::getHttpResponse()->setContentType($this->contentType);
- Environment::getHttpResponse()->setHeader('Pragma', "public");
- Environment::getHttpResponse()->setHeader('Expires', 0);
- Environment::getHttpResponse()->setHeader('Cache-Control', "must-revalidate, post-check=0, pre-check=0");
- Environment::getHttpResponse()->setHeader('Content-Transfer-Encoding', "binary");
- Environment::getHttpResponse()->setHeader('Content-Description', "File Transfer");
- Environment::getHttpResponse()->setHeader('Content-Length', mb_strlen($this->content));
- Environment::getHttpResponse()->setHeader('Content-Disposition', 'attachment; filename="' . $this->name . '"');
- echo $this->content;
- }
- }
podobné články
| 31.05.2008 | Jak nabídnout soubor ke stažení | (100%) |
komentáře
RSS Komentáře
Teď poté, co jsem projel kód bych měl jednu připomínku: Toto: Environment::getHttpResponse()->setContentType($this->contentType); Environment::getHttpResponse()->setHeader(‚Pragma‘, „public“); … se dá zkrátit a vysušit takto: $httpResponse = Environment::getHttpResponse(); $httpResponse->setContentType($this->contentType); $httpResponse->setHeader(‚Pragma‘, „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ý.
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/



Co takhle Nette extras + nějaká licence?