【问题标题】:Cakephp 2.3.x Sending Files and forcing the download of a mp4 fileCakephp 2.3.x 发送文件并强制下载 mp4 文件
【发布时间】:2026-01-24 04:05:01
【问题描述】:

我使用的是 cakephp 2.3.1

我想通过http://book.cakephp.org/2.0/en/controllers/request-response.html#cake-response-file强制下载一个mp4文件

在我的“视图”中,我有以下代码可以正确搜索文件名、找到文件名并显示下载链接:

<?php $filename = APP . 'webroot/files/' . $dance['Dance']['id'] . '.mp4'; 
if (file_exists($filename)) {
    echo $this->Html->link('DOWNLOAD', array('controller' => 'dances', 'action' => 'sendFile', $dance['Dance']['id'])); 
    } else {
    echo 'Coming soon: available April 16th';
    }
?>

当用户点击链接时,我想强制下载 mp4 文件。在我的控制器中,我有以下代码不起作用:

public function sendFile($id) {
    $file = $this->Attachment->getFile($id); //Note: I do not understand the 'Attachment' and the 'getFile($id)'
    $this->response->file($file['webroot/files/'], array('download' => true, 'name' => 'Dance'));
    //Return reponse object to prevent controller from trying to render a view
    return $this->response;
}   

我不明白 'Attachment' 和 'getFile()'

我收到以下错误: 错误:在非对象上调用成员函数 getFile()

我做错了什么,是否有任何其他文档可以让我更好地理解这一点?

【问题讨论】:

    标签: file cakephp download


    【解决方案1】:

    您不理解的那行只是示例的一部分——它假定应用程序有一个名为Attachment 的模型,并且它有一个名为getFile 的方法。由于您没有Attachment 模型(或者至少它对控制器不可见),您会收到“对非对象成员函数的调用”错误。不过这并不重要:您只需要担心提供到this-&gt;response-&gt;file() 的完整系统路径。在您的示例中,您可能可以通过将该行更改为:

    $this->response->file(WWW_ROOT.'files/'. $id .'.mp4', array('download' => true, 'name' => 'Dance'));
    

    您可以删除 $this-&gt;Attachment-&gt;getFile 行,因为它与您的情况无关。

    如果有帮助,请告诉我!

    【讨论】:

    • 我还能够在公共函数中传递第二个变量,使其看起来像这样:public function sendFile($id, $dance_name) {,这太神奇了,因为它可以让我自动创建文件名。
    • 酷,很高兴它成功了。你能接受这个分析器,让我获得一些声誉吗?干杯:)
    • 好吧,我想我接受答案所要做的就是单击复选标记并将其设为绿色?
    【解决方案2】:
    public function downloadfile($id= null) {        
      $this->response->file(APP.'webroot\files\syllabus'.DS.$id,array('download'=> true, 'name'=>'Syllubus'));
      return $this->response;     
    }
    
    <?php echo $this->Html->link('Syllabus', 
      array('controller' => 'coursesubjects',
        'action'=>'downloadfile',
        $courseSubject['CourseSubject']['subject_syllabus']));
    ?>
    

    【讨论】:

    • 您不需要返回响应。 $this-&gt;autoRender = false 就够了。
    • 你为什么在一个地方使用DS,然后在你指定的路径的其余部分使用\。 DS 表示目录分隔符,设置为系统所需的斜线,因此要么使用 DS 代替所有斜线,要么使用所有硬编码的斜线。