如果您使用過PHP,您就會發現它是建立特性豐富的Web頁面的出色工具。作為一大指令碼語言,PHP:容易學習。
有許多強大的架構(比如 CakePHP和CodeIgniter),讓您能夠像 Rails 程式員一樣高效。
能夠與MySQL、PostgreSQL、Microsoft® SQL Server,甚至 Oracle 通訊。
能夠輕鬆地與JavaScript 框架組成,比如 script.aculo.us和jQuery。
但有時候,您想做更多的事情,或必須做更多的事情。我的意思是您必須直接與PHP啟動並執行伺服器的檔案系統打交道。您最終需要處理檔案系統上的檔案,瞭解啟動並執行進程或執行其他任務。
首先,您對在PHP 使用 file()命令開啟檔案很滿意。但是在某種程度上,完成某些事情的唯一途徑是在伺服器上運行shell命令並獲得特定的輸出。例如,您可能想知道特定目錄包含多少個檔案。或者您想知道向某組記錄檔寫了多少行內容。或者您想操作這些檔案,將它們複製到另一個目錄,或使用 rsync 將它們發送到另一個位置。
在“PHP命令列?是的,您可以!” 這篇文章中,Roger McCoy 示範了如何從命令列直接使用 PHP —— 不需任何 網頁瀏覽器。在這篇文章中,我從另一個角度看待相同的主題,向您展示如何緊密地與底層 shell命令整合,以及將傳回值包含到您的介面和進程中。
僅當您運行在Linux®、Berkeley Software Distribution (BSD) 或一些其他 UNIX® 版本上時,這些操作才有效。我假設您運行在Linux-Apache-MySQL-PHP (LAMP) 堆棧上。如果您運行其他版本的UNIX,具體細節可能不同,因為在每個版本中命令列的可用性都不同。我知道很多人還在Mac OS X(運行某個版本的BSD)從事開發,因此我盡量保持樣本命令的通用性,確保移植方便。
命令列概述
PHP Command Line Interface (CLI) Server Application Programming Interface (SAPI) 在PHP V4.2.0開始發布,用於實驗目的。到 V4.3.0 時,已經受到完整支援並且預設啟用。PHP CLI SAPI 允許您開發 PHP 支援的shell指令碼,甚至是基於案頭的指令碼。事實上,可以用 PHP 建立可直接從命令列啟動並執行工具。採用這種方式,PHP開發人員可以像 Perl、AWK、Ruby 或shell 程式員一樣高效。
本文探究構建到 PHP 中的工具,讓您瞭解 PHP啟動並執行底層 shell 環境和檔案系統。PHP 為執行外部命令提供大量函數,其中包括 shell_exec()、exec()、passthru()和system()。這些命令是相似的,但為您啟動並執行外部程式提供不同的介面。所有這些命令都衍生一個子進程,用於運行您指定的命令或指令碼,並且每個子進程會在命令輸出寫到標準輸出 (stdout) 時捕捉它們。
shell_exec()
shell_exec()命令列實際上僅是反撇號 (`) 操作符的變體。如果您編寫過shell 或Perl指令碼,您就知道可以在反撇號操作符內部捕捉其他命令的輸出。例如,清單1 顯示了如何使用反撇號在目前的目錄中擷取每個文本(.txt)的單詞計數。
清單1.使用反撇號計算單詞數量
#! /bin/sh
number_of_words=`wc -w *.txt`
echo $number_of_words
#result would be something like:
#165 readme.txt 388 results.txt 588 summary.txt
#and so on....
在您的PHP指令碼中,您可以在shell_exec() 中運行這個簡單的命令,如清單2 所示,並擷取想要的結果。這裡假設在同一個目錄下有一些文字檔。
清單2.在shell_exec() 中運行相同的命令
<?php
$results = shell_exec('wc -w *.txt');
echo $results;
?>
在圖1 中可以看到,獲得的結果與從shell指令碼得到的一樣。這是因為shell_exec() 允許您通過shell運行外部程式,然後以字串的形式返回結果。
圖1.通過shell_exec()運行shell命令的結果