执行 PHP 文件

CLI SAPI 有三种不同的方法执行 PHP 代码:

  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 执行 PHP 代码时, $argv[0] 的值将是 "Standard input code"; 在 PHP 7.2.0 之前是破折号(-)。如果代码是通过来自 STDIN 的管道执行的,同样如此。

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

只要传送给脚本的参数不是以 - 字符开头,就无需过多的注意什么。向脚本传递以 - 开头的参数会导致错误,因为 PHP 会认为在执行脚本之前应该由它自身来处理这些参数。为防止发生这种情况,可以用列表分隔符 -- 参数来解决。在 PHP 解析此分隔符之后, 该符号后的所有参数将会被原样传递给脚本程序。

# 以下命令将不会运行 PHP 代码,而只显示 PHP 命令行模式的使用说明
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# 将会传递 “-h” 参数传送给脚本,且 PHP 不会显示命令行模式的使用说明
$ 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 代码、PHP 结束标签。一旦设置正确的文件执行属性(例如 chmod +x test),脚本就像其他 shell/perl 脚本一样可以执行。

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

#!/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 系统上,需要在 PHP 脚本的第一行指定 #!(或者说 “shebang”)以便系统可以自动判断用哪个程序运行脚本。 在 Windows 平台上可以使用双击扩展名是.php的文件与 php.exe 相关联,也可以编写一个批处理文件使用 PHP 运行脚本。为 Unix 系统增加的指定 shebang 的第一行代码不会影响 Windows (它也是 PHP 注释的格式),因此也可以用该方法编写跨平台的程序。以下是编写的一个简单 PHP 命令行程序的示例。

示例 #2 试图以命令行方式运行的 PHP 脚本(script.php)

#!/usr/bin/php
<?php

if ($argc != 2 || 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 的第一行代码来指明该文件应该由 PHP 来执行。这里使用 CLI 版本运行,因此不会输出 HTTP 头。

程序首先检查是否有需要的参数(除了脚本名,因为它也会被计算进来)。如果没有参数或者参数是 --help-help-h-?,将会打印出帮助消息, 在命令行上使用 $argv[0] 动态输出脚本名称。否则参数将按照接收的方式进行准确回显。

如果在 Unix 下运行以上脚本,它必须有可执行权限,并简单的以 script.php echothis 或者 script.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 echothis 或者 script.bat -h

参阅 Readline 扩展文档获取更多函数,以用于 PHP 中增强命令行应用程序。

在 Windows 上, PHP 可以配置为无需提供 C:\php\php.exe 或者 扩展名为 .php 的文件运行,如 PHP 在 Microsoft Windows 下的命令行方式中所述。

注意:

在 Windows 上,推荐在真实用户账户下运行 PHP。在网络服务下运行某些操作时将会失败, 因为“帐户名与安全标识间无任何映射完成”。

add a note add a note

User Contributed Notes 7 notes

up
56
php at richardneill dot org
11 years ago
On Linux, the shebang (#!) line is parsed by the kernel into at most two parts.
For example:

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. is the standard way to start a script. (compare "#!/bin/bash".)

2. uses "env" to find where PHP is installed: it might be elsewhere in the $PATH, such as /usr/local/bin.

3. if you don't need to use env, you can pass ONE parameter here. For example, to ignore the system's PHP.ini, and go with the defaults, use "-n". (See "man php".)

4.  or, you can set exactly one configuration variable. I recommend this one, because display_errors actually takes effect if it is set here. Otherwise, the only place you can enable it is system-wide in php.ini. If you try to use ini_set() in your script itself, it's too late: if your script has a parse error, it will silently die.

5. This will not (as of 2013) work on Linux. It acts as if the whole string, "-n -ddisplay_errors=E_ALL" were a single argument. But in BSD, the shebang line can take more than 2 arguments, and so it may work as intended.

Summary: use (2) for maximum portability, and (4) for maximum debugging.
up
6
email at alexander-bombis dot de
3 years ago
For Windows:

After the years I also have the fact that I have to use double quotation marks after php -r on Windows shell.

But in the Powershell you can use single or double quotation!
up
8
gabriel at figdice dot org
7 years ago
Regarding shebang:

In both Linux and Windows, when you execute a script in CLI with:

    php script.php

then PHP will ignore the very first line of your script if it starts with:

    #!

So, this line is not only absorbed by the kernel when the script file is executable, but it is also ignored by the PHP engine itself.

However, the engine will NOT ignore the first #! line of any included files withing your "outer" script.php.
Any "shebang" line in an included script, will result in simply outputting the line to STDOUT, just as any other text residing outside a <?php ...  ?> block.
up
6
david at frankieandshadow dot com
8 years ago
A gotcha when using #!/usr/bin/php at the start of the file as noted above:

if you originally edited the file on Windows and then attempt to use it on Unix, it won't work because the #! line requires a Unix line ending. Bash gives you the following error message if it has DOS line endings:
"bash: /usr/local/bin/wpreplace.php: /usr/bin/php^M: bad interpreter: No such file or directory"

(In Emacs I used "CTRL-X ENTER f" then type "unix" and ENTER to convert)
up
4
spencer at aninternetpresence dot net
13 years ago
If you are running the CLI on Windows and use the "-r" option, be sure to enclose your PHP code in double (not single) quotes. Otherwise, your code will not run.
up
-3
petruzanautico at yah00 dot com dot ar
13 years ago
As you can't use -r and -f together, you can circumvent this by doing the following:
php -r '$foo = 678; include("your_script.php");'
up
-8
synnus at gmail dot com
6 years ago
in php.ini use auto_prepend_file="init.php"
first start script
To Top