PHP + कर्ल, HTTP POST नमूना कोड?


490

क्या कोई मुझे दिखा सकता है कि HTTP POST के साथ php कर्ल कैसे करें?

मैं इस तरह से डेटा भेजना चाहता हूं:

username=user1, password=passuser1, gender=1

सेवा www.domain.com

मुझे उम्मीद है कि कर्ल एक प्रतिक्रिया की तरह लौटेगा result=OK। क्या कोई उदाहरण हैं?

जवाबों:


839
<?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 { ... }
?>

47
http_build_query()मापदंडों को संभालने के लिए उपयोग करने की कोई आवश्यकता नहीं है ; बस पास के लिए CURLOPT_POSTFIELDSपर्याप्त है।
रैप्टर

8
@ सीधे CURLOPT_POSTFIELDS को सरणी प्रदान करने वाला कर्ल वास्तव में POST का थोड़ा अलग प्रकार बनाता है। (उम्मीद: 100-जारी)
ओलेग पोपोव

22
यदि मान CURLOPT_POSTFIELDSएक सरणी है, तो इसके बजाय Content-Typeहेडर सेट किया multipart/form-dataजाएगा application/x-www-form-urlencodedphp.net/manual/en/function.curl-setopt.php
क्लो

2
CURLOPT_RETURNTRANSFER का उपयोग करने का अर्थ है कि curl_exec इसे आउटपुट करने के बजाय स्ट्रिंग के रूप में प्रतिक्रिया लौटाएगा।
bnp887

2
मैं उपयोग करने का सुझाव trueके बजाय 1के लिए CURLOPT_POST
फ्लोरेसेंटग्रीन 5

260

प्रक्रियात्मक

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

वस्तु के उन्मुख

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

प्रयोग

// 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()));
}

यहाँ ध्यान दें: यह विधि के AdapterInterfaceसाथ उदाहरण के लिए बुलाया इंटरफ़ेस के कुछ प्रकार बनाने के लिए सबसे अच्छा होगा getResponse()और कक्षा को इसे लागू करने दें। फिर आप अपने आवेदन के किसी भी साइड इफेक्ट के बिना, इस कार्यान्वयन को हमेशा अपने जैसे किसी अन्य एडाप्टर के साथ स्वैप कर सकते हैं।

HTTPS / एन्क्रिप्टिंग ट्रैफ़िक का उपयोग करना

आमतौर पर विंडोज ऑपरेटिंग सिस्टम के तहत PHP में cURL के साथ एक समस्या है। Https संरक्षित एंडपॉइंट से कनेक्ट करने का प्रयास करते समय, आपको एक त्रुटि मिलेगी जो आपको बता रही है certificate verify failed

ज्यादातर लोग यहां क्या करते हैं, यह बताने के लिए कि CURL लाइब्रेरी को केवल प्रमाणपत्र त्रुटियों को अनदेखा करना और जारी रखना ( curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);) है। जैसा कि यह आपके कोड को काम करेगा, आप भारी सुरक्षा छेद का परिचय देते हैं और दुर्भावनापूर्ण उपयोगकर्ताओं को आपके ऐप पर विभिन्न हमलों को करने में सक्षम बनाते हैं जैसे मैन इन द मिडिल अटैक या ऐसे।

कभी नहीं, कभी ऐसा करो। इसके बजाय, आपको बस अपने को संशोधित करने php.iniऔर पीएचपी CA Certificateको यह बताने की आवश्यकता है कि आपकी फ़ाइल को सही तरीके से प्रमाण पत्र सत्यापित करने की अनुमति है:

; modify the absolute path to the cacert.pem file
curl.cainfo=c:\php\cacert.pem

नवीनतम cacert.pemको इंटरनेट से डाउनलोड किया जा सकता है या अपने पसंदीदा ब्राउज़र से निकाला जा सकता है । किसी भी php.iniसंबंधित सेटिंग्स को बदलते समय अपने वेबसर्वर को पुनः आरंभ करना याद रखें।


4
यह वास्तव में स्वीकृत उत्तर होना चाहिए, क्योंकि HTTP लाइब्रेरी को अपने चरों की एन्कोडिंग को संभालने के लिए सबसे अच्छा अभ्यास होगा।
एरिक सस्टैंडैंड

4
ऐसी स्थिति हर बार नहीं होती है। मैंने ऐसे वेब सर्वर देखे हैं जो उम्मीद करते हैं कि POST चर एक निश्चित तरीके से एन्कोडेड होंगे, जिससे वे अन्यथा विफल हो जाएंगे। यह मुझे लगता है कि http_build_query () वास्तव में इसके लिए cURL से अधिक विश्वसनीय है।
सेसर

4
HTTP का आशय इस बात पर बहुत सीधा है कि POST पैरामीटर कैसे दिखना चाहिए। वेबसर्वर सॉफ्टवेयर को वैसे भी मानकों का पालन करना चाहिए।
एमिक्स

1
इस तरह से उपयोग करके आप CURL को थोड़े अलग प्रकार के POST का उपयोग करने के लिए बाध्य करेंगे। (उम्मीद: 100-जारी)। इस लेख की जाँच करें: support.urbanairship.com/entries/…
ओलेग पोपोव

5
@ César की टिप्पणी पर विस्तार करते हुए, PHP प्रलेखन स्पष्ट रूप से निम्नलिखित नोट करता है: "CURLOPT_POSTFIELDS के लिए एक सरणी पास करना डेटा को मल्टीपार्ट / फॉर्म-डेटा के रूप में एन्कोड करेगा , जबकि एक URL-एनकोड स्ट्रिंग पास करने से डेटा को एप्लिकेशन / x-www-form के रूप में एन्कोड किया जाएगा। -लुरलकोडेड । ”। मैंने हाल ही में एक असुविधाजनक समय बिताया है कि एक समस्या को सुलझाने के लिए तीसरे पक्ष के समापन बिंदु पर विफल क्यों हो रहा है केवल अंततः यह महसूस करने के लिए कि वे मल्टीपार्ट / फॉर्म-डेटा का समर्थन नहीं करते हैं।
जेक जेड

31

HTTP पोस्ट करने के लिए php curl_exec का उपयोग करने का एक जीवंत उदाहरण:

इसे 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);
?>

फिर इसे कमांड के साथ चलाएं 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>

इसलिए आपने www.google.com पर एक PHP POST किया और इसे कुछ डेटा भेजा।

यदि सर्वर को पोस्ट वेरिएबल्स में पढ़ने के लिए प्रोग्राम किया गया था, तो यह उसके आधार पर कुछ अलग करने का निर्णय ले सकता है।


$postvars .= $key . $value;चाहिए $postvars .= $key . $value ."&";या नहीं?
मानवल

इस उत्तर को फिर से देखते हुए, आप अपने कस्टम क्वेरी स्ट्रिंग कनवर्टर कार्यान्वयन को http_build_query के साथ बदल सकते हैं , बस इसे $fieldsसरणी दें और यह क्वेरी स्ट्रिंग आउटपुट करेगा।

इस बात से अवगत रहें कि आपको अपना डेटा सुरक्षित रूप से जमा करने के लिए एनकोड करना चाहिए।
wtf8_decode

3
अरे नहीं पोस्ट स्ट्रिंग बनाने की कोशिश मत करो! इसका उपयोग करें:curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
oriadam

3
-1 क्योंकि आप अपने पोस्ट वेरिएंट से बच नहीं रहे हैं। ओपी का उदाहरण प्रमाणीकरण के लिए उपयोगकर्ता द्वारा प्रस्तुत उपयोगकर्ता नाम और पासवर्ड भेज रहा है। आपके समाधान के साथ, उनके पासवर्ड में & के साथ एक उपयोगकर्ता कभी भी लॉग इन नहीं कर पाएगा; ओरिदम की टिप्पणी सही है, लेकिन आप इसे छोड़ सकते हैं http_build_queryजैसे:curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
एरिक सस्टैंडैंड

26

इसके साथ आसानी से पहुँचा जा सकता है:

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

13

कर्ल पोस्ट + त्रुटि हैंडलिंग + सेट हेडर [@ 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',
]);

आपका कोड हैंडल और फ्री संसाधनों को बंद नहीं करेगा, क्योंकि आप एक अपवाद को फेंकने के बाद curl_close करते हैं। आपको आखिरकार ब्लॉक के अंदर कर्ल_क्लोज करना चाहिए।
एमिक्स

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

1
आपका कोड हैंडल और फ्री संसाधनों को बंद नहीं करेगा, क्योंकि आप एक अपवाद को फेंकने के बाद curl_close करते हैं। आपको curl_closeएक finallyब्लॉक के अंदर होना चाहिए ।
एमिक्स

6

अगर फॉर्म रीडायरेक्ट, ऑथेंटिकेशन, कुकीज, एसएसएल (https), या पूरी तरह से ओपन स्क्रिप्ट के अलावा कुछ और उपयोग कर रहा है, जो कि POST वैरिएबल की अपेक्षा रखते हैं, तो आप अपने दांतों को वास्तव में जल्दी से समेटने लगेंगे। स्नोपॉपी पर एक नज़र डालें , जो ओवरहेड के बहुत से सेट करने की आवश्यकता को हटाते समय आपके दिमाग में वही करता है जो आप करते हैं।


यदि आप स्टॉक लिब के साथ रहना चाहते हैं, तो बस जोड़ने की कोशिश करेंcurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
MarkHu

केवल नकारात्मक पक्ष यह है कि आपको अभी भी कुकी जार और अन्य संभावित मुद्दों (जैसे चाहे अनुप्रेषितों का पालन करना हो, गैर HTTP- आधारित प्रमाणीकरण, आदि से कैसे निपटना है) से निपटना होगा। 6 साल बाद, मैं उस विशिष्ट पुस्तकालय के बजाय एक "हेडलेस-ब्राउज़र" की अधिक सामान्य अवधारणा की सिफारिश करूंगा (या स्रोत पर कुछ भी, कैसे दिनांकित, सही?) और जब मैं आम तौर पर सीधे कर्ल विकल्पों से निपटता हूं, तब भी मैं सलाह दूंगा पीएसआर -7 संगत है कि एक हेडलेस-ब्राउज़र लाइब्रेरी को देखना (सिरदर्द से बचने के लिए केवल एक ही मैं जानता हूं)।
एंथनी

3

एक सरल उत्तर यदि आप अपनी वेबसाइट पर जानकारी दे रहे हैं, तो एक सेशन चर का उपयोग करना है। इसके साथ php पेज शुरू करें:

session_start();

यदि कुछ बिंदु पर ऐसी जानकारी है, जिसे आप PHP में जनरेट करना चाहते हैं और सत्र में अगले पेज पर जाना है, तो POST वेरिएबल का उपयोग करने के बजाय, इसे SESSION वैरिएबल पर असाइन करें। उदाहरण:

$_SESSION['message']='www.'.$_GET['school'].'.edu was not found.  Please try again.'

फिर अगले पेज पर आप इस सत्र चर को देखें। नोट: जब आप इसका उपयोग करते हैं, तो सुनिश्चित करें कि आप इसे नष्ट कर देते हैं, इसलिए इसका उपयोग किए जाने के बाद यह जारी नहीं रहता है:

if (isset($_SESSION['message'])) {echo $_SESSION['message']; unset($_SESSION['message']);}

3

यहाँ PHP + कर्ल के लिए कुछ बॉयलरप्लेट कोड दिए गए हैं http://www.webbotsspidersscreenscrapers.com/DSP_dh.pp

इन लाइब्रेरी में शामिल करने से विकास सरल होगा

<?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, "");
    ...
?>

2

यदि आप कुकीज़ वाली साइट पर लॉगिन करने की कोशिश करते हैं।

यह कोड:

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

यदि आप लॉगिन करने का प्रयास करते हैं तो काम नहीं कर सकता है, क्योंकि कई साइटें स्थिति 200 पर लौटती हैं, लेकिन पोस्ट सफल नहीं है।

यह जांचने का आसान तरीका है कि लॉगिन पोस्ट सफल है या नहीं, यदि यह फिर से कुकीज़ सेट कर रहा है तो जांच लें। यदि आउटपुट में सेट-कुकीज़ स्ट्रिंग है, तो इसका मतलब है कि पोस्ट सफल नहीं हैं और यह नया सत्र शुरू करता है।

साथ ही पद सफल हो सकता है, लेकिन स्थिति 200 के बजाय पुनर्निर्देशित हो सकती है।

यह सुनिश्चित करने के लिए कि पोस्ट सफल है, यह कोशिश करें:

पोस्ट के बाद स्थान का पालन करें, इसलिए यह उस पृष्ठ पर जाएगा जहां पोस्ट रीडायरेक्ट करता है:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

और जाँच करें कि क्या नए कुकीज़ अनुरोध में मौजूद हैं:

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

{echo 'post successful'; }

else { echo 'not successful'; }

1

फॉर्म और कच्चे डेटा भेजने के उदाहरण :

$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);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.