本文目錄一覽:
如何在命令行下運行PHP腳本[帶參數]
.php:?phpecho “Hello from the CLI”;?現在,試著在命令行提示符下運行這個程序,方法是調用CLI可執行文件並提供腳本的文件名:#php phphello.php輸出Hello from the CLI—————–使用標準的輸入和輸出你可以在自己的PHP腳本里使用這三個常量,以接受用戶的輸入,或者顯示處理和計算的結果。要更好地理解這一點,可以看看下面的腳本(列表A):列表A?php// ask for inputfwrite(STDOUT, “Enter your name: “);// get input$name = trim(fgets(STDIN));// write input backfwrite(STDOUT, “Hello, $name!”);?Look what happens when you run it:shell php hello.phpEnter your name: JoeHello, Joe!在這個腳本里,fwrite()函數首先會向標準的輸出設備寫一條消息,詢問用戶的姓名。然後它會把從標準輸入設備獲得的用戶輸入信息讀取到一個PHP變數里,並它把合併成為一個字元串。然後就用fwrite()把這個字元串列印輸出到標準的輸出設備上。—————–使用命令行自變數在命令行里輸入程序參數來更改其運行方式是很常見的做法。你也可以對CLI程序這樣做。PHP CLI帶有兩個特殊的變數,專門用來達到這個目的:一個是$argv變數,它通過命令行把傳遞給PHP腳本的參數保存為單獨的數組元素;另一個是$argc變數,它用來保存$argv數組裡元素的個數。shell php phptest.php chocolate 276 “killer tie, dude!”Array( [0] = test.php[1] = chocolate[2] = 276[3] = killer tie, dude!)正如你可以從輸出的結果看到的,傳遞給test.php的值會自動地作為數組元素出現在$argv里。要注意的是,$argvis的第一個自變數總是腳本自己的名稱。下面是一個更加複雜的例子(列表C):列表C代碼下面是其用法的示例:shell php phpbook.php 21/05/2005 7 single在這裡,腳本首先會檢查$argc,以確保自變數的數量符合要求。它然後會從$argv里提取出每一個自變數,把它們列印輸出到標準的輸出
執行php.exe程序cli提示錯誤如何解決
#!/usr/local/bin/php –q
?php
//Windows平台上,上行應該為:#!C:\php\php.exe -q
echo “你好 PHP CLI!”;
?
不要忘了給該文件設置為可執行的許可權:
$ chmod 755 myfile.php
然後直接輸入以下命令,按回車鍵即可以運行:
$ ./myfile.php
如果要在Windows系統下運行該腳本,則不需要設置文件屬性,
可以直接運行該腳本。
Microsoft Windows [版本 6.0.6000]
版權所有 (C) 2006 Microsoft Corporation。保留所有權利。
C:\ myfile.php
你好 PHP CLI!
再重申一次:如果在Windows平台,CLI腳本的第一行一定要寫正確php.exe所在的位置,像這樣(另外,如果要在CLI腳本中加註釋語句,則要把注釋寫在PHP標籤裡面,因為CLI解釋只認識第一行,不在PHP標籤里認為是語法錯誤):
#!C:\php\php.exe -q
這樣,可以看到在命令行下信息已經列印出來,證明該CLI腳本已經成功運行。
2.從命令行上讀取參數
如果想從命令行獲取參數,CLI可以從$_SERVER[‘argc’]和$_SERVER[‘argv”]取得參數的個數和值。我們再建立一個文件,名字為testargs.php,腳本代碼如下:
#!C:\php\php.exe –q
?php
//UNIX和Linux平台下應該為#!/usr/local/bin/php –q
echo “測試獲取參數:\n”;
echo $_SERVER[“argc”].”\n”;
//顯示傳入的參數值,從索引1開始顯示
echo $_SERVER[“argv”][1].”\n”;
echo $_SERVER[“argv”][2].”\n”;
echo $_SERVER[“argv”][3].”\n”;
echo $_SERVER[“argv”][4].”\n”;
?
在命令行輸入如下代碼:
C:\Users\Johntestargs.php Always To Be Best
測試獲取參數:
4
Always
To
Be
Best
因為我們輸入了一串單詞,為「Always To Be Best」,腳本參數以空格分隔。因此,PHP將其計為4個參數,下面對此說明。
$_SERVER[“argc”]數組返回一個整型的數,代表從命令行上回車後一共輸入了幾個參數。
從上例的結果已經看出,要訪問已經傳入的參數值,需要從索引1開始。因為腳本本身的文件已經佔用了索引0,即$_SERVER[“argv”][0]。
3.處理I/O通道
PHP最初設計不是用於與用戶直接的鍵盤輸入或文本輸出結合使用。了解這一設計是至關重要的,因為如果需要在命令行中執行任何操作,都必須能夠與用戶來回通信。
輸入輸出(I/O)通道這個思想來源於UNIX系統,UNIX系統提供3個文件句柄,用以從一個應用程序及用戶終端發送和接收數據。
我們可以把一個腳本的輸出重定向到一個文件:
php world.php outputfile
如果是在UNIX系統下,也可以使用通道定向到另一個命令或應用程序中。例如:
php world.php | sort.
在PHP 5 CLI中,有一個文件流句柄,可以使用3個系統常量,分別為STDIN、STDOUT和STDERR。下面我們分別介紹。
(1)STDIN
STDIN全稱為standard in或standard input,標準輸入可以從終端取得任何數據。
格式:stdin (』php://stdin』)
下面的例子是顯示用戶輸入:
#!/usr/local/bin/php -q
?php
$file = file_get_contents(“php://stdin”, “r”);
echo $file;
?
這段代碼的工作原理與cat命令很相似,迴轉提供給它的所有輸入。但是,這時它還不能接收參數。
STDIN是PHP的標準輸入設備,利用它,CLI PHP腳本可以做更多的事情。如下面例子:
#!/usr/local/bin/php -q
?php
//UNIX平台下第一行應該為#!/usr/bin/php –q
/* 如果STDIN未定義,將新定義一個STDIN輸入流 */
if(!defined(“STDIN”)) {
define(“STDIN”, fopen(‘php://stdin’,’r’))
}
echo “你好!你叫什麼名字(請輸入):\n”;
$strName = fread(STDIN, 100); //從一個新行讀入80個字元
echo ‘歡迎你’.$strName.”\n”;
?
該腳本執行後將顯示:
你好!你叫什麼名字(請輸入):
比如,輸入Raymond之後,將顯示:
歡迎你Raymond
(2)STDOUT
STDOUT全稱為standard out或standard output,標準輸出可以直接輸出到屏幕(也可以輸出到其他程序,使用STDIN取得),如果在PHP CLI模式里使用print或echo語句,則這些數據將發送到STDOUT。
格式:stdout (』php://stdout』)
我們還可以使用PHP函數進行數據流輸出。如下面例子:
#!/usr/local/bin/php –q
?php
$STDOUT = fopen(‘php://stdout’, ‘w’);
fwrite($STDOUT,”Hello World”);
fclose($STDOUT);
?
輸出結果如下:
Hello World
例如,echo和print命令列印到標準輸出。
#!/usr/local/bin/php –q
Output #1.
?php
echo “Output #2.”;
print “Output #3.”
?
這將得到:
Output #1.
Output #2.Output #3.
說明:PHP標記外的新行已被輸出,但是echo命令或print命令中沒有指示換行。事實上,命令提示符重新出現在Output #2.Output #3. 所在的行中。PHP擁有的任何其他列印函數將會像此函數一樣運行正常,任何寫迴文件的函數也是一樣的。
#!/usr/local/bin/php -q
?php
$STDOUT = fopen(“php://stdout”, “w”);
fwrite($STDOUT, “Output #1.”);
fclose($STDOUT);
?
以上代碼將把php://stdout作為輸出通道顯式打開,並且php://output通常以與php://stdout相同的方法運行。
(3)STDERR
STDERR全稱為standard error,在默認情況下會直接發送至用戶終端,當使用STDIN文件句柄從其他應用程序沒有讀取到數據時會生成一個「stdin.stderr」。
格式:stderr (』php://stderr』)
下面的腳本表示如何把一行文本輸出到錯誤流中。
#!/usr/local/bin/php –q
?php
$STDERR = fopen(‘php://stderr’, ‘w’);
fwrite($STDERR,”There was an Error”);
fclose($STDERR);
?
PHP 5.2可以直接使用STDOUT作為常量,而不是定義上面使用的變數$STDOUT,為了兼容之前版本,我們仍使用了自定義變數,如果您使用的是PHP 5.2,則可以參考STDIN的第二個例子。
4.後台運行CLI
如果正在運行一個進程,而且在退出賬戶時該進程還不會結束,即在系統後台或背景下運行,那麼就可以使用nohup命令。該命令可以在退出賬戶之後繼續運行相應的進程。
nohup在英文中就是不掛起的意思(no hang up)。該命令的一般形式為:
nohup –f scriptname.php
使用nohup命令提交作業,在默認情況下該作業的所有輸出都被重定向到一個名為nohup.out的文件中,除非另外指定了輸出文件。
nohup scriptname.php log.txt
這樣,PHP CLI腳本執行後的結果將輸出到log.txt中,我們可以使用tail命令查看該內容:
tail -n50 -f log.txt
現在再來實現兩個例子,第一個是每隔10分鐘自動生成一個靜態HTML文件,並一直執行下去。腳本代碼如下:
#! /usr/local/bin/php
?php
set_time_limit(0);
while(true){
@fopen(“/usr/local/www/data-dist/content/
article_”.time().”.html”,”w”);
sleep(600);
}
?
保存並且退出vi編輯器,然後賦予genHTML.php文件可執行許可權:
#chmod 755 genHTML.php
然後讓腳本在後台執行,執行如下命令:
$nohup genHTML.php –f
執行上述命令後出現如下提示:
[1] 16623
按回車鍵後將出現shell提示符。上面的提示就是說,所有命令執行的輸出信息都會放到nohup.out文件中。
執行上面命令後,每隔10分鐘就會在指定的目錄生成指定的HTML文件,如article_111990120.html等文件。
如何終止CLI程序的後台運行呢?
可以使用kill命令來終止這個進程,終止進程之前要知道進程的PID號,即進程ID,我們使用ps命令:
www# ps
PID TT STAT TIME COMMAND
561 v0 Is+ 0:00.00 /usr/libexec/getty Pc ttyv0
562 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1
563 v2 Is+ 0:00.00 /usr/libexec/getty Pc ttyv2
564 v3 Is+ 0:00.00 /usr/libexec/getty Pc ttyv3
565 v4 Is+ 0:00.00 /usr/libexec/getty Pc ttyv4
566 v5 Is+ 0:00.00 /usr/libexec/getty Pc ttyv5
567 v6 Is+ 0:00.00 /usr/libexec/getty Pc ttyv6
568 v7 Is+ 0:00.00 /usr/libexec/getty Pc ttyv7
16180 p0 I 0:00.01 su
16181 p0 S 0:00.06 _su (csh)
16695 p0 R+ 0:00.00 ps
16623 p0 S 0:00.06 /usr/local/bin/php /usr/local/www/data/genHTML.php
已經看到PHP的進程ID是:16623,於是再執行kill命令:
$ kill -9 16623
[1]+ Killed nohup /usr/local/www/data/genHTML.php
這時該命令的進程就已經被終止了,再使用ps命令:
$ ps
PID TT STAT TIME COMMAND
82374 p3 Ss 0:00.17 -bash (bash)
82535 p3 R+ 0:00.00 ps
剛才的PHP CLI腳本已經沒有了,如果直接運行ps命令無法看到進程,那麼就結合使用ps apos兩個命令來查看。
注意:上面例子必須運行在UNIX或者Linux系統中,如FreeBSD、Redhat Linux等,在Windows環境不支持nohup命令。
PHP 和cli 有什麼關係 運行一個PHP文件 報錯,該如何解決
CLI 是命令行模式,例如在winXP 的命令行窗口cmd 裡邊,php my_script.php 使用php.exe 直接運行php代碼,相當於控制台應用。
不是web伺服器上運行的。
真需要的話,改成 web伺服器上運行的版本就可以。$argv[0] 是從命令行獲取的參數,改成用變數設置或$_GET或$_POST 獲得。
如何獲取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 的命令選項非常像,沒錯,這就是我們今天要重點介紹的:從命令行參數列表中獲取選項。
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() 函數的第二個參數就是定義這種 — 開頭的長選項的,而且需要注意的是,第一個參數是字元串類型,第二個長選項參數是數組類型的。那麼我們把它們結合起來,就當然可以獲取到全部的參數信息啦!
// php 如何獲取PHP命令行參數.php –a=1 -b=2 -c=3 -d=4 –e=5 ccc ddd print_r(getopt(‘a:b:c:d:e:f:’, [‘a:’,’b:’,’c:’,’d:’,’e:’,’f:’])); // Array // ( // [a] = 1 // [b] = 2 // [c] = 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 變數可以用來獲取命令行腳本的參數,通過這次學習才發現原來還有一個這麼強大的選項參數函數。學習的過程非常簡單,如何運用到真實的項目中才是關鍵所在,加油學習,努力實踐吧!
測試代碼:
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/257542.html