2012-03-06 172 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