调试从 PHP 调用 GraphicsMagick 的想法

发布于 2024-10-09 01:57:20 字数 2869 浏览 7 评论 0原文

我编写了一个小型 PHP 类,它基本上通过 exec() 从 GraphicksMagick 1.3.12 调用 gm Convert 来调整图片大小。实时站点的用户正在报告问题,我也能够在我的开发框中重现一些问题。

相关代码如下所示:

<?php

define('GM_PATH', 'C:\\Archivos de programa\\GraphicsMagick-1.3.12-Q16\\gm.exe');

[...]

private function resize($width, $height, $do_not_upscale=TRUE){
    $source = escapeshellarg($this->source_file);
    $target = escapeshellarg($this->target_file);
    $command = escapeshellarg(GM_PATH) . ' convert ';
    $parameters = array();

    $parameters[] = $source;
    $parameters[] = sprintf('-resize "%dx%d%s"', round($width), round($height), $do_not_upscale ? '>' : '');
    $parameters[] = '+profile "*"';
    $parameters[] = $target;

    $execute = $command . ' ' . implode(' ', $parameters) . ' 2>&1';

    exec($execute, $output, $return);
    if( $return==0 ){
        return $this->target_file;
    }else{
        throw new Exception('Image resizing failed: return code ' . $return . ': ' . implode(PHP_EOL, $output));
    }
}

Live站点在PHP/5.2.9-2下运行,dev站点在PHP/5.3.0下运行。两个机器都运行 Windows Server 2003、Apache/2.2 和 GraphicsMagick 1.3.112 Q16。

在实时站点中,我收到返回代码 1 的异常。在开发站点中,我可以随机看到 cmd.exe 进程如何永远保持空闲状态,使用 0% CPU,直到我终止该任务。

鉴于它是一个外部工具,我已经不知道下一步该做什么了。我该如何解决这个问题?

更新 #1

我修复了一段不相关的代码中的一个小错误,并且我将我能想到的每一个步骤都登录到一个文件中(包括 gm.exe 的活动与 -debug All),但我哪儿也不去。 PHP 到达 exec() 调用,并且 gm.exe 保持永远运行,什么也不做。

更新 #2

我已经通过两种方式执行了确切的命令。日志文件中的回显显示:

"C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" convert  -debug All "\\SHARE\Project\tmp\mini_4d13465d4bc4b.jpg" -resize "1024x1024>" +profile "*" "\\SHARE\Project\tmp\mini_4d13465dafddd.jpg" 2>>"//SHARE/Project/Miniatura-01.log"

Process Explorer 命令行如下所示:

cmd.exe /c ""C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" convert  -debug All "\\SHARE\Project\tmp\mini_4d13465d4bc4b.jpg" -resize "1024x1024>" +profile "*" "\\SHARE\Project\tmp\mini_4d13465dafddd.jpg" 2>>"//SHARE/Project/Miniatura-01.log""

我可以手动运行这两个命令,尽管第二个命令仅从“开始”->“运行”(而不是从命令提示符)运行,除非我 双引号整个表达式

无论如何,我相当确定该命令会按预期执行,因为我确实始终获得调整大小的图像,并且 gm 生成的调试日志看起来很正常。最后一行总是看起来像这样,当它停止时和不停止时:

13:53:52 0:03 3.016u 2344 module.c/UnloadModule/2180/配置: 正在卸载“JPEG”模块...

我怀疑有一些东西会阻止进程在完成后退出:病毒扫描程序、外壳扩展或其他东西...

整个事情开始不值得修复。我会考虑切换到 ImageMagick 或纯 PHP 函数图像。

更新 #3

有趣...我已切换到 ImageMagick,但遇到了同样的问题!我总是可以重现它:我只需要打开两个浏览器选项卡。

很明显我忘记了如何从 PHP 运行命令。我想我会尝试用纯 PHP 代码调整图片大小。

I've written a little PHP class that basically calls gm convert from GraphicksMagick 1.3.12 via exec() to resize a picture. Users from the live site are reporting issues and I've been able to reproduce some problems in my development box as well.

The relevant code looks like this:

<?php

define('GM_PATH', 'C:\\Archivos de programa\\GraphicsMagick-1.3.12-Q16\\gm.exe');

[...]

private function resize($width, $height, $do_not_upscale=TRUE){
    $source = escapeshellarg($this->source_file);
    $target = escapeshellarg($this->target_file);
    $command = escapeshellarg(GM_PATH) . ' convert ';
    $parameters = array();

    $parameters[] = $source;
    $parameters[] = sprintf('-resize "%dx%d%s"', round($width), round($height), $do_not_upscale ? '>' : '');
    $parameters[] = '+profile "*"';
    $parameters[] = $target;

    $execute = $command . ' ' . implode(' ', $parameters) . ' 2>&1';

    exec($execute, $output, $return);
    if( $return==0 ){
        return $this->target_file;
    }else{
        throw new Exception('Image resizing failed: return code ' . $return . ': ' . implode(PHP_EOL, $output));
    }
}

Live site runs under PHP/5.2.9-2 and dev site runs PHP/5.3.0. Both boxes run Windows Server 2003, Apache/2.2 and GraphicsMagick 1.3.112 Q16.

In live site I'm getting an exception with return code 1. In dev site I can randomly see how a cmd.exe process stays idle forever, using 0% CPU until I kill the task.

Given it's an external tool, I've run out of ideas about what to do next. How can I troubleshoot this issue?

Update #1

I fixed a little bug in an unrelated piece of code and I'm logging into a file every individual step I could think of (including gm.exe's activity with -debug All) but I'm going nowhere. PHP reaches the exec() call and gm.exe remains running forever doing nothing.

Update #2

I've got the exact command being executed by two means. An echo into a log file shows this:

"C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" convert  -debug All "\\SHARE\Project\tmp\mini_4d13465d4bc4b.jpg" -resize "1024x1024>" +profile "*" "\\SHARE\Project\tmp\mini_4d13465dafddd.jpg" 2>>"//SHARE/Project/Miniatura-01.log"

In the process properties as shown by Process Explorer the command line looks like this:

cmd.exe /c ""C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" convert  -debug All "\\SHARE\Project\tmp\mini_4d13465d4bc4b.jpg" -resize "1024x1024>" +profile "*" "\\SHARE\Project\tmp\mini_4d13465dafddd.jpg" 2>>"//SHARE/Project/Miniatura-01.log""

I'm able to run both commands manually although the second one only runs from Start->Run (not from a command prompt) unless I double quote the whole expression.

In any case, I'm reasonably sure that the command gets executed as expected because I do get the resized image all the times and the debug log generated by gm looks normal. The the last line always looks like this, when it stalls and when it doesn't:

13:53:52 0:03 3.016u 2344
module.c/UnloadModule/2180/Configure:
Unloading "JPEG" module ...

I suspect there's something that prevents the process from exiting when done: a virus scanner, a shell extension or something...

The whole thing is starting to not be worth the effort of being fixed. I'll consider switching to ImageMagick or plain PHP function images.

Update #3

Funny... I've switched to ImageMagick and I'm getting the same exact issue! And I can reproduce it always: I just need to open two browser tabs.

It's obvious that I've forgotten how to run commands from PHP. I think I'll try to resize the picture with pure PHP code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不气馁 2024-10-16 01:57:20

您是否打印出正在执行的确切命令? (您是否检查过打印的字符串是否有任何明显的错误?)

您是否尝试过直接从命令行运行该确切的命令(即与 PHP 分开)?它在那种情况下有效吗,还是也被锁定在那里?

如果单独运行时完全相同的命令有效,那么您使用 PHP 调用外部命令的方式可能存在问题。

如果它不起作用,那么您提供给 GM 的命令行参数可能有错误,或者您可能在 GM 本身中发现了错误。

不管怎样,这应该可以帮助您更好地处理发生错误的地方。

我建议的另一件事是将 GM 文件夹添加到系统路径中,这样您就可以单独调用 gm 命令,而不必定义整个路径。

哦,顺便说一句,您确实知道 PHP 有 GraphicsMagik 扩展,对吗?这意味着您不需要使用 exec 调用它。您需要从 PECL 安装它,但这可能是值得的...请参阅 http://devzone .zend.com/article/10531

Have you printed out the exact command that is getting executed? (and have you checked that printed string for any obvious errors?)

Have you tried running that exact command directly from the command line (ie separately from PHP)? Does it work in that context, or does it also lock up there?

If the exact same command works when run separately, then you may have an issue with the way you're using PHP to call the external command.

If it doesn't work, then you likely have either an error in the command line parameters you're giving GM, or possibly you've found a bug in GM itself.

Either way, this should help you get a better handle one where the error is occurring.

Another thing I'd suggest is adding the GM folder to your system path, so you can just call the gm command on its own, rather than having to define the whole path.

Oh, and by the way, you do know that PHP has a GraphicsMagik extension right? That would mean you wouldn't need to call it using exec. You'd need to install it from PECL, but it might be worth it... See http://devzone.zend.com/article/10531

独留℉清风醉 2024-10-16 01:57:20

感谢一位同事,我找到了解决方案:

http://es2。 php.net/manual/en/function.exec.php#99781

在 Windows-Apache-PHP 服务器上有
使用exec命令的问题
同时多次。如果一个
脚本(使用 exec 命令)是
同一用户多次加载
同时服务器会
冻结。就我而言,PHP 脚本
使用 exec 命令被用作
图像标签的来源。不止一个
一张 HTML 中的图像制作了服务器
停止。问题描述如下
(http://bugs.php.net/bug.php?id=44942)
连同解决方案 - 停止
exec 命令之前的会话和
之后再次启动。

<?php

session_write_close();
exec($cmd);
session_start();

?>

I found the solution thanks to a co-worker:

http://es2.php.net/manual/en/function.exec.php#99781

On Windows-Apache-PHP servers there is
a problem with using the exec command
more than once at the same time. If a
script (with the exec command) is
loaded more than once by the same user
at the same time the server will
freeze. In my case the PHP script
using the exec command was used as the
source of an image tag. More than one
image in one HTML made the server
stop. The problem is described here
(http://bugs.php.net/bug.php?id=44942)
toghether with a solution - stop the
session before the exec command and
start it again after it.

<?php

session_write_close();
exec($cmd);
session_start();

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文