1. 程式人生 > 程式設計 >PHP如何獲取命令列引數

PHP如何獲取命令列引數

使用 php 開發的同學多少都會接觸過 CLI 命令列。經常會有一些定時任務或者一些指令碼直接使用命令列處理會更加的方便,有些時候我們會需要像網頁的 GET 、 POST 一樣為這些命令列指令碼提供引數。比如在針對某些日期做統計的指令碼,就需要傳遞一個日期給它,這樣我們就統計指定日期的一些資料。這類需求應該非常常見,那麼,我們都是如何來接收這些命令列的引數的呢?今天,就來介紹一下這方面的內容。

$argv 獲得所有空格分隔的引數列表

這個變數估計是大家用得比較多的一個接參變量了。它是 PHP 為我們準備好的一個固定變數,目的就是獲取傳遞給指令碼的引數陣列。

print_r($argv);
// php 如何獲取PHP命令列引數.php --a=1 -b=2 -c=3 -d=4 --e=5 ccc ddd 
// Array
// (
//     [0] => 如何獲取PHP命令列引數.php
//     [1] => --a=1
//     [2] => -b=2
//     [3] => -c=3
//     [4] => -d=4
//     [5] => --e=5
//     [6] => ccc
//     [7] => ddd
// )

這個陣列是以引數間隔的空格進行分隔的。第1個元素是當前執行的指令碼檔名,也就是說,不管有沒有引數,這個變數一定會有一個 $argv[0] 表示的是當前的指令碼檔名。

在日常的開發需求中,其實使用這個變數就已經夠用了。但是這明顯不會是我們今天的主題,大家注意到上面的程式碼中我們有很多引數是 -x=xxx 的形式,這種形式的引數是不是和 linux 的命令選HnxzA項非常像,沒錯,這就是我們今天要重點介紹的:從命令列引數列表中獲取選項。

getopt() 從命令列引數列表中獲取選項

其實就是這樣一個簡單的函式,我們就可以像 Linux 的命令選項一樣獲取指定的命令值。而且不是像 $argv 按空格進行分隔,命令選項函式會將這些命令選項封裝成陣列,組成以選項名為鍵,以等號後面的內容為值的陣列,更加方便我們的使用。

// php 如何獲取PHP命令列引數.php --a=1 -b=2 -c=3 -d=4 --e=5 ccc ddd 
print_r(getopt('a:b:c:d:e:f:'));
// Array
// (
//     [b] => 2
//     [c] => 3
//     [d] => 4
// )

是不是很神奇,而且非常直觀吧,我們直接就拿到了 b 、 c 、d 的內容並且是格式非常清晰的鍵值陣列形式。有同學要問了,a 和 e 呢?還有後面的 ccc 、 ddd 呢?

首先要說明的是,ccc 和 ddd 不是標準的選項引數,也就是說,這個函式接收的內容是以 - 開頭的選項,所以 ccc 和 ddd 不會在這裡輸出,並且需要注意的是,非選項引數會中斷選項引數的獲取,在 ccc 之後如果繼續新增 - 開頭的選項也是無法獲取到的,這個我們後面還會看到。而 -- 開頭的選項引數呢?我們直接看下面的長選項功能。

長選項

// php 如何獲取PHP命令列引數.php --a=1 -b=2 -c=3 -d=4 --e=5 ccc ddd 
print_r(getopt('',['a:','b:','c:','d程式設計客棧:','e:','f:']));
// Array
// (
//     [a] => 1
//     [e] => 5
// )

沒錯,getopt() 函式的第二個引數就是定義這種 -- 開頭的長選項的,而且需要注意的是,第一個引數是字串型別,第二個長選項引數是陣列類HnxzA型的。那麼我們把它們結合起來,就當然可以獲取到全部的引數資訊啦!

// php 如何獲取PHP命令列引數.php --a=1 -b=2 -c=3 -d=4 --e=5 ccc ddd 
print_r(getopt('a:b:c:d:e:f:','d:','f:']));
// Array
// (
//     [a] => 1
//     [b] => 2
//     [c] =>HnxzA; 3
//     [d] => 4
//     [e] => 5
// )

OK,引數選項獲取沒問題了吧,細心的同學肯定又發現了一個問題,這個 getopt() 函式的引數中定義的選項名稱後面為啥都要加個冒號?這就涉及到我們的冒號規則了,請直接往下看。

冒號規則

getopt() 的前兩個引數都支援一套關於選項獲取的規則:

  • 單獨的字元(不接受值)
  • 後面跟隨冒號的字元(此選項需要值)
  • 後面跟隨兩個冒號的字元(此選項的值可選)

我們還是直接通過程式碼來看一下。

// 一
// php 如何獲取PHP命令列引數.php --a=1 -b=2 -c=3 -d=4 --e=5 ccc ddd 
print_r(getopt('abcdef'));
// Array
// (
//     [b] => 
//     [c] => 
//     [d] => 
// )

// 二
// php 如何獲取PHP命令列引數.php -f
print_r(getopt('f::'));
// Array
// (
//     [f] => 
// )
print_r(getopt('f:'));
// Array
// (
// )

// 三
// php 如何獲取PHP命令列引數.php -f 22
print_r(getopt('f::'));
// Array
// (
//     [f] => 
// )
print_r(getopt('f:'));
// Array
// (
//     [f] => 22
// )

// 四
// php 如何獲取PHP命令列引數.php -f=22
print_r(getopt('f::'));
// Array
// (
//     [f] => 22
// )
print_r(getopt('f:'));
// Array
// (
//     [f] => 22
// )

這一段比較長,我們一塊一塊來看。首先是不帶冒號的 abcdef 寫法,返回的陣列中都包含鍵,但沒有值,對應上面的規則就是不接受這些引數選項的值,你傳了這些引數選項也是隻有鍵名而內容是空的。

第二段是定義了一個引數,但是不給值,這時,雙冒號 :: 會有鍵名,而單冒號 : 則什麼都沒有。

第三段是空格形式的選項值,雙冒號 :: 有鍵名但沒有值,單冒號 : 鍵值正常。

第四段是等號 = 形式的選項值,單雙冒號都正常接收到鍵值。

選項引數中斷

上文中我們提到過引數中斷的問題,就是在選項引數之後如果有一個非選項引數的引數出現,getopt() 就無法再獲取到這個非選項引數後面的所有內容了。

// php 如何獲取PHP命令列引數.php -f=22 aa -b=33
// 選項的解析會終止於找到的第一個非選項,之後的任何東西都會被丟棄。
// Array
// (
//     [f] => 22
// )

通過這個測試可以清晰的看出後面的 b 選項無法獲取。這時,如果我們想知道選項引數在什麼地方或者因為哪個引數而中斷的話,就可以使用 getopt() 函式的第三個引數了。

// php 如何獲取PHP命令列引數.php -f=22 aa -b=33
$optind = null;
getopt('f:b:',[],$optind);
echo $optind,PHP_EOL; // 返回中斷位置的索引值,2
echo $argv[$optind],PHP_EOL; // 等同於 $argv 的索引順序,aa

註釋已經寫得很清晰了,第三個引數會回撥一個引數選項中斷位置的索引,並且這個索引是和 $argv 的索引順序位置一致的。

總結

說實話,在沒看文件前真的只知道有一個 $argv 變數可以用來獲取命令列指令碼的引數,通過這次學習才發現原來還有一個這麼強大的選項引數函式。學習的過程非常簡單,如何運用到真實的專案中才是關鍵所在,加油學習,努力實踐吧!

測試程式碼:

github.com/zhangyue050…

以上就是PHP如何獲取命令列www.cppcns.com引數的詳細內容,更多關於PHP 獲取命令列引數的資料請關注我們其它相關文章!