PHP + curl、HTTP POST 示例代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2138527/
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
PHP + curl, HTTP POST sample code?
提问by mysqllearner
Can anyone show me how to do a php curl with an HTTP POST?
谁能告诉我如何用 HTTP POST 做一个 php curl?
I want to send data like this:
我想发送这样的数据:
username=user1, password=passuser1, gender=1
To www.domain.com
到 www.domain.com
I expect the curl to return a response like result=OK. Are there any examples?
我希望 curl 返回类似result=OK. 有没有例子?
回答by miku
<?php
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
?>
回答by emix
Procedural
程序
// set post fields
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init('http://www.example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
Object oriented
面向对象
<?php
// mutatis mutandis
namespace MyApp\Http;
class CurlPost
{
private $url;
private $options;
/**
* @param string $url Request URL
* @param array $options cURL options
*/
public function __construct($url, array $options = [])
{
$this->url = $url;
$this->options = $options;
}
/**
* Get the response
* @return string
* @throws \RuntimeException On cURL error
*/
public function __invoke(array $post)
{
$ch = curl_init($this->url);
foreach ($this->options as $key => $val) {
curl_setopt($ch, $key, $val);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$response = curl_exec($ch);
$error = curl_error($ch);
$errno = curl_errno($ch);
if (is_resource($ch)) {
curl_close($ch);
}
if (0 !== $errno) {
throw new \RuntimeException($error, $errno);
}
return $response;
}
}
Usage
用法
// create curl object
$curl = new \MyApp\Http\CurlPost('http://www.example.com');
try {
// execute the request
echo $curl([
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
]);
} catch (\RuntimeException $ex) {
// catch errors
die(sprintf('Http error %s with code %d', $ex->getMessage(), $ex->getCode()));
}
Side note here: it would be best to create some kind of interface called AdapterInterfacefor example with getResponse()method and let the class above implement it. Then you can always swap this implementation with another adapter of your like, without any side effects to your application.
这里的旁注:最好创建某种接口AdapterInterface,例如用getResponse()方法调用,并让上面的类实现它。然后您可以随时将这个实现与您喜欢的另一个适配器交换,而不会对您的应用程序产生任何副作用。
Using HTTPS / encrypting traffic
使用 HTTPS / 加密流量
Usually there's a problem with cURL in PHP under the Windows operating system. While trying to connect to a https protected endpoint, you will get an error telling you that certificate verify failed.
通常在Windows 操作系统下PHP 中的cURL 会出现问题。在尝试连接到受 https 保护的端点时,您会收到一条错误消息,告诉您certificate verify failed.
What most people do here is to tell the cURL library to simply ignore certificate errors and continue (curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);). As this will make your code work, you introduce huge security hole and enable malicious users to perform various attacks on your app like Man In The Middleattack or such.
大多数人在这里做的是告诉 cURL 库简单地忽略证书错误并继续 ( curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);)。由于这将使您的代码正常工作,因此您引入了巨大的安全漏洞并使恶意用户能够对您的应用程序执行各种攻击,例如中间人攻击等。
Never, ever do that. Instead, you simply need to modify your php.iniand tell PHP where your CA Certificatefile is to let it verify certificates correctly:
永远,永远不要那样做。相反,您只需要修改您php.ini的CA Certificate文件并告诉 PHP 您的文件在哪里,让它正确验证证书:
; modify the absolute path to the cacert.pem file
curl.cainfo=c:\php\cacert.pem
The latest cacert.pemcan be downloaded from the Internet or extracted from your favorite browser. When changing any php.inirelated settings remember to restart your webserver.
最新的cacert.pem可以从 Internet 下载或从您喜欢的浏览器中提取。更改任何php.ini相关设置时,请记住重新启动您的网络服务器。
回答by Eric Leschinski
A live example of using php curl_exec to do an HTTP post:
使用 php curl_exec 执行 HTTP 帖子的现场示例:
Put this in a file called foobar.php:
把它放在一个名为 foobar.php 的文件中:
<?php
$ch = curl_init();
$skipper = "luxury assault recreational vehicle";
$fields = array( 'penguins'=>$skipper, 'bestpony'=>'rainbowdash');
$postvars = '';
foreach($fields as $key=>$value) {
$postvars .= $key . "=" . $value . "&";
}
$url = "http://www.google.com";
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1); //0 for a get request
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
curl_setopt($ch,CURLOPT_TIMEOUT, 20);
$response = curl_exec($ch);
print "curl response is:" . $response;
curl_close ($ch);
?>
Then run it with the command php foobar.php, it dumps this kind of output to screen:
然后使用命令运行它php foobar.php,它将这种输出转储到屏幕:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<body>
A mountain of content...
</body>
</html>
So you did a PHP POST to www.google.com and sent it some data.
因此,您对 www.google.com 进行了 PHP POST 并向其发送了一些数据。
Had the server been programmed to read in the post variables, it could decide to do something different based upon that.
如果服务器被编程为读取 post 变量,它可以决定基于此做一些不同的事情。
回答by V. Kovpak
It's can be easily reached with:
它可以通过以下方式轻松到达:
<?php
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.domain.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$response = curl_exec($ch);
var_export($response);
回答by MSS
Curl Post + Error Handling + Set Headers [thanks to @mantas-d]:
Curl Post + 错误处理 + 设置标题 [感谢@mantas-d]:
function curlPost($url, $data=NULL, $headers = NULL) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
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;
}
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
回答by Mantas D
curlPost('google.com', [
'username' => 'admin',
'password' => '12345',
]);
function curlPost($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error !== '') {
throw new \Exception($error);
}
return $response;
}
回答by Anthony
If the form is using redirects, authentication, cookies, SSL (https), or anything else other than a totally open script expecting POST variables, you are going to start gnashing your teeth really quick. Take a look at Snoopy, which does exactly what you have in mind while removing the need to set up a lot of the overhead.
如果表单使用重定向、身份验证、cookie、SSL (https) 或其他任何东西,而不是需要 POST 变量的完全开放的脚本,那么您将很快开始咬牙切齿。看看Snoopy,它完全符合您的想法,同时消除了设置大量开销的需要。
回答by user2532795
A simpler answer IF you are passing information to your own website is to use a SESSION variable. Begin php page with:
如果您将信息传递到自己的网站,一个更简单的答案是使用 SESSION 变量。开始 php 页面:
session_start();
If at some point there is information you want to generate in PHP and pass to the next page in the session, instead of using a POST variable, assign it to a SESSION variable. Example:
如果在某个时候您想在 PHP 中生成信息并传递到会话中的下一页,而不是使用 POST 变量,请将其分配给 SESSION 变量。例子:
$_SESSION['message']='www.'.$_GET['school'].'.edu was not found. Please try again.'
Then on the next page you simply reference this SESSION variable. NOTE: after you use it, be sure you destroy it, so it doesn't persist after it is used:
然后在下一页上,您只需引用这个 SESSION 变量。注意:使用后,请务必销毁它,以免在使用后持续存在:
if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}
回答by AzizSM
Here are some boilerplate code for PHP + curl http://www.webbotsspidersscreenscrapers.com/DSP_download.php
以下是 PHP + curl 的一些样板代码 http://www.webbotsspidersscreenscrapers.com/DSP_download.php
include in these library will simplify development
包含在这些库中将简化开发
<?php
# Initialization
include("LIB_http.php");
include("LIB_parse.php");
$product_array=array();
$product_count=0;
# Download the target (store) web page
$target = "http://www.tellmewhenitchanges.com/buyair";
$web_page = http_get($target, "");
...
?>
回答by Atanas Atanasov
If you try to login on site with cookies.
如果您尝试使用 cookie 登录网站。
This code:
这段代码:
if ($server_output == "OK") { ... } else { ... }
May not works if you try to login, because many sites returns status 200, but the post is not successful.
如果您尝试登录可能不起作用,因为许多站点返回状态 200,但发布不成功。
Easy way to check if the login post is successful is check if it setting cookies again. If in output have Set-Cookies string, this means the posts is not successful and it starts new session.
检查登录帖子是否成功的简单方法是检查它是否再次设置 cookie。如果在输出中有 Set-Cookies 字符串,这意味着帖子不成功并且它开始新的会话。
Also the post can be successful, but the status can be redirect instead 200.
帖子也可以成功,但状态可以重定向而不是 200。
To be sure the post is successful try this:
为确保帖子成功,请尝试以下操作:
Follow location after the post, so it will go to the page where the post do redirect to:
关注帖子后的位置,因此它将转到帖子重定向到的页面:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
And than check if new cookies existing in the request:
然后检查请求中是否存在新的 cookie:
if (!preg_match('/^Set-Cookie:\s*([^;]*)/mi', $server_output))
{echo 'post successful'; }
else { echo 'not successful'; }

