2012-03-06 123 views
3

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

这是我使用的命令:

<?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而不是我的用户,并导致权限问题,但到目前为止无法使其工作。

任何帮助将不胜感激。

+0

尝试在您的命令中指定'libreoffice'的完整路径,例如'/ usr/local/bin/libreoffice'或者安装它的地方,看看它是否让你更进一步。 – drew010 2012-03-06 23:51:34

+0

处于蠢事的风险 - exec()不会返回错误消息,你确定它默默地失败吗?你试过passthru()吗? – Michal 2012-03-07 00:32:51

回答

3

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

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

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

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

您的处理程序最简单的形式可以是一个永久循环的脚本,检查spool文件夹中的“要处理的文件”,如果找到它们,请使用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 

想一想吗?

+0

谢谢,这似乎是一个很好的方法。自从我解决这个问题已经很长时间了,但下次我会试试这个。 – Flupkear 2012-09-12 14:50:38

5

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

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

谢谢,我会试试看。 – Flupkear 2012-09-12 14:49:48

+0

类似的想法在这里(http://superuser.com/questions/627266/convert-file-to-pdf-using-libreoffice-under-user-apache-i-e-when-using-php)。 – 2014-06-02 13:38:06

+0

你节省了我的一天!,魔法是 - > HOME =/tmp,我想这是因为apache用户没有任何$ HOME文件夹。 – Lyoneel 2015-03-19 07:02:03

4

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

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

只要检查权,LibreOffice的使用用户的主文件夹,如果使用默认Ubuntu的设置,然后运行PHP代码oenter WWW和仁数据的权利,它的家是/ var/www /,脚本,但默认这个目录是由root.enter代码在这里

在PH资P - 你可以看到 - 瑞:

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

在控制台 - 你可以看到你的家,给正确的权限:

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

这对CentOS下的Nginx有效:* chown apache:apache/var/www -R *。你拯救了我的一天。谢谢。 – 2014-04-02 10:21:18

+0

对'CentOS 6.3 x86_64'' libreoffice4.2'也适用我......最重要的是非常感谢你,先生.. – 2014-07-11 02:42:08

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