IIS Express 因 Curl 请求而挂起

IIS Express Hangs with Curl Request

我正在用 php 5.4 使用 Visual Studio 2013、Xdebug 和 IIS Express 开发一个网站。每当我尝试向 localhost:port 发出 curl 请求时,页面都会挂起,直到 curl 请求因超时而失败。但是,在 curl 超时发生后,执行请求页面上的其余代码,然后执行请求页面上的代码,这对我没有帮助,因为我需要页面中的数据。

这是发出 curl 请求的脚本:

    $logfh = fopen("C:\Windows\Temp\curl_log.log", 'a+');
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,'http://localhost:46746/test.php');
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_COOKIE, "XDEBUG_SESSION=" . $_COOKIE['XDEBUG_SESSION'] . ';');
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
    curl_setopt($ch, CURLOPT_TIMEOUT,5);
    curl_setopt($ch,CURLOPT_VERBOSE , true);
    curl_setopt($ch,CURLOPT_STDERR ,$logfh );
    $result = curl_exec($ch);
    curl_close($ch);
    fclose($logfh);

这是请求页面上的脚本:

  <?php
    echo 'reached test';
    ?>

这是 curl 请求的日志:

Adding handle: conn: 0x370ea80
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 3 (0x370ea80) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 46746 (#3)
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 46746 (#3)

> GET /test.php HTTP/1.1 Host: localhost:46746 Accept: */* Cookie: XDEBUG_SESSION=A53CF524;

Operation timed out after 5991 milliseconds with 0 out of -1 bytes received
* Closing connection 3

我的 curl 语法应该是正确的,因为我可以成功地从另一个 url 获取数据。 PHP 没有显示任何错误。我应该怎么做?

这两个选项是true/false:

curl_setopt($ch,CURLOPT_VERBOSE , $logfh );
curl_setopt($ch, CURLOPT_FILE, $logfh);

更新

您可以做一些事情来帮助找到问题

CURLOPT_CONNECTTIMEOUTCURLOPT_FAILONERROR
在调试时很重要。
没有超时,它不会超时,您将看不到任何结果。

我想看看服务器是否有响应,HTTP响应Header可能有相关信息,所以使用CURLOPT_HEADER

使用curl_getinfo($ch);得到结果。

检查 curl 响应是否有错误:curl_errno($ch))

CURLINFO_HEADER_OUT 将 return 您的请求 Header 这可能会揭示您的请求存在问题,例如 cookie。

如果您有递归重定向,请将 CURLOPT_FOLLOWLOCATION 设置为 false。

如果不需要 cookie,请不要使用它们,在调试时将其删除。

这个 header 所以没有回显输出被解释为 HTML。

header('Content-Type: text/plain; charset=utf-8');

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_FILETIME, true);
curl_setopt($ch, CURLINFO_HEADER_OUT,true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, "TestCookies.txt");
curl_setopt($ch, CURLOPT_TIMEOUT,5);
curl_setopt($ch, CURLOPT_COOKIEJAR, "TestCookies.txt");
curl_setopt($ch, CURLOPT_FAILONERROR,true);
$data = curl_exec($ch);
$info = curl_getinfo($ch);
$info = var_export($info,true);
  if (curl_errno($ch)){
      $data .= 'Retreive Base Page Error: ' . curl_error($ch);
  }
  else {
    $skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE)); 
    $responseHeader = substr($data,0,$skip);
    $data= substr($data,$skip);
    $info = curl_getinfo($ch);
    $info = var_export($info,true);
   }
  echo $responseHeader;
  echo "\n$info";
  echo "\n$data";

您可能需要更改默认值 header。

$request = array();
$request[] = "Host: www.example.com";
$request[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$request[] = "User-Agent: MOT-V9mm/00.62 UP.Browser/6.2.3.4.c.1.123 (GUI) MMP/2.0";
$request[] = "Accept-Language: en-US,en;q=0.5";
$request[] = "Connection: keep-alive";
$request[] = "Cache-Control: no-cache";
$request[] = "Pragma: no-cache";

curl_setopt($ch, CURLOPT_HTTPHEADER,$request);

如果您需要 POST 请求:

$post = 'key1=value1&key2=value2&key3=value3';
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

curl cookie jar 有时会出现问题。所以我写了may own cookie routine.

从响应中获取 cookie Header:

  $e = 0;
  while(true){
    $s = strpos($head,'Set-Cookie: ',$e);
    if (!$s){break;}
    $s += 12;
    $e = strpos($head,';',$s);
    $cookie = substr($head,$s,$e-$s) ;
    $s = strpos($cookie,'=');
    $key = substr($cookie,0,$s);
    $value = substr($cookie,$s);
    $cookies[$key] = $value;
  }

为任何后续请求创建 cookie:

 $cookie = '';
 $show = '';
 $head = '';
 $delim = '';
 foreach ($cookies as $k => $v){
   $cookie .= "$delim$k$v";
   $delim = '; ';
 }

将 cookie 添加到请求中 header:

$request = array();  // clear requests from previous request.
$request[] = $cookies;
curl_setopt($ch, CURLOPT_HTTPHEADER,$request);

好吧,答案原来是 simple.I 进入项目属性并选择服务器设置 'Use Local IIS Express'。我让 Visual Studio 为我创建了虚拟目录,现在它工作得很好。