執(zhí)行 PHP 文件

CLI SAPI 有三種不同的方法執(zhí)行 PHP 代碼:

  1. 讓 PHP 運(yùn)行指定文件。

    $ php my_script.php
    
    $ php -f my_script.php
    

    以上兩種方法(使用或不使用 -f 參數(shù))都能夠運(yùn)行給定的 my_script.php 文件。注意,沒(méi)有限制可以執(zhí)行哪種文件, 特別是文件名也不必用 .php 作為擴(kuò)展名。

  2. 在命令行中直接傳遞 PHP 代碼執(zhí)行。

    $ php -r 'print_r(get_defined_constants());'
    

    必須特別注意 shell 變量的替代及引號(hào)的使用。

    注意:

    請(qǐng)仔細(xì)閱讀以上范例,它們沒(méi)有開始和結(jié)束標(biāo)識(shí)符!加上 -r 參數(shù)后不需要這些標(biāo)記符,并且加上它們還會(huì)導(dǎo)致語(yǔ)法錯(cuò)誤。

  3. 通過(guò)標(biāo)準(zhǔn)輸入(stdin)提供需要運(yùn)行的 PHP 代碼。

    這為動(dòng)態(tài)創(chuàng)建 PHP 代碼并通過(guò)二進(jìn)制文件執(zhí)行提供了強(qiáng)大的能力,就像下面(虛構(gòu)的)例子展示的一樣:

    $ some_application | some_filter | php | sort -u > final_output.txt
    
以上三種運(yùn)行代碼的方法不能混合使用。

和所有的 shell 應(yīng)用程序一樣,PHP 的二進(jìn)制文件及其 PHP 腳本能夠接受一系列的參數(shù)。PHP 沒(méi)有限制傳送給腳本的參數(shù)的個(gè)數(shù)( shell 對(duì)傳遞的字符數(shù)有限制,但通常都不會(huì)超過(guò)該限制)。傳遞給腳本的參數(shù)可在全局?jǐn)?shù)組 $argv 中獲取。第一個(gè)索引(零)始終包含從命令行中調(diào)用的腳本名稱。注意在命令行內(nèi)使用 -r 執(zhí)行 PHP 代碼時(shí), $argv[0] 的值將是 "Standard input code"; 在 PHP 7.2.0 之前是破折號(hào)(-)。如果代碼是通過(guò)來(lái)自 STDIN 的管道執(zhí)行的,同樣如此。

另外,第二個(gè)全局變量 $argc 包含 $argv 數(shù)組中元素的個(gè)數(shù)(而不是傳遞給腳本的參數(shù)個(gè)數(shù))。

只要傳送給腳本的參數(shù)不是以 - 字符開頭,就無(wú)需過(guò)多的注意什么。向腳本傳遞以 - 開頭的參數(shù)會(huì)導(dǎo)致錯(cuò)誤,因?yàn)?PHP 會(huì)認(rèn)為在執(zhí)行腳本之前應(yīng)該由它自身來(lái)處理這些參數(shù)。為防止發(fā)生這種情況,可以用列表分隔符 -- 參數(shù)來(lái)解決。在 PHP 解析此分隔符之后, 該符號(hào)后的所有參數(shù)將會(huì)被原樣傳遞給腳本程序。

# 以下命令將不會(huì)運(yùn)行 PHP 代碼,而只顯示 PHP 命令行模式的使用說(shuō)明
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# 將會(huì)傳遞 “-h” 參數(shù)傳送給腳本,且 PHP 不會(huì)顯示命令行模式的使用說(shuō)明
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

然而,在 Unix 系統(tǒng)中還有一個(gè)將 PHP 用于 shell 腳本的方法:寫個(gè)腳本,第一行以 #!/usr/bin/php 為開頭 (如果 PHP CLI 二進(jìn)制文件路徑不一樣,則可以指定為任意實(shí)際的路徑)。文件的剩余部分應(yīng)該包含通用的 PHP 開始標(biāo)簽、正常的 PHP 代碼、PHP 結(jié)束標(biāo)簽。一旦設(shè)置正確的文件執(zhí)行屬性(例如 chmod +x test),腳本就像其他 shell/perl 腳本一樣可以執(zhí)行。

示例 #1 PHP 腳本作為 shell 腳本執(zhí)行

#!/usr/bin/php
<?php
var_dump
($argv);
?>

假設(shè)在當(dāng)前目錄下,該文件名為 test,可以做如下操作:

$ chmod +x test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}

正如看到的,在向該腳本傳遞以 - 開頭的參數(shù)時(shí),無(wú)需關(guān)心這種情況。

PHP 可執(zhí)行文件可用于運(yùn)行完全獨(dú)立于 web 服務(wù)器的 PHP 腳本。在 Unix 系統(tǒng)上,需要在 PHP 腳本的第一行指定 #!(或者說(shuō) “shebang”)以便系統(tǒng)可以自動(dòng)判斷用哪個(gè)程序運(yùn)行腳本。 在 Windows 平臺(tái)上可以使用雙擊擴(kuò)展名是.php的文件與 php.exe 相關(guān)聯(lián),也可以編寫一個(gè)批處理文件使用 PHP 運(yùn)行腳本。為 Unix 系統(tǒng)增加的指定 shebang 的第一行代碼不會(huì)影響 Windows (它也是 PHP 注釋的格式),因此也可以用該方法編寫跨平臺(tái)的程序。以下是編寫的一個(gè)簡(jiǎn)單 PHP 命令行程序的示例。

示例 #2 試圖以命令行方式運(yùn)行的 PHP 腳本(script.php)

#!/usr/bin/php
<?php

if ($argc != || in_array($argv[1], array('--help''-help''-h''-?'))) {
?>

This is a command line PHP script with one option.

  Usage:
  <?php echo $argv[0]; ?> <option>

  <option> can be some word you would like
  to print out. With the --help, -help, -h,
  or -? options, you can get this help.

<?php
} else {
    echo 
$argv[1];
}
?>

在以上腳本中,用包含 Unix shebang 的第一行代碼來(lái)指明該文件應(yīng)該由 PHP 來(lái)執(zhí)行。這里使用 CLI 版本運(yùn)行,因此不會(huì)輸出 HTTP 頭。

程序首先檢查是否有需要的參數(shù)(除了腳本名,因?yàn)樗矔?huì)被計(jì)算進(jìn)來(lái))。如果沒(méi)有參數(shù)或者參數(shù)是 --help-help、 -h、 -?,將會(huì)打印出幫助消息, 在命令行上使用 $argv[0] 動(dòng)態(tài)輸出腳本名稱。否則參數(shù)將按照接收的方式進(jìn)行準(zhǔn)確回顯。

如果在 Unix 下運(yùn)行以上腳本,它必須有可執(zhí)行權(quán)限,并簡(jiǎn)單的以 script.php echothis 或者 script.php -h 方式調(diào)用。在 Windows 下,可以為此類任務(wù)編寫與以下內(nèi)容類似的批處理文件:

示例 #3 運(yùn)行 PHP 命令行腳本的批處理文件(script.bat)

@echo OFF
"C:\php\php.exe" script.php %*

假設(shè)將上述程序名為 script.php,且 CLI 版的 php.exe 位于 C:\php\php.exe, 該批處理文件將會(huì)運(yùn)行并傳遞所有追加選項(xiàng): script.bat echothis 或者 script.bat -h。

參閱 Readline 擴(kuò)展文檔獲取更多函數(shù),以用于 PHP 中增強(qiáng)命令行應(yīng)用程序。

在 Windows 上, PHP 可以配置為無(wú)需提供 C:\php\php.exe 或者 擴(kuò)展名為 .php 的文件運(yùn)行,如 PHP 在 Microsoft Windows 下的命令行方式中所述。

注意:

在 Windows 上,推薦在真實(shí)用戶賬戶下運(yùn)行 PHP。在網(wǎng)絡(luò)服務(wù)下運(yùn)行某些操作時(shí)將會(huì)失敗, 因?yàn)椤皫裘c安全標(biāo)識(shí)間無(wú)任何映射完成”。