使用popen在后台运行php脚本时填充$ _SERVER

时间:2015-11-30 15:29:05

标签: php background-process

我正在使用以下代码在后台运行php脚本email/send-emails.php

if(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
   $phpExec = str_replace('/', '\\', dirname(ini_get('extension_dir'))).'\php.exe';
   if(!file_exists($phpExec))
      throw new Exception('Could not find executable: '.$phpExec);
} else {
   $phpExec = exec("which php-cli");
   if($phpExec{0} !== '/')
      $phpExec = exec("which php");
   if($phpExec{0} !== '/')
      throw new Exception('Could not find executable: '.$phpExec);
}

$exec = $phpExec.' email/send-emails.php';
$cmd = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? 'start /B '.$exec : $exec.' &';
pclose(popen($cmd, 'r'));

这适用于Windows和Linux。唯一的问题是$_SERVER在调用脚本和电子邮件脚本中填充了完全不同的值。例如,电子邮件脚本中缺少密钥SERVER_PROTOCOLSERVER_NAMEREQUEST_URI。我想这是有道理的,因为调用脚本是通过Apache提供的,而电子邮件脚本不是(?)。

使用popen调用php脚本时,有没有办法填充$_SERVER的缺失值?

2 个答案:

答案 0 :(得分:2)

最简单的方法是为文件发出HTTP请求,而不是使用popen来运行它。

否则,在send-emails.php脚本中,您可以检测$_SERVER值是否丢失,并使用一些合理的默认值填充它们。

答案 1 :(得分:0)

考虑在email/send-emails.php中回退到环境变量:

$uri = $_SERVER['REQUEST_URI']?:getenv('REQUEST_URI');

因此,在您的主脚本中,您可以将这些值代理给worker:

$exec = "REQUEST_URI={$_SERVER['REQUEST_URI']} ".$phpExec.' email/send-emails.php';

Windows的语法略有不同。

请注意,解决方案过于简单,以显示核心原则。在实际应用程序中,强烈建议在传递给子进程之前清理$_SERVER变量。