我有一個腳本,可以作爲網頁運行,也可以通過控制檯運行。檢測一個PHP腳本是否正在交互運行
檢測使用哪種方法來調用腳本看起來非常簡單,但是當從控制檯運行腳本時,我需要知道腳本是否以交互方式運行(用戶鍵入命令或輸入重定向從一個文件)。
php script.php
與 php script.php < input_file
這可能嗎?
我有一個腳本,可以作爲網頁運行,也可以通過控制檯運行。檢測一個PHP腳本是否正在交互運行
檢測使用哪種方法來調用腳本看起來非常簡單,但是當從控制檯運行腳本時,我需要知道腳本是否以交互方式運行(用戶鍵入命令或輸入重定向從一個文件)。
php script.php
與 php script.php < input_file
這可能嗎?
我還需要比posix_isatty
稍微更靈活的解決方案,可以檢測:
經過一些實驗和挖掘libc頭後,我想出了一個非常簡單的類,可以做以上所有和更多。
class IOMode
{
public $stdin;
public $stdout;
public $stderr;
private function getMode(&$dev, $fp)
{
$stat = fstat($fp);
$mode = $stat['mode'] & 0170000; // S_IFMT
$dev = new StdClass;
$dev->isFifo = $mode == 0010000; // S_IFIFO
$dev->isChr = $mode == 0020000; // S_IFCHR
$dev->isDir = $mode == 0040000; // S_IFDIR
$dev->isBlk = $mode == 0060000; // S_IFBLK
$dev->isReg = $mode == 0100000; // S_IFREG
$dev->isLnk = $mode == 0120000; // S_IFLNK
$dev->isSock = $mode == 0140000; // S_IFSOCK
}
public function __construct()
{
$this->getMode($this->stdin, STDIN);
$this->getMode($this->stdout, STDOUT);
$this->getMode($this->stderr, STDERR);
}
}
$io = new IOMode;
一些示例用法,顯示它可檢測到的內容。
輸入:
$ php io.php
// Character device as input
// $io->stdin->isChr == true
$ echo | php io.php
// Input piped from another command
// $io->stdin->isFifo == true
$ php io.php < infile
// Input from a regular file (name taken verbatim from C headers)
// $io->stdin->isReg == true
$ mkdir test
$ php io.php < test
// Directory used as input
// $io->stdin->isDir == true
輸出:
$ php io.php
// $io->stdout->isChr == true
$ php io.php | cat
// $io->stdout->isFifo == true
$ php io.php > outfile
// $io->stdout->isReg == true
錯誤:
$ php io.php
// $io->stderr->isChr == true
$ php io.php 2>&1 | cat
// stderr redirected to stdout AND piped to another command
// $io->stderr->isFifo == true
$ php io.php 2>error
// $io->stderr->isReg == true
我已經不包含的鏈接,插座,或塊設備的例子,但我們沒有理由他們不應該工作,因爲設備模式掩蓋他們在課堂上。
(在Windows未測試 - 里程可能會發生變化)
if (posix_isatty(0)) {
// STDIN is a TTY
} else {
// STDIN is a pipe or has no associated TTY
}
顯然對POSIX兼容的操作系統,其中PHP有posix
擴展安裝這僅適用。我不知道Windoze等價物。
非常好,+1 - 在什麼情況下會'S_IFLNK'和'S_IFSOCK'返回true? – DaveRandom
@DaveRandom:我從來沒有真正發現過(或者需要它們),當我從C頭文件中獲取掩碼時,我將它們包括在內以獲得完整性。他們顯然是相關的鏈接和套接字,但是當我嘗試時,我無法觸發任何東西。 – Leigh
非常感謝。這正是我想要的! :) – Fania