ImageMagick转换在命令行中可以工作,但不能通过PHP exec()执行。

3

我正在使用PHP的exec()函数,通过ImagicMagick的convert命令来转换一张图片。这个操作在一个CentOS服务器上运行。

exec(convert http://www.google.com/images/srpr/logo3w.png.jpg 
    -resize 640 /home/mysite/public_html/public/img/posts/original/1414_301a4.jpg);

exec()函数不会导致新图像在目标文件夹出现。但是,如果我在 shell 中运行相同的命令,它可以完美地工作!

我认为这是一个路径问题。如果是这样,我该如何检查 PHP 使用的路径,并如何在 PHP 中设置正确的路径?


很可能您的目标文件夹不可写,由运行您的PHP的某种www用户引起。 - Michael Krelin - hacker
“convert” 是否在 PHP 启动运行命令的 shell 路径中?简单的 echo $PATH 命令可以告诉你。 - Marc B
糟糕,我在这里漏掉了引号,但实际使用的代码中肯定有。该目录的文件夹权限应该是多少?777?目前是755。更改文件夹的所有者/组是否有帮助,还是会搞乱事情? - Nyxynyx
我对我要让Imagemagick写入的文件夹执行了chmod 777命令,现在使用exec()就可以正常工作了。 - Nyxynyx
我有同样的问题,但是在liferay中无法工作。在终端中可以运行。 - Bogdan
3个回答

4
function execute($command)
{
    # remove newlines and convert single quotes to double to prevent errors
    $command = str_replace(array("\n", "'"), array('', '"'), $command);
    # replace multiple spaces with one
    $command = preg_replace('#(\s){2,}#is', ' ', $command);
    # escape shell metacharacters
    $command = escapeshellcmd($command);
    # execute convert program
    return shell_exec($command); // or whatever you like
}

哦!终于有人考虑到转义是必要的做法了 :-) - Fabio Mora

3

首先,您应该尝试使用确实存在且可检索的输入文件:

wget http://www.google.com/images/srpr/logo3w.png.jpg
--2012-08-21 20:55:24-- http://www.google.com/images/srpr/logo3w.png.jpg Resolving www.google.com (www.google.com)... 173.194.35.179, 173.194.35.177, 173.194.35.178, ... Connecting to www.google.com (www.google.com)|173.194.35.179|:80... connected. HTTP request sent, awaiting response... 404 Not Found 2012-08-21 20:55:24 ERROR 404: Not Found.

接下来,查看您的PHP使用哪个convert命令:

exec(which convert 2>/tmp/whichconvert.2 1>whichconvert.1)

并且

cat /tmp/whichconvert.{1,2}

最后,还可以尝试使用完整的路径来运行convert命令:

exec(/usr/local/full/path/to/convert logo: 
-resize 640 /home/mysite/public_html/public/img/posts/original/1414_301a4.jpg);

然后

identify /home/mysite/public_html/public/img/posts/original/1414_301a4.jpg

更新:

您想要检索的文件可能不是logo3w.png.jpg,而是logo3w.png

  wget http://www.google.com/images/srpr/logo3w.png
  --2012-08-21 21:04:22--  http://www.google.com/images/srpr/logo3w.png
  Resolving www.google.com (www.google.com)... 173.194.35.180, 173.194.35.177, 173.194.35.179, ...
  Connecting to www.google.com (www.google.com)|173.194.35.180|:80... connected.
  HTTP request sent, awaiting response... 200 OK
  Length: 7007 (6.8K) [image/png]
  Saving to: ‘logo3w.png’
  
  100%[=====================================================>] 7,007       --.-K/s   in 0.02s   
  
  2012-08-21 21:04:22 (451 KB/s) - ‘logo3w.png’ saved [7007/7007]

另外,如果它仅适用于本地文件(而不是远程http-URI),则您需要检查convert使用的http代理是否确实已安装在您的系统上:

convert -list delegate | grep http
      https =>          "/opt/local/bin/curl" -s -k -o "%o" "https:%M"

另外,请检查您的PHP运行账户是否确实具有向目标目录写入的权限:

exec(touch /home/mysite/public_html/public/img/posts/original/touchtest);

然后

ls -l  /home/mysite/public_html/public/img/posts/original/touchtest

0
我的解决方法是提供完整的路径到ImageMagick二进制文件。不要使用convert,而是使用/path/to/convert
$command = $this->imageMagickFullBinaryPath . ' -resize ' . $dimensions . 
           ' ' . $imageFileToResize . ' ' . $resultingThumbnail; 
exec($command, $output);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接