3

目前我正在研究zf2。现在我必须提供下载选项来下载 pdf 文件。我已将所有 pdf 文件存储在data目录中。如何从 .phtml 文件中指定指向该 pdf 文件的链接?

提前致谢。

4

3 回答 3

7

用户永远不会直接访问您的/data目录。这不会那么好。但是您可以轻松地为自己编写一个download-script.php或类似的东西,将这个目录的内容分发给您的用户。

如果你看一下前六行,public/index.php你会看到以下内容:

<?php
/**
 * This makes our life easier when dealing with paths. Everything is relative
 * to the application root now.
 */
chdir(dirname(__DIR__));

考虑到这一点,您知道从 PHP 的角度来看,访问data目录中的任何内容都非常简单data/file.pdf

您总是想为自己编写某种下载记录器。给自己写一个控制器。在该控制器内部有一个动作可能称为类似download或类似的东西。该动作应该有一个参数filename

此操作所做的只是检查文件名是否存在file_exists('data/'.$filename),如果存在,您只需将该文件交付给您的用户。混合或 zf2 和本机 php 的示例可能是:

public function downloadAction() 
{
    $filename = str_replace('..', '', $this->params('filename'));
    $file     = 'data/' . $filename;

    if (false === file_exists($file)) {
        return $this->redirect('routename-file-does-not-exist');
    }

    $filetype = finfo_file($file);
    header("Content-Type: {$filetype}");
    header("Content-Disposition: attachment; filename=\"{$filename}\"");
    readfile($file);

    // Do some DB or File-Increment on filename download counter
    exit();
}

这不是干净的 ZF2,但我现在很懒。Response使用适当的对象并在那里进行文件处理可能更理想!

重要更新这件事实际上也很不安全。您需要禁止父文件夹。你不会想让这个人在data/download 目录之外做一些事情,比如

`http://domain.com/download/../config/autoload/db.local.php` 

如果我没有完全弄错的话,简单地替换所有出现的双点就足够了......

于 2013-09-25T08:12:54.863 回答
2

我会在公共目录中为数据文件夹中的 PDF 文件创建一个符号链接。

例如:

ln -s /your/project/data/pdfdir /your/project/public/pdf

并创建类似的链接

<a href="/pdf/file.pdf">File.pdf</a>
于 2013-09-25T07:00:37.670 回答
0

借用 Sam 的代码,这是 ZF2 语法中的样子。

public function downloadAction()
{
    $filename = str_replace('..', '', $this->params('filename'));
    $file     = 'data/' . $filename;

    if (false === file_exists($file)) {
        return $this->redirect('routename-file-does-not-exist');
    }

    $filetype = finfo_file($file);
    $response = new \Zend\Http\Response\Stream();
    $response->getHeaders()->addHeaders(array(
        'Content-Type' => $filetype,
        'Content-Disposition' => "attachement; filename=\"$filename\""
    ));
    $response->setStream(fopen($wpFilePath, 'r'));
    return $response;
}
于 2017-08-09T20:09:31.457 回答