0

奇怪的问题,我正在打开一个与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);
}

连接页面(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 部分永远不会被执行......

有什么建议么 ?

编辑:连接必须是异步的

4

3 回答 3

2

有什么建议么 ?

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

于 2012-05-23T08:52:40.110 回答
1

考虑使用 PHP 可以实现异步 HTTP 请求吗?这是一个类似的问题。

exec()如果您不需要返回值,使用-family 函数可能是一个不错的选择;你可以只调用 curl 附加的&,它会在后台运行。

如果您真的非常想在 PHP 中执行此操作,您可以:生成一个新进程(使用pcntl_fork())或自己处理重定向。

要处理重定向,您需要:

  1. 通过查看从流中读取的前三个字符来确定您的响应代码是什么。200 意味着成功,300 中的任何东西都意味着部分成功。
  2. 在前三个字符中找到 302(或 307)后,搜索位置标题。我相信这将匹配 regex /\s*location:\s*(.+)$/m
  3. 验证您从位置字段获得的 URL 是否符合您的期望并且值得信赖。它应该是一个绝对 URL,但您需要检查它是否有安全服务器、安全端口、安全 URL 和安全参数。parse_url()可能会派上用场,但不会检查潜在的安全问题
  4. 打开与上面匹配的新 URL 的新连接(或者,如果它是同一个主机并且您使用 HTTP 1.1 和 Keep-Alive,请重用您的连接)以发送适当的数据。
  5. 根据需要处理任何结果/清理。

你可以看到这是非常复杂的。这也将是递归的。您真正谈论的是用 PHP 编写一个基本的 HTTP 解析器。这不是一个好主意 - 使用 cURL 并找到其他方法使其异步。

于 2012-08-08T14:45:56.330 回答
0

您的连接函数不处理重定向。

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

于 2012-05-23T08:47:04.353 回答