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>&1
将stderr
重定向到输出中,以便我查看问题。
$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 应用程序一起使用吗?