<转>php的stream_context_create让file_get_contents和fopen发送header参数

<?php
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);

$context = stream_context_create($opts);

/* Sends an http request to www.example.com
with additional headers shown above */
$fp = fopen('http://www.example.com', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>


http://www.jb51.net/article/26671.htm

作用:创建并返回一个文本数据流并应用各种选项,可用于fopen(),file_get_contents()等过程的超时设置、代理服务器、请求方式、头信息设置的特殊过程。
函数原型:resource stream_context_create ([ array $options [, array $params ]] )
用法
例子一:

复制代码 代码如下:

<?php
$opts = array( 'http-->array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
/* Sends an http request to www.jb51.net
with additional headers shown above */
$fp = fopen('http://www.jb51.net', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>


例子二:

复制代码 代码如下:

<?php
$opts = array( 'http-->array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
?>
You would setup the header this way:
<?php
$opts = array( 'http-->array(
'method'=>"GET",
'header'=>array("Accept-language: en",
"Cookie: foo=bar",
"Custom-Header: value")
)
);
$context = stream_context_create($opts);
?>


例子三:

复制代码 代码如下:

<?php
$opts = array('http' => array('proxy' => 'tcp://127.0.0.1:8080', 'request_fulluri' => true));
$context = stream_context_create($opts);
$data = file_get_contents('http://www.jb51.net', false, $context);
echo $data;
?>


例子四:

复制代码 代码如下:


<?php
function do_post_request($url, $postdata, $files = null)
{
$data = "";
$boundary = "---------------------".substr(md5(rand(0,32000)), 0, 10);
//Collect Postdata
foreach($postdata as $key => $val)
{
$data .= "--$boundary\n";
$data .= "Content-Disposition: form-data; name=\"".$key."\"\n\n".$val."\n";
}
$data .= "--$boundary\n";
//Collect Filedata
foreach($files as $key => $file)
{
$fileContents = file_get_contents($file['tmp_name']);
$data .= "Content-Disposition: form-data; name=\"{$key}\"; filename=\"{$file['name']}\"\n";
$data .= "Content-Type: image/jpeg\n";
$data .= "Content-Transfer-Encoding: binary\n\n";
$data .= $fileContents."\n";
$data .= "--$boundary--\n";
}
$params = array('http' => array(
'method' => 'POST',
'header' => 'Content-Type: multipart/form-data; boundary='.$boundary,
'content' => $data
));
$ctx = stream_context_create($params);
$fp = fopen($url, 'rb', false, $ctx);
if (!$fp) {
throw new Exception("Problem with $url, $php_errormsg");
}
$response = @stream_get_contents($fp);
if ($response === false) {
throw new Exception("Problem reading data from $url, $php_errormsg");
}
return $response;
}
//set data (in this example from post)
//sample data
$postdata = array(
'name' => $_POST['name'],
'age' => $_POST['age'],
'sex' => $_POST['sex']
);
//sample image
$files['image'] = $_FILES['image'];
do_post_request("http://www.jb51.net", $postdata, $files);
?>



stream_context_create解决file_get_contents超时处理

stream_context_create作用:
创建并返回一个文本数据流并应用各种选项,可用于fopen(),file_get_contents()等过程的超时设置、代理服务器、请求方式、头信息设置的特殊过程。
函数原型:resource stream_context_create ([ array $options [, array $params ]] )

在使用file_get_contents函数的时候,经常会出现超时的情况,在这里要通过查看一下错误提示,看看是哪种错误,比较常见的是读取超时,这种情况大家可以通过一些方法来尽量的避免或者解决。这里就简单介绍两种:

一、增加超时的时间限制

这里需要注意:set_time_limit只是设置你的PHP程序的超时时间,而不是file_get_contents函数读取URL的超时时间。一 开始以为set_time_limit也能影响到file_get_contents,后来经测试,是无效的。真正的修改 file_get_contents延时可以用resource $context的timeout参数:
 
$opts = array(
    'http'=>array(
    'method'=>"GET",
    'timeout'=>60,
  )
);
//创建数据流上下文
$context = stream_context_create($opts);

$html =file_get_contents('http://blog.sina.com/mirze', false, $context);

//fopen输出文件指针处的所有剩余数据:
//fpassthru($fp); //fclose()前使用

二、一次有延时的话那就多试几次

有时候失败是因为网络等因素造成,没有解决办法,但是可以修改程序,失败时重试几次,仍然失败就放弃,因为file_get_contents()如果失败将返回 FALSE,所以可以下面这样编写代码:
$cnt=0;
while($cnt < 3 && ($str=@file_get_contents('http://blog.sina.com/mirze'))===FALSE) $cnt++;

以上方法对付超时已经OK了。

那么Post呢?细心点有人发现了'method'=>"GET", 对!是不是能设置成post呢?百度找了下相关资料,还真可以!而且有人写出了山寨版的post传值函数,如下:

function Post($url, $post = null){
     $context = array();

     if (is_array($post)) {
         ksort($post);

         $context['http'] = array (
             'timeout'=>60,
             'method' => 'POST',
             'content' => http_build_query($post, '', '&'),
         );
     }
     return file_get_contents($url, false, stream_context_create($context));
}

$data = array(
     'name' => 'test',
     'email' => 'test@gmail.com',
     'submit' => 'submit',
);
echo Post('http://www.ej38.com', $data);

OK , 上面函数完美了,既解决了超时控制又解决了Post传值。再配合康盛的改良版RC4加密解密算法,做一个安全性很高的webservice就简单多了。

参考:http://hi.baidu.com/lssbing/blog/item/9a2dcb0f1183a1266059f38d.html


php使用stream_context_create用POST方法发送数据时目标服务器接收不到数据的解决办法


$opts=array(
‘http’=>array(
‘method’=>’post’,
‘header’=>’Content-Type: application/x-www-form-urlencoded’,
‘content’=>$data)
);
$context=stream_context_create($opts);
return file_get_contents(REMOTE_URL.’?act=’.$act.’&id=’.$this->id,false,$context);
看出什么问题了么?

答案就是method=>’POST’,这里POST必须大写。



stream_context_create:

使用这个方法,就可以更容易的模拟GET、POST请求了,当然,他们作用不只局限于这些,演示代码:
PHP Code复制内容到剪贴板
  1. private static function client($method='GET', $queryString='')   
  2.     {   
  3.         $params['http'] = array(   
  4.             'method' => $method,   
  5.             'header'=> "Content-type: application/x-www-form-urlencoded\r\n"  
  6.                     .  "Content-Length:" . strlen($queryString) ."\r\n"  
  7.                     .  "connection:close\r\n\r\n",   
  8.             'user_agent' => $_SERVER['HTTP_USER_AGENT'],   
  9.             'content' => $queryString  
  10.         );   
  11.           
  12.         $context = stream_context_create($params);   
  13.         return file_get_contents(self::$_url, false, $context);   
  14.     }   
  15.   
  16.   
  17. <?php   
  18. $opts = array(   
  19. 'http'=>array(   
  20.     'method'=>"GET",   
  21.     'header'=>"Accept-language: en\r\n" .   
  22.               "Cookie: foo=bar\r\n"  
  23. )   
  24. );   
  25.   
  26. $context = stream_context_create($opts);   
  27.   
  28. /* Sends an http request to www.example.com  
  29.    with additional headers shown above */  
  30. $fp = fopen('http://www.example.com', 'r', false, $context);   
  31. fpassthru($fp);   
  32. fclose($fp);   
  33. ?>  


参考:
http://www.itokit.com/2011/0530/66343.html

posted on 2015-10-25 00:02  hahahahahai12  阅读(633)  评论(0)    收藏  举报

导航