在php开发中,除了处理web请求,我们还经常需要编写命令行脚本执行定时任务、数据迁移等操作,这时候就需要读取命令行传入的参数。php提供了内置的argv和argc变量来获取命令行参数,其中argc表示参数数量,argv是参数组成的数组。不过很多开发者不清楚这两个变量的具体用法,也不知道如何处理带短横线或者双短横线的可选参数。

argv与argc的基础概念
php在命令行模式下运行脚本时,会自动生成两个全局变量,分别是$argc和$argv,这两个变量不需要额外引入即可直接使用。
$argc:是一个整型变量,表示命令行传入的参数总数量,包含脚本文件名本身,所以最少值为1。$argv:是一个数组变量,按顺序存储所有命令行参数,第一个元素$argv[0]是执行的脚本文件名,后续元素依次是传入的参数。
基础参数读取示例
我们先编写一个简单的测试脚本,打印出$argc和$argv的内容,脚本文件命名为test.php,代码如下:
<?php // 打印参数数量 echo "参数总数量:" . $argc . PHP_EOL; // 打印所有参数数组 echo "参数数组内容:" . PHP_EOL; print_r($argv);
在命令行中执行以下命令:
php test.php hello world 123
执行后输出结果如下:
参数总数量:4
参数数组内容:
Array
(
[0] => test.php
[1] => hello
[2] => world
[3] => 123
)
可以看到$argc的值为4,包含了脚本名和三个传入参数,$argv数组按顺序存储了所有内容。
处理可选参数的逻辑实现
实际开发中,命令行参数经常会包含可选参数,比如常见的-h表示帮助、--name=张三表示指定名称这类格式。我们需要编写逻辑解析这些可选参数,下面给出一个通用的解析函数示例。
可选参数解析函数
该函数支持两种可选参数格式:短格式-k value和长格式--key=value或者--key value,同时保留普通的位置参数。
<?php
function parse_cli_args($argv) {
$options = []; // 存储可选参数
$params = []; // 存储普通位置参数
$count = count($argv);
for ($i = 1; $i < $count; $i++) {
$arg = $argv[$i];
// 处理长格式参数 --key=value
if (strpos($arg, '--') === 0 && strpos($arg, '=') !== false) {
$parts = explode('=', substr($arg, 2), 2);
$options[$parts[0]] = $parts[1];
}
// 处理长格式参数 --key value
elseif (strpos($arg, '--') === 0) {
$key = substr($arg, 2);
// 如果下一个参数存在且不是可选参数,则作为当前参数的值
if (isset($argv[$i + 1]) && strpos($argv[$i + 1], '-') !== 0) {
$options[$key] = $argv[$i + 1];
$i++;
} else {
$options[$key] = true;
}
}
// 处理短格式参数 -k value
elseif (strpos($arg, '-') === 0) {
$key = substr($arg, 1);
if (isset($argv[$i + 1]) && strpos($argv[$i + 1], '-') !== 0) {
$options[$key] = $argv[$i + 1];
$i++;
} else {
$options[$key] = true;
}
}
// 普通位置参数
else {
$params[] = $arg;
}
}
return [
'options' => $options,
'params' => $params
];
}
// 测试解析函数
$result = parse_cli_args($argv);
echo "可选参数:" . PHP_EOL;
print_r($result['options']);
echo "普通位置参数:" . PHP_EOL;
print_r($result['params']);
解析函数测试
将上述代码保存为parse.php,执行以下命令测试:
php parse.php --name=李四 -a 18 --verbose hello world
执行后输出结果如下:
可选参数:
Array
(
[name] => 李四
[a] => 18
[verbose] => 1
)
普通位置参数:
Array
(
[0] => hello
[1] => world
)
可以看到函数正确解析了长格式、短格式的可选参数,同时把剩余的普通参数存储到了位置参数数组中。
注意事项
- 如果php配置中
register_argc_argv设置为Off,那么$argc和$argv将无法使用,需要在php.ini中将该配置改为On,或者在命令行运行时添加-d register_argc_argv=On参数。 - 处理可选参数时,需要注意参数顺序的问题,如果可选参数后面紧跟另一个可选参数,那么该可选参数会被识别为布尔类型,没有对应的值。
- 如果参数中包含特殊字符,比如空格,需要在命令行传入时用引号包裹,比如
php test.php "hello world",这样才会被识别为一个参数。