Apache-2.2

PHP 的 shell_exec() 和 apache

  • July 5, 2015

我正在通過 Ratche 在 Apache 伺服器上執行 ZMQ“推送”介面,該介面在命令行上執行良好,完全按照我想要的方式與我的伺服器互動。這是程式碼

//script1.php
<?php
echo exec('php script2.php');
?>

//script2.php
<?php
       $entryData = array(
       'category' => 'modelLmdap'
     , 'job_id'    => '1234'
     , 'text'    => ''
     , 'status'    => ''
   );
   $context = new ZMQContext();
   $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
   $socket->connect("tcp://localhost:5555");
       $socket->send(json_encode($entryData));
?>

當我執行 script1.php 時,我在伺服器視窗中看到一個彈出視窗,顯示“請求已記錄”。但是,如果我嘗試通過瀏覽器執行它,我會得到一個空白頁面並且在伺服器上沒有輸出。

我環顧四周,這可能是由於 Apache 無法在命令行執行,解決方案是將以下內容添加到我的 sudoers(使用 sudo visudo):

www-data ALL=NOPASSWD: ALL

依然沒有!一個空白頁。我將命令切換到 exec() 並收到此錯誤:

致命錯誤:在第 8 行的 /home/username/server/qap/v2/tools/push.php 中找不到類“ZMQContext”

有任何想法嗎?

編輯:有人問我為什麼要做這一切,這是一個很好的問題。

TL;DR 我想不出將另一個 php 腳本作為服務執行的方法——curl 不能在本地工作,並且 include 不能削減它。

我正在執行一些複雜的統計計算,這些計算需要大量資源並且花費太多時間來生成任何輸出,從而導致特殊的腳本執行問題,包括無緣無故的空白頁(即使我已經擴展了最大腳本執行time) 和 AJAX 錯誤,儘管超時已達到最大值。因此,我將伺服器端的計算分配給了許多不同的後台程序,所有這些都是 php 腳本。這也允許我在執行這個長腳本時更新使用者。有問題的呼叫是執行一個控制計算場的“控制器”腳本(這是正確的術語嗎?Idk)。然後該腳本與推送伺服器(通過 ZMQ)通信並將數據推送到客戶端。原始程式碼很重 AJAX,我真的不想更新所有程式碼以使用 websockets,所以我選擇了使用 Ratchet 作為套接字伺服器的“推送”類型。這意味著我可以進行最初的 AJAX 呼叫來啟動整個過程,然後頁面從伺服器接收更新,單向。這有很多優點,我最喜歡的是通信本質上是單向的,這使我不得不在伺服器端實現許多安全功能。不幸的是,為了讓這一切正常工作,Ajax-ed 腳本需要能夠 shell_exec ‘farm’ 腳本,因為它們需要作為後台程序執行,這就是我遇到問題的方式。我嘗試過 curl(),但它只是抓取了裸文本,而 include() 只會導致其他腳本作為 ajax-ed 腳本的一部分執行,這會破壞整點。

如果有什麼我錯過的,請告訴我,我和你一樣討厭不安全的網站!

好的,我已經解決了!

問題是由於系統上安裝了許多不同的 PHP 版本(我將系統從共享託管域移植到私有伺服器,攜帶所有相關的包袱)。Apache 使用的是 php5.4,而 ZMQ 安裝在 5.6 上。

我將所有 php 5.4 文件夾重命名為 php54_old 並創建了一個指向所有相關 php 5.6 文件夾的連結(sudo ln -s /etc/php56 /etc/php54)。我相信這與它的 sudo 權限(上圖)一起允許它工作,儘管我會在部署站點時測試它是否在沒有 sudo 權限的情況下工作。由於許多原因,我對 Apache 具有 sudo 權限感到不舒服——在此期間,我將 Apache 的 sudo 權限限制為僅執行 php。

編輯:哦,我還解除安裝並重新安裝了 ZMQ PEAR 包和 zmq php 包裝器。

引用自:https://serverfault.com/questions/702982