【问题标题】:Display pdf file from local disk in Laravel 5?在 Laravel 5 中从本地磁盘显示 pdf 文件?
【发布时间】:2018-04-04 12:24:52
【问题描述】:

我有一个 Laravel 5.5 应用程序,具有管理员权限的用户可以上传文件。在他们上传文件后,我希望他们能够在管理员仪表板中查看文件。

我有一个处理文件上传到本地磁盘的DocumentController.php

public function store(Request $request)
{
    // check to make sure user is an admin
    $request->user()->authorizeRoles('admin');

    // validate that the document is a pdf and 
    // that required fields are filled out
    $this->validate($request, [
        'title' => 'required',
        'description' => 'required',
        'user_id' => 'required|exists:users,id', 
        'document_path' => 'required|mimes:pdf'
    ]);

    $file = $request->file('document_path');

    $path = $file->store('documents/' . $request->user_id);

    $document = Document::create([
        'user_id' => $request->user_id,
        'title' => $request->title,
        'description' => $request->description,
        'file_path' => $path
    ]);

    return redirect($document->path());
} 

此方法从表单中获取文件,确保它是 pdf,然后将文件保存到 storage/app/documents/{user_id}。然后它在数据库中创建一个文档记录并根据文档 id 转发到 URL:/admin/document/{ $document->id }

该路由定义为Route::get('/admin/document/{document}', 'DocumentController@show');

在控制器中我将文档传递给视图的位置:

public function show(Document $document, Request $request)
{
    // check to make sure user is an admin
    $request->user()->authorizeRoles('admin');

    $storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();

    return view('admin.document', compact('document', 'storagePath'));
}

我想在那个页面上显示 pdf 文档。

resources/views/admin/document.blade.php

@extends('layouts.app')

@section('content')
<div class='container'>
    <div class='row'>
        <div class='col-sm-2'>
            <a href='/admin'>< Back to admin</a>
        </div>
        <div class='col-sm-8'>
            {{ $document }}

            <embed src="{{ Storage::url($document->file_path) }}" style="width:600px; height:800px;" frameborder="0">

        </div>
    </div>
</div>
@endsection

我已尝试使用$storagePath 变量和Storage 方法,但无法在 iframe 中显示 pdf 文件。

使用本地文件存储如何在浏览器中显示文件?另外,我已经保护了路由,以便只有管理员可以查看文档的页面,但是保护文档本身的路径的最佳方法是什么?

【问题讨论】:

  • $document-&gt;file_path 的值是多少?并回答您的第二个问题 - 为了保护文档,您需要将它们移到您的 webroot 之外,或者使它们无法通过网络访问。我建议前者,以避免将来可能出现权限错误。然后,您将使用 PHP 从文件系统读取文件内容并将其流式传输到浏览器。
  • file_path 是我本地机器上的路径。对于这个应用程序的需要,我认为最好将文件存储在 S3 上。关于将文档存储在 webroot 之外的要点

标签: php laravel laravel-5 file-upload


【解决方案1】:

如果您希望您的文件受到保护(只有管理员可以访问它们),那么您需要创建一个新路由和新的DocumentController 方法getDocument

添加新路线

Route::get('documents/pdf-document/{id}', 'DocumentController@getDocument');

DocumentController中,添加

use Storage;
use Response;

添加将从存储中读取您的 pdf 文件并将其返回的新方法

public function getDocument($id)
{
    $document = Document::findOrFail($id);

    $filePath = $document->file_path;

    // file not found
    if( ! Storage::exists($filePath) ) {
      abort(404);
    }

    $pdfContent = Storage::get($filePath);

    // for pdf, it will be 'application/pdf'
    $type       = Storage::mimeType($filePath);
    $fileName   = Storage::name($filePath);

    return Response::make($pdfContent, 200, [
      'Content-Type'        => $type,
      'Content-Disposition' => 'inline; filename="'.$fileName.'"'
    ]);
}

在您看来,您可以像这样显示文档

<embed
    src="{{ action('DocumentController@getDocument', ['id'=> $document->id]) }}"
    style="width:600px; height:800px;"
    frameborder="0"
>

【讨论】:

    【解决方案2】:

    来自@ljubadr 答案的Response::make() 的较短版本:

    return Storage::response($document-&gt;file_path)

    【讨论】:

      【解决方案3】:
      <embed
      src="{{ url('/filepath') }}"
      style="width:600px; height:800px;"
      frameborder="0">
      

      【讨论】:

      • 请为您的代码添加一些解释 - 它在哪里使用任何 PDF 文件?
      猜你喜欢
      • 2023-03-13
      • 2015-05-29
      • 2017-09-02
      • 2017-11-26
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-25
      相关资源
      最近更新 更多