爲了使用路由是有道理的,你需要做這樣的事情:
public function executeDownload(sfWebRequest $request)
{
// assume this method holds the logic for generating or getting a path to the pdf
$pdfPath = $this->getOrCreatePdf();
// disbale the layout
$this->setLayout(false);
$response = $this->getResponse();
// return the binary pdf dat directly int he response as if serving a static pdf file
$response->setHttpHeader('Content-Disposition', 'attachment; filename="'. basename($pdfPath));
$response->setContentType('application/pdf');
$response->setContent(file_get_contents($pdfPath));
return sfView::NONE;
}
這一行動實際上將讀取該文件併發送內容。但除非你有充分的理由這樣做,否則不可取,因爲你會從php中招致不必要的開銷。
如果您確實有一個很好的理由(限制訪問,動態文件名等),那麼您只需確定在該操作中需要使用哪些參數來確定文件系統上的pdf路徑並建立一條正常的路線。例如,讓我們說你使用人類可識別的slu to來引用文件。然後你有一個db記錄,它包含了slug到文件路徑的映射。在這種情況下,上述行動可能是這樣的:
public function executeDownload(sfWebRequest $request)
{
$q = Doctrine_Core::getTable('PdfAsset')
->createQuery('p')
->where('slug = ?', $request->getSlug());
$this->forward404Unless($asset = $q->fetchOne());
$pdfPath = $asset->getPath();
// disbale the layout
$this->setLayout(false);
$response = $this->getResponse();
// return the binary pdf dat directly in the response as if serving a static pdf file
$response->setHttpHeader('Content-Disposition', 'attachment; filename="'. basename($pdfPath));
$response->setContentType('application/pdf');
$response->setContent(file_get_contents($pdfPath));
return sfView::NONE;
}
與相應的路徑看起來像:
pdf_asset:
url: /download/pdf/:slug
params: {module: yourModule, action: 'download'}
注意如果文件很大,你可能想使用fopen
而不是file_get_contents
,然後以流的形式讀取數據,這樣您就不必將所有數據都放入內存中。這需要你使用一個視圖,但是你仍然可以將佈局設置爲false來阻止佈局封裝你的流數據。
我不認爲我在最初的問題中已經夠清楚了。該目錄需要具有某種類型的安全性。理想情況下,我想使用sfGuard來要求驗證以讀取此目錄中的任何pdf文件。我想只使用href的PDF文件,並將鏈接放在模板上。我不希望有人獲得一個PDF文件的URL,然後能夠讀取沒有身份驗證的文件。 – 2010-12-04 01:37:49