2017-04-07 63 views
2

我正在編寫一個PHP腳本,我希望能夠可選使用文件作爲腳本輸入。通過這種方式:如何檢查bash輸入是否被重定向到PHP腳本?

$ php script.php < file.txt 

我,實際上,能夠做到這一點使用file_get_contents

$data = file_get_contents('php://stdin'); 

但是,如果我沒有通過文件的輸入,腳本掛indefinetelly,等待爲輸入。

我嘗試以下,但它沒有工作:

$data = ''; 
$in = fopen('php://stdin', 'r'); 
do { 
    $bytes = fread($in, 4096); 
    // Maybe the input will be empty here?! But no, it's not :(
    if (empty($bytes)) { 
     break; 
    } 
    $data .= $bytes; 
} while (!feof($in)); 

腳本等待fread返回一個值,但它永遠不會返回。我想它會以相同的方式等待一些輸入file_get_contents

另一個嘗試是將do { ... } while循環替換爲while { ... },在嘗試讀取輸入之前檢查EOF。但是這也沒有奏效。

關於如何實現這一點的任何想法?

+0

@JustOnUnderMillions也許我從PHP客戶端問得太多了,但還有其他的非PHP **命令行程序實現了這個邏輯 - 讀取輸入或忽略/退出。 –

+0

是的,你說得對。我在錯誤的車道上。 @Alex Howansky注意到它。 – JustOnUnderMillions

回答

3

您可以通過stream_set_blocking()函數將STDIN設置爲非阻塞。

function stdin() 
{ 
    $stdin = ''; 
    $fh = fopen('php://stdin', 'r'); 
    stream_set_blocking($fh, false); 
    while (($line = fgets($fh)) !== false) { 
     $stdin .= $line; 
    } 
    return $stdin; 
} 

$stdin = stdin(); // returns the contents of STDIN or empty string if nothing is ready 

很明顯,你可以改變使用線在-A-時間fgets()到大塊-AT-A-時間fread()按您的需求。

+1

正如我從OP所理解的那樣,我認爲這不是關於阻塞IO,而是關於檢查輸入是否isset,'然而,如果我沒有將文件傳遞到輸入,那麼腳本會不確定地掛起,等待輸入「。 – hassan

+0

正確 - 這項技術將緩解這個問題。如果在STDIN上沒有可用的輸入,該函數將立即返回一個空字符串。 –

+0

@AlexHowansky,它按我想要的方式工作。我不知道'stream_set_blocking'函數。 –