如何使用PHP发送POST请求?

实际上,我想在搜索查询完成后读取搜索查询后的内容。问题是URL只接受POST方法,它不使用GET方法执行任何操作…

我必须在domdocumentfile_get_contents()的帮助下读取所有内容。有没有什么方法可以让我使用POST方法发送参数,然后通过PHP读取内容?

1362250 次浏览

尝试PEAR的HTTP_Request2包以轻松发送POST请求。或者,您可以使用PHP的curl函数或使用PHP流上下文

HTTP_Request2还可以模拟服务器,因此您可以轻松地对代码进行单元测试

您可以使用cURL

<?php//The url you wish to send the POST request to$url = $file_name;
//The data you want to send via POST$fields = ['__VIEWSTATE '      => $state,'__EVENTVALIDATION' => $valid,'btnSubmit'         => 'Submit'];
//url-ify the data for the POST$fields_string = http_build_query($fields);
//open connection$ch = curl_init();
//set the url, number of POST vars, POST datacurl_setopt($ch,CURLOPT_URL, $url);curl_setopt($ch,CURLOPT_POST, true);curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//So that curl_exec returns the contents of the cURL; rather than echoing itcurl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post$result = curl_exec($ch);echo $result;?>

使用PHP5的无卷曲方法:

$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);

有关该方法以及如何添加标头的更多信息,请参阅PHP手册,例如:

如果你要走那条路,还有另一种CURL方法。

一旦你了解了PHP curl扩展的工作方式,将各种标志与setop()调用组合起来,这就非常简单了。在这个例子中,我有一个变量$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的返回值,而不是输出它。然后我们进行调用并关闭连接-结果是$响应。

[编辑]:请忽略,现在在php中不可用。

还有一个你可以用的

<?php$fields = array('name' => 'mike','pass' => 'se_ret');$files = array(array('name' => 'uimg','type' => 'image/jpeg','file' => './profile.jpg',));
$response = http_post_fields("http://www.example.com/", $fields, $files);?>

点击这里了解详情

如果你有机会使用Wordpress来开发你的应用程序(它实际上是一种方便的方式来获得授权,信息页面等,即使是非常简单的东西),你可以使用以下片段:

$response = wp_remote_post( $url, array('body' => $parameters));
if ( is_wp_error( $response ) ) {// $response->get_error_message()} else {// $response['body']}

它使用不同的方式发出实际的HTTP请求,具体取决于Web服务器上可用的内容。有关更多详细信息,请参阅HTTP API留档

如果您不想开发自定义主题或插件来启动Wordpress引擎,您可以在wordpress根目录中的独立PHP文件中执行以下操作:

require_once( dirname(__FILE__) . '/wp-load.php' );
// ... your code

它不会显示任何主题或输出任何超文本标记语言,只需使用WordPress API即可!

我一直在寻找一个类似的问题,并找到了一个更好的解决方法。

您可以简单地将以下行放在重定向页面上(例如page1.php)。

header("Location: URL", TRUE, 307); // Replace URL with to be redirected URL, e.g. final.php

我需要它来重定向REST API调用的POST请求。此解决方案能够使用发布数据以及自定义标头值重定向。

这里是的参考链接

我使用以下函数使用curl发布数据。$data是要发布的字段数组(将使用http_build_query()正确编码)。

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;}

@Edward提到http_build_query()可能会被省略,因为curl将正确编码传递给CURLOPT_POSTFIELDS参数的数组,这是正确的,但请注意,在这种情况下,数据将使用multipart/form-data编码,并且可能不理想,因为一些端点期望数据使用application/x-www-form-urlencoded编码。当像上面的函数一样使用http_build_query()时,数据将使用application/x-www-form-urlencoded编码。

我建议您使用经过完全单元测试并使用最新编码实践的开源包狂饮

安装喷枪

转到项目文件夹中的命令行并输入以下命令(假设您已经安装了包管理器作曲家)。如果您需要帮助如何安装Composer,你应该看看这里

php composer.phar require guzzlehttp/guzzle

使用Guzzes发送POST请求

古斯的用法非常简单,因为它使用了一个轻量级的面向对象的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 purposesvar_dump($headers, $body);

我想补充一些关于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;}}

改进

  • 使用http_build_query从请求数组中获取查询字符串(您也可以使用数组本身,因此请参阅:http://php.net/manual/en/function.curl-setopt.php
  • 返回响应而不是回显它。顺便说一句,您可以通过删除curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);行来避免返回。之后返回值是布尔值(true=请求成功,否则发生错误)并且响应被回显。见:http://php.net/en/manual/function.curl-exec.php
  • 使用curl_close清理会话关闭和删除curl-handler。参见:http://php.net/manual/en/function.curl-close.php
  • curl_setopt函数使用布尔值而不是使用任何数字。(我知道任何不等于零的数字也被认为是true,但是使用true会产生更可读的代码,但这只是我的意见)
  • 能够进行HTTP-PUT/DELETE调用(对RESTful服务测试有用)

用法示例

get

$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));

POST

$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));

$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}]');}}

<强>少卷曲上面的方法的另一种选择是使用本机函数:

带有这些的POST函数可以简单地像这样:

<?php
function post_request($url, array $params) {$query_content = http_build_query($params);$fp = fopen($url, 'r', FALSE, // do not use_include_pathstream_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/offsetfclose($fp);return $result;}

使用PHP发送GETPOST请求的更好方法如下:

<?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

这里只使用一个没有cURL的命令。超级简单。

echo file_get_contents('https://www.server.com', false, stream_context_create(['http' => ['method' => 'POST','header'  => "Content-type: application/x-www-form-urlencoded",'content' => http_build_query(['key1' => 'Hello world!', 'key2' => 'second value'])]]));

根据主要答案,以下是我使用的:

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...');

我比较喜欢这个:

function curlPost($url, $data = NULL, $headers = []) {$ch = curl_init($url);curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36');curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);curl_setopt($ch, CURLOPT_TIMEOUT, 5); //timeout in secondscurl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);curl_setopt($ch, CURLOPT_ENCODING, 'identity');
    
if (!empty($data)) {curl_setopt($ch, CURLOPT_POSTFIELDS, $data);}
if (!empty($headers)) {curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);}
$response = curl_exec($ch);if (curl_error($ch)) {trigger_error('Curl Error:' . curl_error($ch));}
curl_close($ch);return $response;}

使用示例:

$response=curlPost("http://my.url.com", ["myField1"=>"myValue1"], ["myFitstHeaderName"=>"myFirstHeaderValue"]);

我创建了一个函数来使用JSON请求帖子:

const FORMAT_CONTENT_LENGTH = 'Content-Length: %d';const FORMAT_CONTENT_TYPE = 'Content-Type: %s';
const CONTENT_TYPE_JSON = 'application/json';/*** @description Make a HTTP-POST JSON call* @param string $url* @param array $params* @return bool|string HTTP-Response body or an empty string if the request fails or is empty*/function HTTPJSONPost(string $url, array $params){$content = json_encode($params);$response = file_get_contents($url, false, // do not use_include_pathstream_context_create(['http' => ['method' => 'POST','header' => [ // header array does not need '\r\n'sprintf(FORMAT_CONTENT_TYPE, CONTENT_TYPE_JSON),sprintf(FORMAT_CONTENT_LENGTH, strlen($content)),],'content' => $content]])); // no maxlength/offsetif ($response === false) {return json_encode(['error' => 'Failed to get contents...']);}
return $response;}

这里可以使用此代码:

<?php$postdata = http_build_query(array('name' => 'Robert','id' => '1'));$opts = array('http' =>array('method' => 'POST','header' => 'Content-type: application/x-www-form-urlencoded','content' => $postdata));$context = stream_context_create($opts);$result = file_get_contents('http://localhost:8000/api/test', false, $context);echo $result;?>

上面的答案对我不起作用。这是第一个运行完美的解决方案:

$sPD = "name=Jacob&bench=150"; // The POST Data$aHTTP = array('http' => // The wrapper to be usedarray('method'  => 'POST', // Request Method// Request Headers Below'header'  => 'Content-type: application/x-www-form-urlencoded','content' => $sPD));$context = stream_context_create($aHTTP);$contents = file_get_contents($sURL, false, $context);
echo $contents;