2024年PHP日本大会

执行PHP文件

有三种不同的方法可以为PHP代码提供CLI SAPI来执行。

  1. 告诉PHP执行某个文件。

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

    这两种方法(无论是否使用-f开关)都会执行文件my_script.php。请注意,对可以执行的文件没有限制;特别是,文件名不需要具有.php扩展名。

  2. 直接在命令行上传递要执行的PHP代码。

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

    需要注意的是shell变量替换和引号的使用。

    注意:

    仔细阅读示例:没有开始或结束标签!-r开关根本不需要它们,使用它们会导致解析错误。

  3. 通过标准输入(stdin)提供要执行的PHP代码。

    这提供了强大的功能,可以动态创建PHP代码并将其馈送到二进制文件,如这个(虚构的)示例所示

    $ some_application | some_filter | php | sort -u > final_output.txt
    
您不能组合这三种执行代码的方法。

与每个shell应用程序一样,PHP二进制文件接受许多参数;但是,PHP脚本也可以接收更多参数。可以传递给脚本的参数数量不受PHP限制(尽管shell对可以传递的字符数有限制,但这通常不太可能达到)。传递给脚本的参数在全局数组$argv中可用。第一个索引(零)始终包含从命令行调用的脚本的名称。请注意,如果使用命令行开关-r内联执行代码,则$argv[0]的值将为"Standard input code";在PHP 7.2.0之前,它是一个短划线("-")。如果代码通过来自STDIN的管道执行,则也是如此。

第二个全局变量$argc包含$argv数组中的元素数量(**不是**传递给脚本的参数数量)。

只要传递给脚本的参数不以-字符开头,就没有什么特别的需要注意的。传递以-字符开头的参数将导致问题,因为PHP解释器认为它必须自己处理它,甚至在执行脚本之前。要防止这种情况,请使用参数列表分隔符--。在PHP解析此分隔符后,每个后续参数都将完整地传递给脚本。

# This will not execute the given code but will show the PHP usage
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# This will pass the '-h' argument to the script and prevent PHP from showing its usage
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

但是,在Unix系统上,还有另一种使用PHP进行shell脚本编写的方法:使脚本的第一行以#!/usr/bin/php开头(如果路径到您的PHP CLI二进制文件不同,则为该路径)。文件的其余部分应包含通常的PHP开始和结束标签内的普通PHP代码。一旦文件的执行属性被适当地设置(例如chmod +x test),该脚本就可以像任何其他shell或perl脚本一样执行

示例1 作为shell脚本执行PHP脚本

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

假设此文件在当前目录中名为test,则现在可以执行以下操作

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

可以看出,在这种情况下,传递以-开头的参数时,无需特别注意。

PHP可执行文件可用于运行与Web服务器完全无关的PHP脚本。在Unix系统上,应将特殊的#!(或“shebang”)第一行添加到PHP脚本中,以便系统可以自动确定哪个程序应运行该脚本。在Windows平台上,可以将php.exe.php扩展名的双击选项关联,或者可以创建批处理文件以通过PHP运行脚本。Unix的特殊shebang第一行在Windows上不会造成任何损害(因为它被格式化为PHP注释),因此可以通过包含它来编写跨平台程序。下面显示了一个编写命令行PHP程序的简单示例。

示例2 旨在从命令行运行的脚本 (script.php)

#!/usr/bin/php
<?php

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

这是一个带有一个选项的命令行PHP脚本。

用法
<?php echo $argv[0]; ?> <option>

<option> 可以是你想要
打印出来的词。使用 --help、-help、-h、
或 -? 选项,可以获得此帮助。

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

上面的脚本包含Unix shebang第一行,以指示此文件应由PHP运行。我们在这里使用的是CLI版本,因此不会输出HTTP标头。

该程序首先检查是否有必需的一个参数(除了脚本名称,该名称也被计数)。如果没有,或者如果参数是--help-help-h-?,则会打印帮助消息,使用$argv[0]动态打印在命令行上键入的脚本名称。否则,将按原样回显该参数。

要在Unix上运行上述脚本,必须使其可执行,并只需调用script.php echothisscript.php -h即可。在Windows上,可以为此任务创建一个类似于以下内容的批处理文件

示例3 用于运行命令行PHP脚本的批处理文件 (script.bat)

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

假设上述程序名为script.php,并且CLI php.exe位于C:\php\php.exe,则此批处理文件将运行它,并传递所有附加的选项:script.bat echothisscript.bat -h

另请参见Readline扩展文档,了解可用于增强PHP中命令行应用程序的更多功能。

在Windows上,可以将PHP配置为无需提供C:\php\php.exe.php扩展名即可运行,如Microsoft Windows上的命令行PHP中所述。

注意:

在 Windows 系统上,建议在实际用户帐户下运行 PHP。在网络服务下运行时,某些操作会失败,因为“帐户名和安全 ID 之间没有映射”。

添加注释

用户贡献注释 5 条注释

59
php at richardneill dot org
11 年前
在 Linux 系统上,Shebang 行(#!)由内核解析成最多两部分。
例如

1: #!/usr/bin/php
2: #!/usr/bin/env php
3: #!/usr/bin/php -n
4: #!/usr/bin/php -ddisplay_errors=E_ALL
5: #!/usr/bin/php -n -ddisplay_errors=E_ALL

1. 是启动脚本的标准方法。(比较“#!/bin/bash”)。

2. 使用“env”查找 PHP 的安装位置:它可能位于 $PATH 的其他位置,例如 /usr/local/bin。

3. 如果你不需要使用 env,你可以在这里传递一个参数。例如,要忽略系统的 PHP.ini 并使用默认值,请使用“-n”。(参见“man php”)。

4. 或者,你可以设置 exactly one 个配置变量。我推荐这个,因为如果在这里设置,display_errors 实际上会生效。否则,你唯一可以启用它的位置是在 php.ini 中系统范围地启用它。如果你试图在你的脚本本身中使用 ini_set(),那就太晚了:如果你的脚本有解析错误,它会静默地退出。

5. (截至 2013 年) 这在 Linux 上不起作用。它表现得好像整个字符串“-n -ddisplay_errors=E_ALL”是一个参数。但在 BSD 中,Shebang 行可以接受多个参数,因此它可能按预期工作。

总结:为了最大限度的可移植性,使用 (2);为了最大限度的调试,使用 (4)。
6
email at alexander-bombis dot de
3 年前
对于 Windows

多年来,我还发现必须在 Windows shell 中的 php -r 后使用双引号。

但在 Powershell 中,你可以使用单引号或双引号!
4
gabriel at figdice dot org
8 年前
关于 Shebang

在 Linux 和 Windows 系统上,当你在 CLI 中使用以下命令执行脚本时:

php script.php

那么 PHP 将忽略脚本的第一行,如果它以

#!

开头。因此,当脚本文件可执行时,这行不仅被内核吸收,而且也被 PHP 引擎本身忽略。

但是,引擎不会忽略你“外部”script.php 中任何包含文件的第一个 #! 行。
包含脚本中的任何“Shebang”行都将导致简单地将该行输出到 STDOUT,就像位于 <?php ... ?> 块之外的任何其他文本一样。
3
david at frankieandshadow dot com
8 年前
如上所述,在文件开头使用 #!/usr/bin/php 时的一个陷阱

如果你最初在 Windows 上编辑了文件,然后尝试在 Unix 上使用它,它将无法工作,因为 #! 行需要 Unix 行结尾。如果它具有 DOS 行结尾,Bash 会给你以下错误消息:
"bash: /usr/local/bin/wpreplace.php: /usr/bin/php^M: bad interpreter: No such file or directory"

(在 Emacs 中,我使用“CTRL-X ENTER f”,然后键入“unix”并按 ENTER 进行转换)
2
spencer at aninternetpresence dot net
13 年前
如果你在 Windows 上运行 CLI 并使用“-r”选项,请确保将你的 PHP 代码放在双引号(而不是单引号)中。否则,你的代码将无法运行。
To Top