PHP如何执行命令

时间:2012-03-06 23:46:45

标签: php apache execution

我正在尝试使用LibreOffice将电子表格转换为另一种格式,当我从控制台执行命令时它工作正常但是当我使用exec()或system()从PHP执行它时它不起作用。 它没有显示任何错误或任何内容,它只是默默地失败,如果我尝试执行一些简单的命令,如“ls”,它的工作正常。

这是我正在使用的命令:

<?php
system("libreoffice --headless -convert-to ooxml '/home/www/path_to_app/file.xlsx' -outdir /home/www/path_to_app/");

我已经尝试将/opt/lampp/etc/httpd.conf上的apache用户和组更改为我所登录的用户。

我想知道问题是www文件夹是/ home而不是我的用户内部并导致权限问题,但到目前为止无法使其工作。

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:5)

我用下面的命令解决了这个问题:

system('
  export HOME=/tmp 
  libreoffice --headless --invisible --norestore --convert-to pdf --outdir /my/folder /my/file/calc.xls');

答案 1 :(得分:4)

我用下面的命令解决了这个问题:

exec('libreoffice --headless --invisible --norestore --convert-to pdf --outdir /my/folder /my/file/calc.xls');

只是检查权限,libreoffice使用用户主文件夹,如果你使用Ubuntu的默认设置,那么PHP在这里运行中心代码www-data rights,它的主页是/ var / www /,但默认此目录由root.enter拥有代码在这里

在PHP中 - 你可以看到rigths:

exec('whoami', $arr);
print_r($arr);

在控制台中 - 您可以看到您的主页并给出正确的权利:

su wwww-data
echo $HOME
exit;
chown www-data:www-data /var/www -R

答案 2 :(得分:3)

尽管你的$ PATH提到了010,但我不会这样做。

LibreOffice是一个非常大的程序,有很多你不知道的代码,它会在你的$ HOME目录中生成和更新文件,当然不是你能够运行的东西。一次一份。

因此,不要让您的Web服务器启动LibreOffice,并通过将其作为比“www-data”或“nobody”更具特权的用户运行来破坏Apache的安全性,您应该创建一个处理程序。

首先,验证您是否可以从终端运行libreoffice ...命令行。为了确保您没有任何X11依赖项,请在测试命令行之前在xterm中运行unset DISPLAY(对于bash)或unsetenv DISPLAY(对于tcsh)。它破了吗?首先解决这个问题。它有用吗?很好,然后继续处理。

您的处理程序,最简单的形式,可以是一个永远循环的脚本,检查假脱机目录中的“要处理的文件”,如果找到它们,使用libreoffice转换它们并将结果文件放在可能的位置通过您的网络应用找到。

#!/bin/sh

while sleep 10; do
  if [ `ls /var/tmp/myspool/ | grep -c '\.xlsx$'` -gt 0 ]; then
    ls /var/tmp/myspool/*.xlsx | while read file; do
      /usr/local/bin/libreoffice --headless -convert-to ooxml "$file" yadda yadda
      if [ $? = 0 ]; then
        mv "$file" "/var/tmp/myspool/done/
      fi
    done
  fi
done

如果您不想要“轮询”(每10秒检查假脱机目录)的开销,那么您可以让PHP脚本在处理程序监视的日志中添加一行。例如:

<?php

// process form, save file to spool dir
syslog(LOG_NOTICE, "Saved: " . $filename);

?>

确保您已配置syslog以将这些消息存储在/var/log/filelog中,然后您的处理程序可以直接记录日志。

#!/bin/sh

tail -F /var/log/filelog | while read line; do
  filename="`echo \"$line\" | sed 's/.*Saved: //'`"
  /usr/local/bin/libreoffice --headless -convert-to ooxml "$file" yadda yadda
  # etc ... error handling and mv as in the other script
done

明白了吗?

答案 3 :(得分:0)

我之前也遇到过同样的问题......

这个解决方案似乎对我有用......

function execInBackground($cmd) { 
    if (substr(php_uname(), 0, 7) == "Windows"){ 
        pclose(popen("start /B ". $cmd, "r"));  
    } 
    else { 
        exec($cmd . " > /dev/null &");   
    } 
} 

$mainFile = "YOUR FILE";     
$cmd2 = "export HOME=/tmp
             libreoffice --headless --invisible --norestore --convert-to pdf " .
                    "'$mainFile'";



        $saved = getenv("LD_LIBRARY_PATH");        // save old value 
        $newld = "/usr/lib";  // extra paths to add 
        if ($saved) {

            putenv("LD_LIBRARY_PATH=" . $newld);
        }           
                // set new value 
        //


        // command is loaded using 
        // libs in the new path list 
        execInBackground($cmd2);
        putenv("LD_LIBRARY_PATH=$saved");        // restore old value