没有系统调用的PHP异步


PHP async without system calls

由于去年我们的服务器受到攻击,我阻止了所有通过php:的系统调用

## php.ini
disable_functions = exec, passthru, shell_exec, system, proc_open, popen, curl_exec, curl_multi_exec, parse_ini_file, show_source, eval

但这已经停止了我的异步功能的工作,该功能用于在后台发送电子邮件。

有没有一种纯粹的php"安全"方法可以在不再次打开exec()函数的情况下进行异步调用?

function doEmail($subject,$body,$to){                    
    $pwd = realpath(dirname(__FILE__));
    $body = urlencode($body);
    $subject = urlencode($subject);
    $mailpage = $pwd."/email.php";
    $command = "$mailpage $subject $body $to";
    bgExecute($command);    
}
## Asyncronous PHP - Multi-Tasking (Email etc)
function bgExecute($command) {
    if (substr(php_uname(), 0, 7) == "Windows") pclose(popen("start /B ". $command, "r"));  // Windows
    $exec = "/usr/bin/php -f $command > /dev/null &"; // Ubuntu
    exec($exec);    
} 

好吧,如果你想继续发送任意命令而不允许发送任意命令,那么不。

如果您要问的是是否有办法根据PHP的需求执行外部应用程序,那么是的。

一种方法是将命令写入一个文件,并让另一个进程实际监视该文件的更改。

$filename = '/tmp/myfile.txt';
$prevMtime = 0;
while (true) {
  clearstatcache();
  //Do it in two steps just in case you have PHP < 5.4
  $mtime = stat($filename);
  $mtime = $mtime['mtime'];
  if ($mtime > $prevMtime) {
    $prevMtime = $mtime;
    print("file ${filename} changed'n");
  }
  usleep(10);
}

另一种方法是使用套接字来实现同样的目的。

问题是,这两种解决方案都不是灵丹妙药:如果你只允许执行任意命令,那么你几乎没有安全性。

你需要定义你想要多大的安全性。然后你需要决定你想要多大的灵活性。

可以做到这一点的一种方法是拥有一个进程(基于套接字或文件),您可以将其配置为只执行特定的可执行文件列表,并让您的PHP向其发送命令