将 Snappy PDF 生成的字符串转换为服务器上的加密 PDF

将 snappy pdf 生成的字符串转换为服务器上的加密 pdf

本文详细介绍了如何在 Symfony 3.4 应用程序中,将 Snappy PDF 生成的原始 PDF 字符串保存为服务器上的文件,并利用 `qpdf` 工具通过 Symfony 的 `Process` 组件对其进行密码保护。教程涵盖了文件写入、外部命令执行、错误处理以及临时文件清理等关键步骤,旨在提供一个将无保护 PDF 转换为安全加密 PDF 的完整解决方案。

背景与挑战

在使用 Snappy PDF(基于 wkhtmltopdf)生成 PDF 文档时,其通常以字符串形式返回生成的 PDF 内容。然而,wkhtmltopdf 本身不直接提供密码保护功能。为了满足对 PDF 文档进行加密的需求,我们需要将这个 PDF 字符串写入服务器上的临时文件,然后借助外部工具(如 qpdf)对其进行加密处理。在 Symfony 应用程序中,执行此类系统级命令的最佳实践是使用其内置的 Process 组件。

解决方案概述

本教程将分步指导您完成以下操作:

将 Snappy PDF 返回的 PDF 字符串保存到服务器上的一个临时文件。使用 Symfony 的 Process 组件执行 qpdf 命令,对临时 PDF 文件进行密码保护。读取加密后的 PDF 文件内容,并清理所有临时文件。

步骤一:保存 PDF 字符串到临时文件

首先,您需要将 Snappy PDF 生成的 PDF 内容(一个二进制字符串)写入服务器上的一个临时文件。这可以通过 PHP 的 file_put_contents 函数轻松实现。为了确保文件名的唯一性,可以使用 tempnam 函数生成一个唯一的临时文件名。

<?phpuse SymfonyComponentProcessProcess;use SymfonyComponentProcessExceptionProcessFailedException;// 假设 $pdfString 是 Snappy PDF 返回的原始 PDF 内容$pdfString = '%PDF-1.4%âã1 0 obj<>endobj2 0 obj<

注意事项:

tempnam() 函数会创建一个空文件,并返回其路径。sys_get_temp_dir() 确保临时文件存储在系统指定的临时目录中。务必检查 file_put_contents 的返回值,以确保写入成功。设置正确的文件权限 (chmod) 对于外部工具访问文件至关重要。

步骤二:使用 qpdf 进行密码保护

接下来,我们将使用 qpdf 工具对刚刚创建的临时 PDF 文件进行密码保护。qpdf 是一个强大的命令行工具,用于转换和检查 PDF 文件。您需要确保 qpdf 已安装在您的服务器上。

我们将使用 Symfony 的 Process 组件来执行 qpdf 命令。

setTimeout(60); // 设置超时时间,根据 PDF 大小调整try {    $process->run();    // 检查命令是否成功执行    if (!$process->isSuccessful()) {        throw new ProcessFailedException($process);    }    echo "PDF 已成功加密并保存到: " . $protectedPdfPath . "n";    // 确保加密后的文件权限正确    chmod($protectedPdfPath, 0644);} catch (ProcessFailedException $exception) {    // 处理命令执行失败的情况    echo "加密 PDF 失败。n";    echo "错误输出: " . $exception->getMessage() . "n";    echo "标准输出: " . $process->getOutput() . "n";    echo "错误输出: " . $process->getErrorOutput() . "n";    // 清理可能已创建的文件    if (file_exists($unprotectedPdfPath)) {        unlink($unprotectedPdfPath);    }    if (file_exists($protectedPdfPath)) {        unlink($protectedPdfPath);    }    throw $exception; // 重新抛出异常} finally {    // 无论成功与否,都尝试删除未保护的临时文件    if (file_exists($unprotectedPdfPath)) {        unlink($unprotectedPdfPath);        echo "已清理未保护的临时文件: " . $unprotectedPdfPath . "n";    }}?>

注意事项:

qpdf 安装:确保您的服务器上已安装 qpdf。在 Debian/Ubuntu 系统上,可以使用 sudo apt-get install qpdf 安装。命令参数:qpdf –encrypt 命令的参数顺序和含义非常重要。–encrypt word> :设置用户密码、所有者密码和加密密钥长度。权限选项(如 –print=full)控制用户可以对文档执行的操作。– 是一个重要的分隔符,用于区分 qpdf 的选项和文件路径参数。错误处理:ProcessFailedException 是处理命令执行失败的关键。通过 getOutput() 和 getErrorOutput() 可以获取命令的标准输出和错误输出,这对于调试非常有帮助。超时设置:setTimeout() 方法可以防止长时间运行的命令导致脚本挂起。

步骤三:读取加密后的 PDF 并清理

加密完成后,您可以读取加密后的 PDF 文件内容,以便进行后续处理(例如将其作为 HTTP 响应返回给用户,或上传到云存储)。最后,务必清理所有临时文件,以避免服务器磁盘空间被占用。

 'application/pdf',//     'Content-Disposition' => 'attachment; filename="protected_document.pdf"',// ]);?>

综合示例代码

将上述所有步骤整合到一个完整的 PHP 脚本中,您可以在 Symfony 控制器或服务中调用此逻辑。

setTimeout(120); // 增加超时时间以适应大型 PDF            $process->run();            if (!$process->isSuccessful()) {                throw new ProcessFailedException($process);            }            chmod($protectedPdfPath, 0644);            // 3. 读取加密后的 PDF 内容            $protectedPdfContent = file_get_contents($protectedPdfPath);            if ($protectedPdfContent === false) {                throw new RuntimeException('无法读取加密后的 PDF 文件: ' . $protectedPdfPath);            }            return $protectedPdfContent;        } catch (Exception $e) {            // 记录错误或进行其他错误处理            error_log("PDF 加密失败: " . $e->getMessage());            if ($e instanceof ProcessFailedException) {                error_log("QPDF 错误输出: " . $e->getProcess()->getErrorOutput());                error_log("QPDF 标准输出: " . $e->getProcess()->getOutput());            }            return null; // 或者抛出自定义异常        } finally {            // 清理所有临时文件            if ($unprotectedPdfPath && file_exists($unprotectedPdfPath)) {                unlink($unprotectedPdfPath);            }            if ($protectedPdfPath && file_exists($protectedPdfPath)) {                unlink($protectedPdfPath);            }        }    }}// 如何在控制器中使用:// class MyController extends Controller// {//     public function generateProtectedPdfAction()//     {//         // 假设您已经从 Snappy PDF 获取了 $originalPdfString//         $originalPdfString = $this->get('snappy.pdf')->getOutputFromHtml('

Hello World

');//// $pdfProtectorService = $this->get('app.pdf_protector_service'); // 假设服务已注册// $protectedPdfContent = $pdfProtectorService->protectPdfString(// $originalPdfString,// 'my_user_password',// 'my_owner_password'// );//// if ($protectedPdfContent) {// return new Response($protectedPdfContent, 200, [// 'Content-Type' => 'application/pdf',// 'Content-Disposition' => 'attachment; filename="protected_document.pdf"',// ]);// } else {// // 处理加密失败的情况// return new Response('PDF 加密失败。', 500);// }// }// }?>

总结

通过利用 Symfony 的 Process 组件,我们能够有效地在 PHP 应用程序中执行外部命令行工具(如 qpdf),从而实现了将 Snappy PDF 生成的原始 PDF 字符串转换为密码保护的 PDF 文件。这个过程涉及临时文件管理、外部命令的构建与执行、以及健壮的错误处理。遵循这些步骤和最佳实践,可以确保您的应用程序能够安全、可靠地处理 PDF 加密需求。

以上就是将 Snappy PDF 生成的字符串转换为服务器上的加密 PDF的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1340877.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
PHP sprintf 占位符值处理:避免输出完整属性字符串
上一篇 2025年12月13日 04:13:49
php怎么获取源码下载_php获取源码下载渠道与安全法【技巧】
下一篇 2025年12月13日 04:14:02

相关推荐

发表回复

登录后才能评论
关注微信