有人能告诉我如何用HTTP POST做一个PHP cURL吗?

我想这样发送数据:

username=user1, password=passuser1, gender=1

到www.example.com

我希望cURL返回result=OK这样的响应。有什么例子吗?


当前回答

我很惊讶没有人建议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);

这很简单,很有效;我把它用在两端都能控制代码的环境中。

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

$result = json_decode(file_get_contents($url, false, $context), TRUE);

这种方法在幕后调用curl,但不需要经历那么多困难。

从Stack Overflow上其他地方的原始答案提炼出来的答案: PHP将变量发送到file_get_contents()

其他回答

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

发送表单和原始数据的示例:

$curlHandler = curl_init();

curl_setopt_array($curlHandler, [
    CURLOPT_URL => 'https://postman-echo.com/post',
    CURLOPT_RETURNTRANSFER => true,

    /**
     * Specify POST method
     */
    CURLOPT_POST => true,

    /**
     * Specify array of form fields
     */
    CURLOPT_POSTFIELDS => [
        'foo' => 'bar',
        'baz' => 'biz',
    ],
]);

$response = curl_exec($curlHandler);

curl_close($curlHandler);

echo($response);

1.一步一步

初始化cURL会话:

$url = "www.domain.com";
$ch = curl_init($url);

如果你的请求有报头,如承载令牌或定义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))
    )
);

如果你想在输出中包含报头,将CURLOPT_HEADER设置为true:

curl_setopt($ch, CURLOPT_HEADER, false);

设置RETURNTRANSFER选项为true以字符串形式返回传输,而不是直接输出:

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

要检查SSL对端证书中是否存在公共名称,可以设置为0(不检查名称)、1(cURL 7.28.1中不支持)、2(默认值,用于生产模式):

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

对于cURL将字段作为数组发布:

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

执行cURL并返回字符串。根据你的资源,这将返回类似result=OK的输出:

$result = curl_exec($ch);

关闭cURL资源,释放系统资源:

curl_close($ch);

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

使用类并调用cURL:

$class = new class_name_for_call_cURL();
var_dump($class->call_cURL()); // output is true/false

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

这个函数可以通过以下方式使用:

var_dump(get_cURL());

如果你试图用cookies登录网站。

这段代码:

if ($server_output == "OK") { ... } else { ... }

如果您尝试登录,它可能无法工作,因为许多网站返回状态200,但发布不成功。

检查登录帖子是否成功的简单方法是检查它是否再次设置cookie。如果在输出中有一个Set-Cookies字符串,这意味着帖子没有成功,它开始一个新的会话。

同样,帖子可以成功,但是状态可以重定向,而不是200。

为了确保帖子成功,试试下面的方法:

Follow location在post之后,所以它会转到post重定向到的页面:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

然后检查请求中是否存在新的cookie:

if (!preg_match('/^Set-Cookie:\s*([^;]*)/mi', $server_output)) 

{echo 'post successful'; }

else { echo 'not successful'; }

如果表单使用重定向、身份验证、cookie、SSL (https)或其他任何东西,而不是期望POST变量的完全开放脚本,那么您将很快开始咬牙切齿。看看Snoopy,它完全按照您的想法来做,而且不需要设置大量的开销。