打开脚本中的fsockopen()和header(location:xxx)?

时间:2012-05-23 08:44:10

标签: php header fsockopen

奇怪的问题,我正在打开与fsockopen()到页面的连接, 该页面在同一页面上有一个header(location:xx)(我只是刷新脚本),但似乎重定向不起作用......

如果我用浏览器复制它,显然一切正常......

一些代码:

连接页面:

$socketcon = fsockopen($_SERVER['HTTP_HOST'],80,$errorno,$errorstr,10);
if($socketcon) {
    $socketdata = "GET http://www.example.com/test2.php HTTP/1.0\r\nHost: ".$_SERVER['HTTP_HOST']."\r\nConnection: Close\r\n\r\n";
    fwrite($socketcon,$socketdata); 
    fclose($socketcon);
}

CONNECTED PAGE(test2.php):

<?
//other code (working fine)

if($_GET["AAA"]){

     //REDIRECT WORKED !

} else {
     header("location:test2.php?AAA=1");   //same page but with a get param
}
?>

REDIRECT WORKED部分永远不会被执行......

有什么建议吗?

编辑:连接必须是异步的

3 个答案:

答案 0 :(得分:2)

  

有什么建议吗?

是的,停止使用套接字执行cURL可以做得更好的事情;)header('Location: X')实际上会向您发送301/303 HTTP响应,您(或浏览器)应通过制作一个新的要求。但是,您似乎无法处理重定向。另一方面,cURL模仿类似浏览器的功能,它可以使用curl_setopt( $curlResource, CURLOPT_FOLLOWLOCATION, true );

跟踪重定向

答案 1 :(得分:1)

考虑Is making asynchronous HTTP requests possible with PHP?这是一个类似的问题。

使用exec() - 家庭功能可能是一个不错的选择,如果你不需要返回值;你可以调用&附加的卷曲,它将在后台运行。

如果你真的想在PHP中真正做到这一点,你可以:产生一个新进程(使用pcntl_fork())或自己处理重定向。

要处理重定向,您需要:

  1. 通过查看从流中读取的前三个字符来确定您的响应代码。 200意味着成功,300s中的任何东西意味着部分成功。
  2. 在前三个字符中找到302(或307)后,搜索位置标题。我相信这会匹配正则表达式/\s*location:\s*(.+)$/m
  3. 验证您在位置字段中显示的网址是否符合您的期望并且值得信赖。它应该是一个绝对URL,但您需要检查它是否有安全的服务器,安全端口,安全URL和安全参数。 parse_url()可能会派上用场,但不会检查潜在的安全问题
  4. 打开与上面匹配的新网址的新连接(或者,如果它是相同的主机,并且您使用的是带有Keep-Alive的HTTP 1.1,则重复使用您的连接)以发送相应的数据。
  5. 根据需要处理任何结果/清理工作。
  6. 你可以看到这非常复杂。这也将是递归的。你真正在谈论的是在PHP中编写一个基本的HTTP解析器。这不是一个好主意 - 使用cURL并找到一些其他方法使其异步。

答案 2 :(得分:0)

您的连接功能无法处理重定向。

如果您想支持它,您必须自己编写代码,或使用curl之类的库来建立连接。