如何通过命令行向 PHP 脚本传递参数
最近,我收到了一些评论,都是对我之前写的一篇关于使用 Cron 调度 PHP 脚本的文章的评论,他们询问如何向脚本传递参数。在本文中,我将介绍几种不同的方法。
请注意,如果在 php.ini 中禁用了 register_argc_argv(设置为 false),这些方法将不起作用。
首先,让我们看看哪些是 100% 不可行的。如果你习惯于在网络浏览器中使用查询参数将命令行参数传递给 PHP 脚本(然后使用 $_GET),那么你可能会尝试做这样的事情…
php script.php?param1=value1
当然,PHP 会立即拒绝接受,并显示如下错误
Could not open input file: script.php?param1=value1
出现这种情况的原因是 PHP 正在查找一个名为 “script.php?param1=value1 “的文件,但实际上该脚本名为 “script.php”。文件系统不是网络服务器,因此它不知道如何处理查询参数。这就需要一种不同的方法。
让我们看看向脚本传递命令行参数的 “经典 “方法–使用 $argc 和 $argv。
这里有一个 PHP 脚本,可以显示传给它的所有命令行参数…
if (isset($argc)) { for ($i = 0; $i < $argc; $i++) { echo "Argument #" . $i . " - " . $argv[$i] . "\n"; } } else { echo "argc and argv disabled\n"; }
要将命令行参数传递给脚本,只需将它们放在脚本名称之后即可,如下所示
php script.php value1 value2
产生的输出是…
Argument #0 - script.php Argument #1 - value1 Argument #2 - value2
请注意,第 0 个参数是运行的 PHP 脚本的名称。数组的其余部分是命令行中传入的值。这些值通过 $argv 数组访问。这种方法可行,但非常简单,如果你想从向脚本传递值的查询参数方式过渡,这种方法就不太适用了。这种方法无法为传入的命令行参数命名。
如果你想为传入的值指定变量名,getopt() 就是一种方法。现在让我们看看脚本的另一个版本…
$val = getopt("p:"); if ($val !== false) { echo var_export($val, true); } else { echo "Could not get value of command line option\n"; }
让我们这样运行这个脚本
php script.php -pvalue1
产生的输出是…
array ( 'p' => 'value1' )
这里有一些主要区别。首先,使用 getopt() 时,你必须指定要检索的命令行参数。在本脚本中,它会查找”-p “参数,该参数由传递给 getopt() 的 “p: “值指定。冒号(:)表示参数必须有一个值。如果你习惯使用类似 “script.php?p=value1 “这样的命令行,这就是一个等价参数。
也可以传递多个值,例如
php script.php -pvalue1 -pvalue2
在这种情况下,值会变为数组,因此在使用前必须检查值的类型。
array ( 'p' => array ( 0 => 'value1', 1 => 'value2', ), )
如果要传递多个不同名称的参数,例如 “p “和 “q”,则要像这样更改 getopt() 调用…
$val = getopt("p:q:");
然后像这样运行脚本
php script.php -pvalue1 -qvalue2
…产生此输出…
array ( 'p' => 'value1', 'q' => 'value2', )
上述使用 getopt() 的方法限制了您使用单字符参数名,如果您想使用 “name “这样的参数名呢?这也是可能的,我们只需将 getopt() 调用改为…
$val = getopt(null, ["name:"]);
使用长参数名时,PHP 脚本的运行方式会稍有改变,在本例中,我们是这样传递参数的…
php script.php --name=Igor
然后输出…
array ( 'name' => 'Igor', )
这也可以扩展到多个不同名称的参数。多次传递相同名称的参数也会导致值是数组类型,这与前面描述的相同。还可以通过加引号的方式传递带有空格的值。
本文并未涵盖 getopt() 的所有可能性,但提供了一个起点,希望你现在可以将使用 $_GET 的常规查询参数的脚本转换为使用上述方法之一的脚本。