实际上,我想读取搜索查询之后的内容,当它完成时。问题是URL只接受POST方法,它不采取任何行动与GET方法…
我必须在domdocument或file_get_contents()的帮助下读取所有内容。有没有什么方法可以让我用POST方法发送参数,然后通过PHP读取内容?
实际上,我想读取搜索查询之后的内容,当它完成时。问题是URL只接受POST方法,它不采取任何行动与GET方法…
我必须在domdocument或file_get_contents()的帮助下读取所有内容。有没有什么方法可以让我用POST方法发送参数,然后通过PHP读取内容?
当前回答
上面的无卷曲方法的另一种替代方法是使用本机流函数:
stream_context_create (): 创建并返回带有options预置中提供的任何选项的流上下文。 stream_get_contents (): 与file_get_contents()相同,不同之处在于stream_get_contents()操作的是已经打开的流资源,并以字符串形式返回剩余内容,最大长度为maxlength字节,从指定的偏移量开始。
具有这些功能的POST函数可以简单地像这样:
<?php
function post_request($url, array $params) {
$query_content = http_build_query($params);
$fp = fopen($url, 'r', FALSE, // do not use_include_path
stream_context_create([
'http' => [
'header' => [ // header array does not need '\r\n'
'Content-type: application/x-www-form-urlencoded',
'Content-Length: ' . strlen($query_content)
],
'method' => 'POST',
'content' => $query_content
]
]));
if ($fp === FALSE) {
return json_encode(['error' => 'Failed to get contents...']);
}
$result = stream_get_contents($fp); // no maxlength/offset
fclose($fp);
return $result;
}
其他回答
我想补充一些关于Fred Tanrikut基于卷曲的回答的想法。我知道大部分问题已经写在上面的答案中,但我认为给出一个包括所有问题的答案是个好主意。
下面是我编写的基于curl进行HTTP-GET/POST/PUT/DELETE请求的类,只涉及响应体:
class HTTPRequester {
/**
* @description Make HTTP-GET call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPGet($url, array $params) {
$query = http_build_query($params);
$ch = curl_init($url.'?'.$query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
/**
* @description Make HTTP-POST call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPPost($url, array $params) {
$query = http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
/**
* @description Make HTTP-PUT call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPPut($url, array $params) {
$query = \http_build_query($params);
$ch = \curl_init();
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_HEADER, false);
\curl_setopt($ch, \CURLOPT_URL, $url);
\curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
$response = \curl_exec($ch);
\curl_close($ch);
return $response;
}
/**
* @category Make HTTP-DELETE call
* @param $url
* @param array $params
* @return HTTP-Response body or an empty string if the request fails or is empty
*/
public static function HTTPDelete($url, array $params) {
$query = \http_build_query($params);
$ch = \curl_init();
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, \CURLOPT_HEADER, false);
\curl_setopt($ch, \CURLOPT_URL, $url);
\curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
\curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
$response = \curl_exec($ch);
\curl_close($ch);
return $response;
}
}
改进
Using http_build_query to get the query-string out of an request-array.(you could also use the array itself, therefore see: http://php.net/manual/en/function.curl-setopt.php) Returning the response instead of echoing it. Btw you can avoid the returning by removing the line curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);. After that the return value is a boolean(true = request was successful otherwise an error occured) and the response is echoed. See: http://php.net/en/manual/function.curl-exec.php Clean session closing and deletion of the curl-handler by using curl_close. See: http://php.net/manual/en/function.curl-close.php Using boolean values for the curl_setopt function instead of using any number.(I know that any number not equal zero is also considered as true, but the usage of true generates a more readable code, but that's just my opinion) Ability to make HTTP-PUT/DELETE calls(useful for RESTful service testing)
用法示例
GET
$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));
POST
$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));
PUT
$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));
删除
$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));
测试
您还可以通过使用这个简单的类来进行一些很酷的服务测试。
class HTTPRequesterCase extends TestCase {
/**
* @description test static method HTTPGet
*/
public function testHTTPGet() {
$requestArr = array("getLicenses" => 1);
$url = "http://localhost/project/req/licenseService.php";
$this->assertEquals(HTTPRequester::HTTPGet($url, $requestArr), '[{"error":false,"val":["NONE","AGPL","GPLv3"]}]');
}
/**
* @description test static method HTTPPost
*/
public function testHTTPPost() {
$requestArr = array("addPerson" => array("foo", "bar"));
$url = "http://localhost/project/req/personService.php";
$this->assertEquals(HTTPRequester::HTTPPost($url, $requestArr), '[{"error":false}]');
}
/**
* @description test static method HTTPPut
*/
public function testHTTPPut() {
$requestArr = array("updatePerson" => array("foo", "bar"));
$url = "http://localhost/project/req/personService.php";
$this->assertEquals(HTTPRequester::HTTPPut($url, $requestArr), '[{"error":false}]');
}
/**
* @description test static method HTTPDelete
*/
public function testHTTPDelete() {
$requestArr = array("deletePerson" => array("foo", "bar"));
$url = "http://localhost/project/req/personService.php";
$this->assertEquals(HTTPRequester::HTTPDelete($url, $requestArr), '[{"error":false}]');
}
}
如果你这样做的话,还有另一个CURL方法。
一旦您了解了PHP curl扩展的工作方式,将各种标志与setopt()调用结合起来,这就非常简单了。在这个例子中,我有一个变量$xml,它保存了我准备发送的xml -我将把它的内容发布到示例的测试方法。
$url = 'http://api.example.com/services/xmlrpc/';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
//process $response
首先初始化连接,然后使用setopt()设置一些选项。它们告诉PHP我们正在发出post请求,并且我们正在发送一些数据,提供数据。CURLOPT_RETURNTRANSFER标志告诉curl将输出作为curl_exec的返回值而不是输出。然后我们进行调用并关闭连接-结果显示在$response中。
用PHP发送GET或POST请求的更好方法如下:
<?php
$r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
$r->setOptions(array('cookies' => array('lang' => 'de')));
$r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));
try {
echo $r->send()->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
代码摘自官方文档http://docs.php.net/manual/da/httprequest.send.php
我建议你使用开源包guzzle,它经过了完整的单元测试,并使用了最新的编码实践。
安装狂饮
转到项目文件夹中的命令行并键入以下命令(假设已经安装了包管理器编写器)。如果你需要如何安装Composer的帮助,你应该看看这里。
php composer.phar require guzzlehttp/guzzle
使用Guzzle发送POST请求
Guzzle的用法非常直接,因为它使用了一个轻量级的面向对象的API:
// Initialize Guzzle client
$client = new GuzzleHttp\Client();
// Create a POST request
$response = $client->request(
'POST',
'http://example.org/',
[
'form_params' => [
'key1' => 'value1',
'key2' => 'value2'
]
]
);
// Parse the response object, e.g. read the headers, body, etc.
$headers = $response->getHeaders();
$body = $response->getBody();
// Output headers and body for debugging purposes
var_dump($headers, $body);
根据主要答案,以下是我使用的方法:
function do_post($url, $params) {
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => $params
)
);
$result = file_get_contents($url, false, stream_context_create($options));
}
使用示例:
do_post('https://www.google-analytics.com/collect', 'v=1&t=pageview&tid=UA-xxxxxxx-xx&cid=abcdef...');