【问题标题】:Upload and display PDF file saved in PostgreSQL using Laravel使用 Laravel 上传并显示保存在 PostgreSQL 中的 PDF 文件
【发布时间】:2018-07-21 15:53:20
【问题描述】:

我有一个项目要求我在数据库中保存一个 PDF 文件(字面意思是将文件保存在数据库中,而不是路径)。我正在使用 PostgreSQL 10 和 Laravel 5.6。这是我的迁移文件:

public function up()
{
    Schema::create('uploads', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('mime');
        $table->binary('data'); // generate a bytea column after running migration
        $table->timestamps();
    });
}

以下是我的控制器中上传PDF文件的功能:

public function upload(Request $req)
{
  $name = pg_escape_string($_FILES['fpdf']['name']);
  $type = pg_escape_string($_FILES['fpdf']['type']);
  $data = pg_escape_bytea(file_get_contents($_FILES['fpdf']['tmp_name']));

  DB::table('uploads')
  ->insert(['name' => $name, 'mime' => $type, 'data' => $data]);

  return "success upload";
}

PDF文件上传成功: Result showed in pgAdmin

但问题是,PDF 文件无法在浏览器中显示(下载)。这是我的控制器中的功能,用于在浏览器中显示 PDF 文件:

public function showPDF($id)
{
  $pdf = Upload::find($id);
  return view('upload/pdf', compact('pdf'));
}

视图文件:

<?php
    $content = pg_unescape_bytea(stream_get_contents($pdf->data));
    echo "<embed src='data:". $pdf->mime .";base64,".base64_encode($content)."' />";
?>

输出是: Output for displaying the PDF file in the browser


我试图通过在 stackoverflow 和其他问答网站上使用关键字“上传并显示存储在 PostgreSQL 数据库中的 PDF 文件”来浏览这么多问题来找到解决方案,但不幸的是我找不到任何关于如何解决的问题显示 PDF 文件。

我在 YouTube (Insert File into MySQL Blob with PHP) 上找到了一个视频,但尝试后仍然没有成功。

我的问题是,如何使用 Laravel 5.6 框架在浏览器上显示/下载 PostgreSQL 数据库中保存的 PDF 文件?

================================================ ====================

我根据 Devon 的建议修改了我的 showPDF 函数,但得到了以下输出:

这是修改后的 showPDF 函数:

public function showPDF($id)
{
    $pdf = Upload::find($id);
    $content = pg_unescape_bytea(stream_get_contents($pdf->data));
    return response($content)->header('Content-Type', $pdf->mime);
}

【问题讨论】:

  • 为什么要使用转义字符串函数?你真的想嵌入还是让他们下载?
  • 嗨,Devon,我想做其中之一,但我更喜欢下载 PDF 文件。
  • 你真的不应该将 pg_ 函数与 Laravel 结合起来。无论如何都不要使用转义字符串函数,即使在 Laravel 之外,您也应该使用准备好的语句。

标签: php laravel postgresql pdf


【解决方案1】:

现在大多数浏览器都内置了 PDF 阅读器,通常没有理由使用 embed,除非您想在其他内容中实际嵌入 PDF。

为此,您应该能够从控制器返回响应,并为 Content-Type 设置标头:

return response($content)->header('Content-Type', $pdf->mime);

【讨论】:

  • 我在我的 showPDF 函数中尝试了你的代码,但它给了我一个错误:响应内容必须是实现 __toString() 的字符串或对象,给定“资源”。
  • 我修改了showPDF函数,但现在错误是未能加载PDF文档(上面问题的详细信息)。我错过了什么?
  • 您的第一条消息表明 $content 不是字符串。
【解决方案2】:

在尝试了几种组合之后,我找到了解决方案。这是我的解决方案:

迁移文件:

Schema::create('uploads', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('mime');
        $table->text('data');
        $table->timestamps();
});

我在迁移文件中所做的是更改列数据的数据类型,之前我使用binary,这里我使用text

我的控制器中上传 PDF 文件的功能:

public function upload()
{
    $name = $_FILES['fpdf']['name'];
    $mime = $_FILES['fpdf']['type'];
    $content = base64_encode(file_get_contents($_FILES['fpdf'['tmp_name']));

    $up = new Upload;

    $up->name = $name;
    $up->mime = $mime;
    $up->content = $content;

    $up->save();

    return redirect('upload');
}

我使用 base64_encode() 函数对 PDF 文件进行编码。这是显示 PDF 文件的方法:

public function showPDF($id)
{
    $pdf = Upload::find($id);

    $content = base64_decode($pdf->content);
    return response($content)->header('Content-Type', $pdf->mime); // thanks to Devon
}

查看文件:

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
    <meta charset="utf-8">
    <title>Demo Upload</title>
</head>
<body>
    <h1>Form Upload PDF File</h1>

    <form action="upload" method="post" enctype="multipart/form-data">
        @csrf

        <br>
        <input type="file" name="fpdf">
        <br> <br>
        <input type="submit" value="Upload">
    </form>

    <p>&nbsp;</p>

    <h3>List of PDFs</h3>

    @foreach($pdfs as $row)
        <a href="show/{{ $row->id }}" target="_blank"> {{ $row->name }} </a>
        <br>
    @endforeach
</body>
</html>

这是我目前的解决方案。我知道这可能不是处理文件上传的最佳方式,但它确实有效。欢迎提出任何使代码更好、更安全的建议。

【讨论】:

    猜你喜欢
    • 2015-06-11
    • 2018-12-07
    • 1970-01-01
    • 2016-08-11
    • 2016-10-05
    • 2011-05-28
    • 2011-07-06
    • 2021-11-06
    • 2020-06-05
    相关资源
    最近更新 更多