You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将PHP变量存储的PDF数据通过exec传递给PDFtk处理?

核心原因

exec()函数的作用只是将拼接好的字符串传入系统Shell执行,本身不限制传入内容的类型,你第二段代码运行失败和exec无关,是两个问题导致的:

  • 直接把PDF二进制内容拼接到命令字符串中完全不符合Shell语法规则。PDF是二进制格式,包含大量Shell特殊字符(空格、引号、控制符、空字节等),拼接后会直接打乱命令结构,Shell根本无法正确解析指令。
  • PDFtk本身不会从命令参数位置读取PDF二进制内容,默认只接收物理文件路径作为输入源,直接把二进制内容塞在参数位置,PDFtk只会把这串乱码当成一个不存在的文件名,自然运行失败。
内存PDF数据的正确调用方式

PDFtk支持用特殊文件名-代表从标准输入(stdin)读取源PDF内容,你不能用exec直接拼命令传内容,需要用proc_open打开进程管道,把内存里的PDF数据写入进程的输入流即可,不需要把PDF落地存成实体文件。
可直接参考以下实现代码:

<?php
// 内存中存储的PDF二进制数据,不管是从接口拿到的还是本地读的都可以
$pdfContent = file_get_contents('12345.pdf');
$descriptors = [
    0 => ['pipe', 'r'], // 进程标准输入,用来给pdftk传PDF数据
    1 => ['pipe', 'w'], // 进程标准输出,用来接收正常返回内容
    2 => ['pipe', 'w']  // 进程标准错误,用来接收报错信息
];
// 启动pdftk进程:- 代表从标准输入读源文件,提取第2页输出到abc.pdf
$process = proc_open('pdftk - cat 2 output abc.pdf', $descriptors, $pipes);
if (is_resource($process)) {
    // 把内存里的PDF内容写入输入管道
    fwrite($pipes[0], $pdfContent);
    fclose($pipes[0]); // 关闭输入流,告知pdftk数据传输完成

    // 按需读取输出和错误信息
    $stdout = stream_get_contents($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[1]);
    fclose($pipes[2]);

    // 关闭进程获取返回码,返回0代表执行成功
    $exitCode = proc_close($process);
    if ($exitCode !== 0) {
        echo "执行失败,错误:" . $stderr;
    }
}
?>
补充说明
  • 任何时候都不要把二进制数据、未经转义的外部输入直接拼接到exec类函数的命令字符串中,不仅会导致运行错误,还会触发严重的命令注入漏洞。
  • 如果业务没有强制要求PDF必须在内存中处理不落地,直接传物理路径给PDFtk是稳定性最高、性能最好的方式,没有管道通信的额外开销。
  • 如果需要把PDFtk处理后的结果也直接存在内存、不生成实体文件,可以把输出文件的位置也换成-,之后从标准输出流$pipes[1]里读取处理完成的PDF二进制内容即可。

内容的提问来源于stack exchange,提问作者TWolfe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:45:33