PHP + curl,HTTP POST示例代码?

mys*_*ner 454 php curl http http-post

任何人都可以告诉我如何使用HTTP POST进行PHP卷曲吗?

我想发送这样的数据:

username=user1, password=passuser1, gender=1
Run Code Online (Sandbox Code Playgroud)

www.domain.com

我希望curl能够返回响应result=OK.有什么例子吗?

mik*_*iku 776

<?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 { ... }
?>
Run Code Online (Sandbox Code Playgroud)

  • 不需要使用`http_build_query()`来处理参数; 只需将数组传递给`CURLOPT_POSTFIELDS`即可. (37认同)
  • 此外,如果`CURLOPT_POSTFIELDS`的值是一个数组,`Content-Type`标题将被设置为`multipart/form-data`而不是`application/x-www-form-urlencoded`.http://php.net/manual/en/function.curl-setopt.php (20认同)
  • 我建议对 CURLOPT_POST 使用 `true` 而不是 `1`。 (11认同)
  • @Raptor直接向CURLOPT_POSTFIELDS提供数组,实际上curl会使POST类型略有不同.(期待:100-继续) (5认同)
  • 使用CURLOPT_RETURNTRANSFER意味着curl_exec将响应作为字符串返回而不是输出它. (2认同)

emi*_*mix 230

程序

// 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);
Run Code Online (Sandbox Code Playgroud)

面向对象

<?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;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意:最好创建某种类型的接口AdapterInterface,例如使用getResponse()方法调用,让上面的类实现它.然后,您可以随时将此实现与您喜欢的另一个适配器交换,而不会对您的应用程序产生任何副作用.

使用HTTPS /加密流量

通常在Windows操作系统下PHP中的cURL存在问题.在尝试连接到受https保护的端点时,您会收到错误消息certificate verify failed.

大多数人在这里做的是告诉cURL库简单地忽略证书错误并继续(curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);).由于这将使您的代码工作,您将引入巨大的安全漏洞并使恶意用户能够对您的应用程序执行各种攻击,例如Man In The Middle攻击等.

从来没有这样做过.相反,您只需要修改php.ini并告诉PHP您的CA Certificate文件在哪里让它正确验证证书:

// 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()));
}
Run Code Online (Sandbox Code Playgroud)

最新版本cacert.pem可以从Internet下载或从您喜欢的浏览器中提取.更改任何php.ini相关设置时,请记住重新启动网络服务器.

  • 这应该是公认的答案,因为最好的做法是让HTTP库处理变量的编码. (4认同)
  • 这并非总是如此.我见过Web服务器期望POST变量以某种方式编码,导致它们失败.在我看来,http_build_query()实际上比cURL更可靠. (4认同)
  • 关于POST参数的外观,HTTP规范非常简单.无论如何,网络服务器软件应符合标准. (4认同)
  • 扩展@César的评论,[PHP文档](http://php.net/curl_setopt)明确指出以下内容:"将数组传递给CURLOPT_POSTFIELDS将数据编码为**multipart/form-data**,同时传递URL编码的字符串将数据编码为**application/x-www-form-urlencoded**." 我最近花费了大量的时间来解决为什么cURL调用在第三方端点上失败,最终才意识到他们不支持multipart/form-data. (4认同)

Eri*_*ski 30

使用php curl_exec执行HTTP帖子的实例:

把它放在一个名为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);
?>
Run Code Online (Sandbox Code Playgroud)

然后使用该命令运行它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>
Run Code Online (Sandbox Code Playgroud)

所以你向www.google.com做了一个PHP POST并发送了一些数据.

如果服务器被编程为读取后变量,它可以决定基于此做一些不同的事情.

  • 哦,不,不要尝试自己建立帖子!使用这个:`curl_setopt($ ch,CURLOPT_POSTFIELDS,http_build_query($ fields));` (3认同)
  • -1因为你没有逃避你的邮政变革.OP的示例是发送用户提交的用户名和密码以进行身份​​验证.使用您的解决方案,具有&密码的用户永远无法登录.oriadam的评论是正确的,但您可以省略``http_build_query`,如:`curl_setopt($ ch,CURLOPT_POSTFIELDS,$ fields); (3认同)

Vla*_*pak 24

可以通过以下方式轻松达到:

<?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);
Run Code Online (Sandbox Code Playgroud)


MSS*_*MSS 12

卷曲帖子+错误处理+设置标题[感谢@ 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',
]);
Run Code Online (Sandbox Code Playgroud)


clo*_*xix 10

我很惊讶没有人建议 file_get_contents:

$url = "http://www.example.com";
$parameters = array('username' => 'user1', 'password' => 'passuser1', 'gender' => '1');
$options = array('http' => array(
    'header'  => 'Content-Type: application/x-www-form-urlencoded\r\n',
    'method'  => 'POST',
    'content' => http_build_query($parameters)
));

$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
Run Code Online (Sandbox Code Playgroud)

很简单,很有效;我在可以控制两端代码的环境中使用它。

更好的是,使用 json_decode (并设置您的代码以返回 JSON)

$result = json_decode(file_get_contents($url, false, $context), TRUE);
Run Code Online (Sandbox Code Playgroud)

这种方法会在幕后调用curl,但您不会跳过那么多麻烦。

答案是根据 Stack Overflow 上其他地方的原始答案精炼而成的: PHP 将变量发送到 file_get_contents()


Pej*_*yri 7

1.循序渐进

  • 初始化 cURL 会话:
$url = "www.domain.com";
$ch = curl_init($url);
Run Code Online (Sandbox Code Playgroud)
  • 如果您的请求具有不记名令牌或定义 JSON 内容之类的标头,则必须将HTTPHEADER选项设置为 cURL:
$token = "generated token code";
curl_setopt(
    $ch, 
    CURLOPT_HTTPHEADER, 
    array(
        'Content-Type: application/json', // for define content type that is json
        'bearer: '.$token, // send token in header request
        'Content-length: 100' // content length for example 100 characters (can add by strlen($fields))
    )
);
Run Code Online (Sandbox Code Playgroud)
  • 如果您想在输出中包含标题设置CURLOPT_HEADERtrue
curl_setopt($ch, CURLOPT_HEADER, false);
Run Code Online (Sandbox Code Playgroud)
  • RETURNTRANSFER选项设置true为以字符串形式返回传输而不是直接输出:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
Run Code Online (Sandbox Code Playgroud)
  • 要检查 SSL 对等证书中是否存在通用名称,可以将其设置为0(to not check the names), 1(not supported in cURL 7.28.1), 2(default value and for production mode)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
Run Code Online (Sandbox Code Playgroud)
  • 通过 cURL 将字段作为数组发布:
$fields = array(
    "username" => "user1",
    "password" => "passuser1",
    "gender" => 1
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
Run Code Online (Sandbox Code Playgroud)
  • 执行 cURL 并返回字符串。根据您的资源,这将返回如下输出result=OK
$result = curl_exec($ch);
Run Code Online (Sandbox Code Playgroud)
  • 关闭cURL资源,释放系统资源:
curl_close($ch);
Run Code Online (Sandbox Code Playgroud)

2.作为类使用

  • call_cURL可以扩展的整个类:
class class_name_for_call_cURL {
    protected function getUrl() {
        return "www.domain.com";
    }

    public function call_cURL() {
        $token = "generated token code";

        $fields = array(
            "username" => "user1",
            "password" => "passuser1",
            "gender" => 1
        );

        $url = $this->getUrl();
        $output = $this->_execute($fields, $url, $token);
        
        // if you want to get json data
        // $output = json_decode($output);
            
        if ($output == "OK") {
            return true;
        } else {
             return false;
        }
    }

    private function _execute($postData, $url, $token) {
        // for sending data as json type
        $fields = json_encode($postData);

        $ch = curl_init($url);
        curl_setopt(
            $ch, 
            CURLOPT_HTTPHEADER, 
            array(
                'Content-Type: application/json', // if the content type is json
                'bearer: '.$token // if you need token in header
            )
        );
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

        $result = curl_exec($ch);
        curl_close($ch);

        return $result;
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 使用该类并调用 cURL:
$class = new class_name_for_call_cURL();
var_dump($class->call_cURL()); // output is true/false
Run Code Online (Sandbox Code Playgroud)

3.一个功能

  • 在任何需要的地方使用的功能:
function get_cURL() {

        $url = "www.domain.com";
        $token = "generated token code";

        $postData = array(
            "username" => "user1",
            "password" => "passuser1",
            "gender" => 1
        );

        // for sending data as json type
        $fields = json_encode($postData);

        $ch = curl_init($url);
        curl_setopt(
            $ch, 
            CURLOPT_HTTPHEADER, 
            array(
                'Content-Type: application/json', // if the content type is json
                'bearer: '.$token // if you need token in header
            )
        );
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

        $result = curl_exec($ch);
        curl_close($ch);

        return $result;
}
Run Code Online (Sandbox Code Playgroud)
  • 此功能仅可通过以下方式使用:
var_dump(get_cURL());
Run Code Online (Sandbox Code Playgroud)


Ant*_*ony 6

如果表单使用重定向,身份验证,cookie,SSL(https)或除了完全打开的脚本以外的任何其他期望POST变量,您将开始快速咬牙切齿.看一下Snoopy,它可以完全满足您的需求,同时无需设置大量开销.


Man*_*s D 6

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;
}
Run Code Online (Sandbox Code Playgroud)


Tob*_*nst 5

最简单的是将数据作为 application/json 发送。这会将数组作为输入并将其正确编码为 json 字符串:

$data = array(
    'field1' => 'field1value',
    'field2' => 'field2value',
)

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type:application/json',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resultStr = curl_exec($ch);
return json_decode($resultStr, true);
Run Code Online (Sandbox Code Playgroud)