Чтобы использовать маршрут, чтобы иметь смысл, вам нужно сделать что-то вроде этого:
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 в файловой системе и установить нормальный маршрут. Например, допустим, вы используете распознаваемый человеком слаг для ссылки на файл. Затем у вас есть запись БД, которая содержит отображение пути 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, чтобы не допустить того, чтобы макет обернул ваши потоковые данные).