如何使用 PHP 发送 POST 请求?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5647461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I send a POST request with PHP?
提问by Fred Tanrikut
Actually I want to read the contents that come after the search query, when it is done. The problem is that the URL only accepts POST
methods, and it does not take any action with GET
method...
实际上,我想阅读搜索查询之后的内容,完成后。问题是URL只接受POST
方法,对GET
方法不做任何动作...
I have to read all contents with the help of domdocument
or file_get_contents()
. Is there any method that will let me send parameters with POST
method and then read the contents via PHP
?
我必须在domdocument
或的帮助下阅读所有内容file_get_contents()
。有没有什么方法可以让我用POST
方法发送参数然后通过读取内容PHP
?
回答by dbau
CURL-less method with PHP5:
使用 PHP5 的无 CURL 方法:
$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);
See the PHP manual for more information on the method and how to add headers, for example:
有关该方法以及如何添加标题的更多信息,请参阅 PHP 手册,例如:
- stream_context_create: http://php.net/manual/en/function.stream-context-create.php
- stream_context_create: http://php.net/manual/en/function.stream-context-create.php
回答by Fred Tanrikut
You could use cURL:
您可以使用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 data
curl_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 it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec($ch);
echo $result;
?>
回答by Dima L.
I use the following function to post data using curl. $data is an array of fields to post (will be correctly encoded using http_build_query). The data is encoded using application/x-www-form-urlencoded.
我使用以下函数使用 curl 发布数据。$data 是要发布的字段数组(将使用 http_build_query 正确编码)。数据使用 application/x-www-form-urlencoded 进行编码。
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 mentions that http_build_query may be omitted since curl will correctly encode array passed to CURLOPT_POSTFIELDS parameter, but be advised that in this case the data will be encoded using multipart/form-data.
@Edward 提到 http_build_query 可能会被省略,因为 curl 会正确编码传递给 CURLOPT_POSTFIELDS 参数的数组,但请注意,在这种情况下,数据将使用 multipart/form-data 进行编码。
I use this function with APIs that expect data to be encoded using application/x-www-form-urlencoded. That's why I use http_build_query().
我将此函数与希望使用 application/x-www-form-urlencoded 对数据进行编码的 API 一起使用。这就是我使用 http_build_query() 的原因。
回答by Andreas
I recommend you to use the open-source package guzzlethat is fully unit tested and uses the latest coding practices.
我建议您使用经过全面单元测试并使用最新编码实践的开源软件包guzzle。
Installing Guzzle
安装 Guzzle
Go to the command line in your project folder and type in the following command (assuming you already have the package manager composerinstalled). If you need help how to install Composer, you should have a look here.
转到项目文件夹中的命令行并输入以下命令(假设您已经安装了包管理器composer)。如果您需要有关如何安装 Composer 的帮助,您应该查看这里。
php composer.phar require guzzlehttp/guzzle
Using Guzzle to send a POST request
使用 Guzzle 发送 POST 请求
The usage of Guzzle is very straight forward as it uses a light-weight object-oriented API:
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);
回答by Josip Ivic
There's another CURL method if you are going that way.
如果您要这样做,还有另一种 CURL 方法。
This is pretty straightforward once you get your head around the way the PHP curl extension works, combining various flags with setopt() calls. In this example I've got a variable $xml which holds the XML I have prepared to send - I'm going to post the contents of that to example's test method.
一旦您了解 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
First we initialised the connection, then we set some options using setopt(). These tell PHP that we are making a post request, and that we are sending some data with it, supplying the data. The CURLOPT_RETURNTRANSFER flag tells curl to give us the output as the return value of curl_exec rather than outputting it. Then we make the call and close the connection - the result is in $response.
首先我们初始化连接,然后我们使用 setopt() 设置一些选项。这些告诉 PHP 我们正在发出一个 post 请求,并且我们正在发送一些数据,提供数据。CURLOPT_RETURNTRANSFER 标志告诉 curl 将输出作为 curl_exec 的返回值提供给我们,而不是输出它。然后我们进行调用并关闭连接 - 结果在 $response 中。
回答by Josip Ivic
If you by any chance are using Wordpress to develop your app (it's actually a convenient way to get authorization, info pages etc even for very simple stuff), you can use the following snippet:
如果您有机会使用 Wordpress 来开发您的应用程序(它实际上是一种获得授权、信息页面等的便捷方式,即使是非常简单的东西),您可以使用以下代码段:
$response = wp_remote_post( $url, array('body' => $parameters));
if ( is_wp_error( $response ) ) {
// $response->get_error_message()
} else {
// $response['body']
}
It uses different ways of making the actual HTTP request, depending on what is available on the web server. For more details, see the HTTP API documentation.
它使用不同的方式发出实际的 HTTP 请求,具体取决于 Web 服务器上可用的内容。有关更多详细信息,请参阅HTTP API 文档。
If you don't want to develop a custom theme or plugin to start the Wordpress engine, you can just do the following in an isolated PHP file in the wordpress root:
如果您不想开发自定义主题或插件来启动 Wordpress 引擎,您只需在 wordpress 根目录下的独立 PHP 文件中执行以下操作:
require_once( dirname(__FILE__) . '/wp-load.php' );
// ... your code
It won't show any theme or output any HTML, just hack away with the Wordpress APIs!
它不会显示任何主题或输出任何 HTML,只需使用 Wordpress API 即可!
回答by mwatzer
I'd like to add some thoughts about the curl-based answer of Fred Tanrikut. I know most of them are already written in the answers above, but I think it is a good idea to show an answer that includes all of them together.
我想补充一些关于 Fred Tanrikut 基于 curl 的答案的想法。我知道他们中的大多数已经写在上面的答案中,但我认为展示一个包含所有这些的答案是个好主意。
Here is the class I wrote to make HTTP-GET/POST/PUT/DELETE requests based on curl, concerning just about the response body:
这是我编写的基于 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;
}
}
Improvements
改进
- 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_setoptfunction 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)
- 使用 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 处理程序的删除。见:http: //php.net/manual/en/function.curl-close.php
- 对curl_setopt函数使用布尔值而不是使用任何数字。(我知道任何不等于零的数字也被认为是 true,但使用 true 会生成更易读的代码,但这只是我的意见)
- 能够进行 HTTP-PUT/DELETE 调用(用于 RESTful 服务测试)
Example of usage
使用示例
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"));
DELETE
删除
$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));
Testing
测试
You can also make some cool service tests by using this simple class.
您还可以使用这个简单的类进行一些很酷的服务测试。
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}]');
}
}
回答by CPHPython
Another alternative of the curl-lessmethod aboveis to use the native streamfunctions:
上面的curl-less方法的另一种替代方法是使用本机流函数:
stream_context_create()
:Creates and returns a stream context with any options supplied in optionspreset.
stream_get_contents()
:Identical to
file_get_contents()
, except thatstream_get_contents()
operates on an already open streamresource and returns the remaining contents in a string, up to maxlengthbytes and starting at the specified offset.
stream_context_create()
:使用选项预设中提供的任何选项创建并返回流上下文。
stream_get_contents()
:与 相同
file_get_contents()
,除了stream_get_contents()
在已经打开的流资源上操作并返回字符串中的剩余内容,最多为maxlength字节并从指定的offset 开始。
A POST function with these can simply be like this:
带有这些的 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;
}
回答by Imran Zahoor
The better way of sending GET
or POST
requests with PHP
is as below:
更好的发送GET
或POST
请求方式PHP
如下:
<?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;
}
?>
The code is taken from official documentation here http://docs.php.net/manual/da/httprequest.send.php
代码取自这里的官方文档http://docs.php.net/manual/da/httprequest.send.php
回答by Liga
Here is using just one command without cURL. Super simple.
这里只使用一个没有 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'
])
]
]));