【发布时间】:2011-09-10 13:19:02
【问题描述】:
我想使用exec调用一个php文件。
当我调用它时,我希望能够通过(一个 id)传递一个变量。
我可以调用echo exec("php /var/www/unity/src/emailer.php"); 很好,但是当我添加类似echo exec("php /var/www/unity/src/emailer.php?id=123"); 的任何内容时,exec 调用会失败。
我该怎么做?
【问题讨论】:
我想使用exec调用一个php文件。
当我调用它时,我希望能够通过(一个 id)传递一个变量。
我可以调用echo exec("php /var/www/unity/src/emailer.php"); 很好,但是当我添加类似echo exec("php /var/www/unity/src/emailer.php?id=123"); 的任何内容时,exec 调用会失败。
我该怎么做?
【问题讨论】:
您的呼叫失败,因为您使用的是带有命令行调用的 Web 样式语法 (?parameter=value)。我明白你在想什么,但它根本行不通。
您需要改用$argv。见the PHP manual。
要查看实际情况,请将此单行代码写入文件:
<?php print_r($argv); ?>
然后使用参数从命令行调用它:
php -f /path/to/the/file.php firstparam secondparam
您会看到$argv 包含脚本本身的名称作为元素零,后跟您传入的任何其他参数。
【讨论】:
php -q "./yii.php" migrate/up --interactive=0 --migrationPath=@vendor/pheme/yii2-settings/migrations 中执行和传递参数
在你的脚本中尝试echo exec("php /var/www/unity/src/emailer.php 123");,然后读入commandline parameters。
【讨论】:
这个改编后的脚本显示了从 php exec 命令向 php 脚本传递参数的 2 种方法: 调用脚本
<?php
$fileName = '/var/www/ztest/helloworld.php 12';
$options = 'target=13';
exec ("/usr/bin/php -f {$fileName} {$options} > /var/www/ztest/log01.txt 2>&1 &");
echo "ended the calling script";
?>
调用脚本
<?php
echo "argv params: ";
print_r($argv);
if ($argv[1]) {echo "got the size right, wilbur! argv element 1: ".$argv[1];}
?>
不要忘记验证执行权限并创建具有写入权限的 log01.txt 文件(您的 apache 用户通常是 www-data)。
结果
argv 参数:数组
(
[0] => /var/www/ztest/helloworld.php
[1] => 12
[2] => target=13
)
大小合适,wilburargv 元素 1:12
选择您喜欢的任何解决方案来传递参数,您需要做的就是访问 argv 数组并按照传递的顺序检索它们(文件名是 0 元素)。
tks @hakre
【讨论】:
$argv 来自哪里?这显然是一个你没有在任何地方声明的变量???
如果你想传递一个 GET 参数给它,那么必须提供一个 php-cgi 二进制文件来调用:
exec("QUERY_STRING=id=123 php-cgi /var/www/emailer.php");
但这可能需要更多虚假的 CGI 环境变量。因此,通常建议重写被调用的脚本,让它接受普通的命令行参数并通过$_SERVER["argv"] 读取它们。
(您也可以通过在脚本顶部添加 parse_str($_SERVER["QUERY_STRING"], $_GET); 来使用普通的 php 解释器和上面的示例来伪造 php-cgi 行为。)
【讨论】:
我知道这是一个旧线程,但它帮助我解决了一个问题,所以我想提供一个扩展的解决方案。我有一个通常通过 Web 界面调用的 php 程序,它采用一长串参数。我想使用 shell_exec() 在后台使用 cron 作业运行它,并将一长串参数传递给它。每次运行时参数值都会发生变化。
这是我的解决方案:在调用程序中,我传递了一串参数,这些参数看起来就像网络调用在 ? 之后发送的字符串。例如:sky=blue&roses=red&sun=bright 等。在被调用的程序中,我检查 $argv[1] 的存在,如果找到,我将字符串解析到 $_GET 数组中。从那时起,程序将读取参数,就好像它们是从网络调用中传递的一样。
调用程序代码:
$pars = escapeshellarg($pars); // must use escapeshellarg()
$output = shell_exec($php_path . ' path/called_program.php ' . $pars); // $pars is the parameter string
在读取 $_GET 参数之前插入的调用程序代码:
if(isset($argv[1])){ // if being called from the shell build a $_GET array from the string passed as $argv[1]
$args = explode('&', $argv[1]); // explode the string into an array of Type=Value elements
foreach($args as $arg){
$TV = explode('=', $arg); // now explode each Type and Value into a 2 element array
$_GET[$TV[0]] = $TV[1]; // set the indexes in the $_GET array
}
}
//------------------------
// from this point on the program processes the $_GET array normally just as if it were passed from a web call.
效果很好,只需对被调用程序进行最少的更改。希望有人觉得它有价值。
【讨论】: