PHP exec() 与 Pygments for PHP

Posted

技术标签:

【中文标题】PHP exec() 与 Pygments for PHP【英文标题】:PHP exec() with Pygments for PHP 【发布时间】:2013-03-06 11:57:24 【问题描述】:

我目前正在使用位于此处的 Pygments for php 插件:http://derek.simkowiak.net/pygments-for-php/。

从该代码中实际调用 Pygments 的行是一个 exec() 传递:

pygmentize -f html $extra_opts -l $language $temp_name
作为命令。这一切都很好,我得到了输出并由插件格式化。

我希望同时发生的是让 Pygments 创建它的图像,所以我通过 exec() 一个类似的命令:

pygmentize -f png $extra_opts -l $language -o $full_image_path/$output_file.png $temp_name
这是我遇到问题的地方。该图像永远不会出现在预期的文件夹中。

但是,如果我在 exec() 之前 var_dump() 那个命令字符串,然后直接从命令行运行它,它就可以正常工作。

我尝试回显 exec('whoami'),它告诉我 PHP 用户是 www-data。我已经尝试授予 www-data 权限并将所有权更改为我存储图像的文件夹上的 www-data 。我也尝试将权限更改为 777 只是为了看看会发生什么,答案是什么都没有。

我有什么遗漏吗?我已经没有想法可以尝试了。谢谢!

编辑: 我检查的另一件事是 exec 命令的输出和返回值。它输出一个空数组,并返回 1 作为返回值。

编辑 2: 在看到该目录对 PHP 用户应该是可写/可读的之后,pygments 是否可能没有权限将其作为特定用户写入?我不确定这是否有意义,因为当我自己运行它时它工作正常,事实上,当 PHP 使用 HTML 词法分析器运行它时,它能够运行。我在 Python 方面不是很有经验,所以我不知道这是否是一个潜在的问题。

【问题讨论】:

在调用exec()之前尝试使用print()查看构造的命令字符串。这应该告诉你问题是什么。 这会和var_dump() 做同样的事情吗?我var_dump($command) 其中$command 是在调用exec() 之前构造的命令字符串,我得到:pygmentize -f png -O full,style=manni,cssclass=pygmentize_kbOKBd -l php -o /srv/www/path/to/images/uploads/2513732976ad4b7.02729290.png /tmp/pygmentize_kbOKBd。然后我可以自己在命令行中运行它,它工作正常,这就是为什么它对我来说很奇怪,我认为这是一个权限问题,但即使文件夹上有 777 我似乎也无法修复它我把它放进去。 嗯,是的,var_dump 在这里实现了与print 相同的功能;这个想法是为了确认我们正在调用我们认为我们正在调用的东西。因此,既然这很好,我想它排除了这个想法。 要仔细检查 PHP 内部的权限,请使用 PHP 在您要写入的路径上使用 file_exists()is_readable()is_writable() 等检查路径。 如果file_exists() 给出false,那么你的PHP 可能在chroot 环境中;即它可能与系统的其余部分隔离,无法以与普通用户相同的方式访问路径。 【参考方案1】:

我猜你不能这样做。

$output_file.png

试试

$file = $output_file.".png"

并在 exec 中替换

【讨论】:

更改后,问题仍然存在。我认为整个字符串与之前和之后产生的字符串相同。传递给命令行的 exec 命令产生的是这样的:pygmentize -f png -O full,style=manni,cssclass=pygmentize_kbOKBd -l php -o /srv/www/path/to/images/uploads/2513732976ad4b7.02729290.png /tmp/pygmentize_kbOKBd【参考方案2】:

最终导致安装供 www-root 用户使用的字体出现问题。显然,默认情况下用于 Pygments 的那个只是为我在使用命令行时运行的用户安装的。

我能够解决这个问题的方法是运行 exec("$command 2>&1", $out, $code);.

额外的2>&1stderr 重定向到输出中,以便我查看问题。

$out 参数显示了 pygments 抛出的 FontNotFound 错误。

在找到我可以使用的字体后,我通过命令行更改了 Pygments 使用的字体:full,style=manni,cssclass=pygmentize_kbOKBd,font_name='DejaVu Sans Mono' -l php -o /srv/www/path/to/images/uploads/2513732976ad4b7.02729290.png /tmp/pygmentize_kbOKBd

为了查看作为运行脚本的用户我可以使用哪些字体,我只是在 Ubuntu 的 exec() 命令中运行了 fc-list,并检查了输出的可用字体列表。

【讨论】:

以上是关于PHP exec() 与 Pygments for PHP的主要内容,如果未能解决你的问题,请参考以下文章

用于 HTML、PHP 和 JavaScript 的 Pygments 样式

使用 Pygments 在 Jekyll 中突出显示围栏代码块

将 pygments 词法分析器与 antl python 目标一起使用

我应该将 Pygments 与 Scala 应用程序一起使用吗?

PHP:get_current_user() 与 exec('whoami')

Pygments 代码中的行号在 Windows 上的 xampp 中突出显示