我正在使用以下代码在后台运行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_PROTOCOL
,SERVER_NAME
和REQUEST_URI
。我想这是有道理的,因为调用脚本是通过Apache提供的,而电子邮件脚本不是(?)。
使用popen
调用php脚本时,有没有办法填充$_SERVER
的缺失值?
答案 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
变量。