PHP: 模拟 POST 提交表单, Sending POST data without form, send a POST request with PHP

 

方法有很多种,比如用 AJAX:

$.post('/foo.php', { key1: 'value1', key2: 'value2' }, function(result) {
    alert('successfully posted key1=value1&key2=value2 to foo.php');
});

又比如用CURL:

function httpPost($url, $data)
{
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);
    curl_close($curl);
    return $response;
}

或者带登录信息的:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

但是今天要说的是:stream_context_create

实例:

$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');

// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }

var_dump($result);

作用:创建并返回一个文本数据流并应用各种选项,可用于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 justcode.ikeepstudying.com
with additional headers shown above */
$fp = fopen('http://www.your-server.com', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>

一些要点讲解:

1. 以上程序用到了 http_build_query() 函数,就是将一个数组转换成url 问号?后面的参数字符串,并且会自动进行urlencode处理。还是看一些简单的例子吧:

$data = array(
	'foo'=>'bar', 
	'baz'=>'boom', 
	'site'=>'www.ikeepstuyding.com', 
	'name'=>'just code'); 
	
echo http_build_query($data); 

/* output 
	foo=bar&baz=boom&site=www.ikeepstuyding.com&name=just+code 
*/ 

如果是索引数组与关联数组混合而成的数组又如何呢?

$data = array(
	'foo',
	'bar', 
	'site'=>'www.ikeepstuyding.com', 
	'name'=>'just code'); 
	
echo http_build_query($data); 

/* output 
	0=foo&1=bar&site=www.ikeepstuyding.com&name=just+code
*/ 

它会自动添加数字索引。

http_build_query 还有一个参数,可以给数字索引加前缀,我们再试试:

$data = array(
	'foo',
	'bar', 
	'site'=>'www.ikeepstuyding.com', 
	'name'=>'just code'); 
	
echo http_build_query($data, "nm_"); 

/* output 
	nm_0=foo&nm_1=bar&site=www.ikeepstuyding.com&name=just+code
*/ 

2. stream_context_create() 是用来创建打开文件的上下文件选项的,比如用POST访问,使用代理,发送header等。就是 创建一个流,再举一个例子吧:

$context = stream_context_create(array( 
	'http' => array( 
		'method'  => 'POST', 
		'header'  => sprintf("Authorization: Basic %s\r\n", base64_encode($username.':'.$password)). 
		"Content-type: application/x-www-form-urlencoded\r\n", 
		'content' => http_build_query(array('status' => $message)), 
		'timeout' => 5, 
	), 
)); 
$ret = file_get_contents('http://twitter.com/statuses/update.xml', false, $context); 

3. stream_context_create创建的上下文选项即可用于流(stream),也可用于文件系统(file system)。对于像 file_get_contents、file_put_contents、readfile直接使用文件名操作而没有文件句柄的函数来说更有用。stream_context_create增加header头只是一部份功能,还可以定义代理、超时等。这使得访问web的功能不弱于curl。

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

5. stream_context_create 还能通过增加 timeout 选项解决file_get_contents超时处理:

$opts = array(
    'http'=>array(
    'method'=>"GET",
    'timeout'=>60,
  )
);
//创建数据流上下文
$context = stream_context_create($opts);

$html =file_get_contents('http://www.ikeepstuyding.com', false, $context);

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

 

PHP: 模拟 POST 提交表单, Sending POST data without form, send a POST request with PHP
PHP: 模拟 POST 提交表单, Sending POST data without form, send a POST request with PHP

 

 

本文:PHP: 模拟 POST 提交表单, Sending POST data without form, send a POST request with PHP