有時(shí)候我們需要在php程序中運(yùn)行一些shell命令,并獲取返回結(jié)果。PHP提供了popen函數(shù)來實(shí)現(xiàn)此功能。popen函數(shù)可以打開一個(gè)進(jìn)程,并與其進(jìn)行通信,同時(shí)也允許我們對這個(gè)進(jìn)程進(jìn)行讀寫操作。不過,當(dāng)需要執(zhí)行一條持續(xù)輸出結(jié)果的命令時(shí),我們需要對popen進(jìn)行一定的循環(huán)處理。本文會通過一個(gè)簡單的例子,詳細(xì)介紹使用popen實(shí)現(xiàn)循環(huán)獲取執(zhí)行輸出的方法。
假設(shè)我們需要執(zhí)行一條命令,這個(gè)命令是每秒鐘持續(xù)輸出當(dāng)前時(shí)間。在終端中執(zhí)行這個(gè)命令可以使用:
watch -n 1 date
它會每秒鐘輸出一次當(dāng)前的時(shí)間,如下所示:
Every 1.0s: date Fri Aug 27 09:56:25 2021
現(xiàn)在我們需要在PHP中運(yùn)行這個(gè)命令,并持續(xù)獲取其輸出。代碼如下:
$handle = popen("watch -n 1 date", 'r'); while (!feof($handle)) { $buffer = fgets($handle); echo $buffer; ob_flush(); flush(); } pclose($handle);
在上面的例子中,我們使用popen打開了一個(gè)名為$handle的進(jìn)程,并將其輸出的結(jié)果以只讀模式賦值給一個(gè)$buffer變量。然后我們使用echo語句將$buffer輸出出來,并使用ob_flush()和flush()函數(shù)將緩沖區(qū)中的數(shù)據(jù)輸出到瀏覽器中。在這個(gè)循環(huán)中,直到讀取完所有的行,才會結(jié)束循環(huán)。最后使用pclose()函數(shù)關(guān)閉進(jìn)程。
當(dāng)執(zhí)行這個(gè)程序時(shí),我們可以看到每秒鐘都會輸出當(dāng)前的時(shí)間。循環(huán)會持續(xù)運(yùn)行,直到我們手動中斷。
總結(jié)一下,在PHP中使用popen函數(shù)與外部進(jìn)程進(jìn)行通信,可以很容易地實(shí)現(xiàn)一些常見的Shell命令。在循環(huán)輸出的情況下,我們需要對popen函數(shù)進(jìn)行循環(huán)處理,并及時(shí)刷新輸出緩沖區(qū)。另外,我們還可以使用fwrite函數(shù)向外部進(jìn)程發(fā)送命令,獲取我們需要的輸出結(jié)果。