【问题标题】:php shell_exec command doesn't act like bash / returns an errorphp shell_exec 命令不像 bash / 返回错误
【发布时间】:2012-05-06 00:34:11
【问题描述】:

这是我的代码:

$url = escapeshellarg("http://www.mysite.com");
$command = shell_exec("xvfb-run -a -s '-screen 0 640x480x16' wkhtmltopdf --dpi 300  --page-size A4 $url /srv/www/mysite/public_html/tmp_pdf.pdf");
$str = file_get_contents("/srv/www/mysite/public_html/tmp_pdf.pdf");
header('Content-Type: application/pdf');
header('Content-Length: '.strlen($str));
header('Content-Disposition: inline; filename="pdf.pdf"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
ini_set('zlib.output_compression','0');
die($str);

在我的 bash shell(使用 Debian)中,命令

shell_exec("xvfb-run -a -s '-screen 0 640x480x16' wkhtmltopdf --dpi 300 --page-size A4 html://www.mysite.com /srv/www/mysite/public_html/tmp_pdf.pdf

工作,它会在所需的位置生成一个 pdf,但是当我在 php 中执行命令时,什么都没有创建,我返回到一个空的 pdf 文件(因为它不存在)。 有人可以帮我找出问题所在吗?

【问题讨论】:

  • 我希望 html:// 协议存在,否则您可能想尝试 http:// .. 此外,要确保 URL 中没有其他字符在 shell_exec/ 中被解释bash,在将其作为参数传递之前,在 url php.net/manual/en/function.escapeshellarg.php 上使用 escapeshellarg()。干杯

标签: php bash pdf pdf-generation wkhtmltopdf


【解决方案1】:

问题是 Apache 服务器没有对我尝试将 pdf 写入的文件夹(在我的示例中为 /srv/www/mysite/public_html/)的写入权限。

所以我只是将文件夹位置更改为 /tmp(每个人都有写权限),现在它可以工作了。更正后的代码是:

$url = escapeshellarg("http://www.mysite.com");
$command = shell_exec("xvfb-run -a -s '-screen 0 640x480x16' wkhtmltopdf --dpi 300  --page-size A4 $url /tmp/tmp_pdf.pdf");
$str = file_get_contents("/tmp/tmp_pdf.pdf");
header('Content-Type: application/pdf');
header('Content-Length: '.strlen($str));
header('Content-Disposition: inline; filename="pdf.pdf"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
ini_set('zlib.output_compression','0');
die($str);

【讨论】:

    【解决方案2】:

    我不知道你的工具,所以把它和一公吨的盐放在一起。

    如果您有 url 并且该工具会自行下载 url,则可能存在一些网络权限阻塞。如果您可以自行下载 url 并为该工具提供可能消除这种可能性的内容(或来自临时文件)。

    还要检查您尝试写入的文件夹的权限。

    既然你说的是Debian,那就执行以下:

    which xvfb-run
    

    这将为您提供可执行文件的完整路径,我将在调用 shell_exec 时使用该路径。

    至于流式传输文件,我会使用 readfile。

    $filePath = "/srv/www/mysite/public_html/tmp_pdf.pdf";
    
    header('Content-Type: application/pdf');
    header('Content-Length: ' . filesize($filePath));
    header('Content-Disposition: inline; filename="pdf.pdf"');
    header('Cache-Control: private, max-age=0, must-revalidate');
    header('Pragma: public');
    ini_set('zlib.output_compression','0');
    
    readfile($filePath);
    exit();
    

    这样做的好处是不需要将整个文件读入内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-22
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2021-02-26
      • 1970-01-01
      相关资源
      最近更新 更多