我有一个PHP文件需要从命令行运行(通过crontab)。我需要传递type=daily
到该文件,但我不知道如何做。我尝试了:
php myfile.php?type=daily
但是返回了以下错误:
无法打开输入文件:myfile.php?type=daily
我该怎么办?
我有一个PHP文件需要从命令行运行(通过crontab)。我需要传递type=daily
到该文件,但我不知道如何做。我尝试了:
php myfile.php?type=daily
但是返回了以下错误:
无法打开输入文件:myfile.php?type=daily
我该怎么办?
?type=daily
参数(最终在$_GET
数组中)仅适用于通过网络访问的页面。
您需要像这样调用它:php myfile.php daily
并从$argv
数组检索该参数(在这种情况下,$argv[1]
将是该参数,因为$argv[0]
是myfile.php
)。
如果该页面也用作网页,则有两个选项可供考虑。要么使用shell脚本和Wget访问它,并从cron中调用它:
#!/bin/sh
wget http://location.to/myfile.php?type=daily
或者在 PHP 文件中检查它是否是从命令行调用的:
if (defined('STDIN')) {
$type = $argv[1];
} else {
$type = $_GET['type'];
}
(注意:你可能需要/想要检查$argv
是否实际包含足够的变量等)
将它作为普通参数传递,然后在PHP中使用$argv
数组访问它。
php myfile.php daily
并且在myfile.php中
$type = $argv[1];
这些代码将把CLI调用的参数(例如php myfile.php "type=daily&foo=bar"
)转换为众所周知的$_GET
数组:
$query = parse_url($argv[1], PHP_URL_QUERY);
parse_str($query, $_GET);
if (!empty($argv[1])) {
parse_str($argv[1], $_GET);
}
虽然覆盖全局变量$_GET
数组可能会比较混乱,但它可以快速转换所有脚本以接受CLI参数。
有关详细信息,请参见parse_str。
如果您想要更传统的CLI样式,例如php myfile.php type=daily foo=bar
,则可以使用一个小型函数将其转换为与$_GET
兼容的关联数组:
// Convert $argv into associative array
function parse_argv(array $argv): array
{
$request = [];
foreach ($argv as $i => $a) {
if (!$i) {
continue;
}
if (preg_match('/^-*(.+?)=(.+)$/', $a, $matches)) {
$request[$matches[1]] = $matches[2];
} else {
$request[$a] = true;
}
}
return $request;
}
if (!empty($argv[1])) {
$_GET = parse_argv($argv);
}
通过使用getopt()函数,我们可以从命令行读取参数。只需在php
运行命令时传递一个值:
php abc.php --name=xyz
$val = getopt(null, ["name:"]);
print_r($val); // Output: ['name' => 'xyz'];
像其他应用程序一样,可以按索引发送参数:
php myfile.php type=daily
<?php
if (count($argv) == 0)
exit;
foreach ($argv as $arg)
echo $arg;
?>
将此代码保存在文件myfile.php
中,并运行php myfile.php type=daily
<?php
$a = $argv;
$b = array();
if (count($a) === 1) exit;
foreach ($a as $key => $arg) {
if ($key > 0) {
list($x,$y) = explode('=', $arg);
$b["$x"] = $y;
}
}
?>
?>
标记之前添加var_dump($b);
,您将看到数组$b
包含type => daily
。您可以使用以下代码来同时处理命令行和Web浏览器。将此代码放置在PHP代码之上。它为每个命令行参数创建一个$ _GET变量。
在您的代码中,您只需要检查 $ _GET
变量,而不必担心脚本是从Web浏览器还是命令行调用的。
if(isset($argv))
foreach ($argv as $arg) {
$e=explode("=",$arg);
if(count($e)==2)
$_GET[$e[0]]=$e[1];
else
$_GET[$e[0]]=0;
}
编辑。使用此代码,我发现一个小错误。如果您的参数值包含“=”,则会失败。我现在使用以下代码:
if(isset($argv))
foreach ($argv as $arg) {
$e=explode("=",$arg);
if(count($e)>=2)
$_GET[$e[0]]=substr($arg,strlen($e[0])+1,strlen($arg));
else
$_GET[$e[0]]=0;
}
php test.php one two three
在文件test.php内部:
<?php
if(isset($argv))
{
foreach ($argv as $arg)
{
echo $arg;
echo "\r\n";
}
}
?>
<?php
parse_str(implode('&', array_slice($argv, 1)), $_GET);
?>
$ php -f myfile.php type=daily a=1 b[]=2 b[]=3
将 $_GET['type']
设置为 'daily'
,将 $_GET['a']
设置为 '1'
,将 $_GET['b']
设置为 array('2', '3')
。