php脚本的异步执行正在使用经过身份验证的会话

时间:2012-03-16 10:47:54

标签: php linux asynchronous apache

我正在尝试异步运行脚本。在Stackoverflow上找到如何做到这一点没有问题。问题是我正在尝试我发现的一个例子,但它没有用。尽管如此,脚本在error_log中运行时没有输出错误。

我的主要php脚本:

function backgroundPost($url){

    $parts=parse_url($url);

      $fp = fsockopen($parts['host'],
              isset($parts['port'])?$parts['port']:80,
              $errno, $errstr, 30);


      if (!$fp) {
          return false;
      } else {
          $out = "POST ".$parts['path']." HTTP/1.1\r\n";
          $out.= "Host: ".$parts['host']."\r\n";
          $out.= "Content-Type: text/plain\r\n";
          $out.= "Content-Length: ".strlen($parts['query'])."\r\n";
          $out.= "Content-Length: ".strlen($parts['query'])."\r\n";
          $out.= "Connection: Close\r\n\r\n";
          if (isset($parts['query'])) $out.= $parts['query'];

          fwrite($fp, $out);

          fclose($fp);

          return true;
      }
    }

    //Example of use
    backgroundPost('http://192.168.1.107/smic/testarea/runner.php?id=1');

来自fwrite()的响应是“155”。

backgroundPost返回'true'。

runner.php:

ignore_user_abort(true);
set_time_limit(50);
error_log("RUNNING!"); 

为什么“RUNNING!”是写入错误日志的注释?就像scipt实际上没有被执行。

直接访问runner.php(使用在backgroundPost中发布的URL),脚本按预期工作。

两个脚本都有apache特权777:apache。

上运行
  • Linux / CentOS 6.2
  • PHP 5.3.3
  • Apache 2.2.15

是否与我使用经过身份验证的会话有关,而且经过身份验证的用户当然不是运行脚本的apache?

使用CURL进行测试

@jprofitt建议我也尝试过curl:

async_curl.php:

$ch = curl_init("http://192.168.1.107/");
$fp = fopen("http://192.168.1.107/smic/testarea/runner.php", "r");

curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
curl_setopt($ch, CURLOPT_USERPWD, "kaand:xIWGWt0DNVriw"); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);

curl_exec($ch);
$info = curl_getinfo($ch);
echo print_r($info);
curl_close($ch);
fclose($fp);

从curl_getinfo($ ch)打印Tis:

Array
(
    [url] => http://192.168.1.107/
    [content_type] => text/html; charset=UTF-8
    [http_code] => 302
    [header_size] => 411
    [request_size] => 103
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.002165
    [namelookup_time] => 0.000106
    [connect_time] => 0.000192
    [pretransfer_time] => 0.000211
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0.002109
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [redirect_url] => http://192.168.1.107/login.php
)
1

我尝试过使用$ ch = curl_init(“http://192.168.1.107/”);同样,我在网上收到了“需要授权”的消息。在error_log中,我获得了running.php所需的HTTP / 1.1 401授权。

在执行'curl_setopt($ ch,CURLOPT_FILE,$ fp)时,我也会在error_log中抱怨$ fp“不是有效的文件句柄资源”。'。

有一个重定向到数组末尾的登录页面,这可能与该问题有关吗?

1 个答案:

答案 0 :(得分:0)

所以,我遇到的问题与runner.php的限制区有关。无论我使用curl还是fsockopen,我都需要验证请求。在这里,我为fsockopen和curl提供了针对受限区域的异步请求的解决方案。

<强>的fsockopen:

function backgroundPost($url){        

    $parts=parse_url($url);
    echo $parts['path']."<br/>"; 
    echo $parts['host']."<br/>"; 
    echo $url;

  $fp = fsockopen($parts['host'],  
          isset($parts['port'])?$parts['port']:80,
          $errno, $errstr, 10);

 $auth = base64_encode("kaand:kaand123");
  if (!$fp) {
      return false;
  } else {
      $out = "POST ".$parts['path']." HTTP/1.1\r\n";
      $out.= "Host: ".$parts['host']."\r\n";
      $out.= "User-Agent: Anonymous\r\n";
      $out.= "Content-Type: text/plain\r\n";
      $out.= "Authorization: Basic ".$auth;
      $out.= "Content-Length: ".strlen($parts['query'])."\r\n";
      $out.= "Connection: Close\r\n\r\n";
      if (isset($parts['query'])) $out.= $parts['query'];

      fwrite($fp, $out);

      fclose($fp);

      return true;
  }
}

使用示例:

backgroundPost('http://192.168.1.107/smic/testarea/runner.php?id=1');

<强>卷曲:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://192.168.1.107/smic/testarea/runner.php");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
curl_setopt($ch, CURLOPT_USERPWD, "kaand:kaand123"); //Don't use the sha1-value
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);

curl_exec($ch);
curl_close($ch);

<强> runner.php

do whatever...

我想我会选择fsockopen,认为这是一个更好的解决方案,而不是超时会迫使你至少有一些等待时间。如果有很多流量,即使1秒钟就可以建立......