PHP + kıvırmak, HTTP POST örnek kodu?


491

Herkes bana nasıl bir HTTP POST ile bir php curl yapmak gösterebilir?

Bunun gibi veri göndermek istiyorum:

username=user1, password=passuser1, gender=1

için www.domain.com

Kıvırmak gibi bir yanıt dönmesini bekliyoruz result=OK. Örnek var mı?

Yanıtlar:


840
<?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()parametreleri işlemek için kullanmaya gerek yoktur ; diziyi geçmek CURLOPT_POSTFIELDSyeterlidir.
Raptor

8
@Raptor doğrudan CURLOPT_POSTFIELDS dizisini sağlayan aslında kıvrılma biraz farklı POST yapar. (Beklenti: 100-devam ediyor)
Oleg Popov

22
Ayrıca değeri CURLOPT_POSTFIELDSbir dizi ise, Content-Typebaşlık multipart/form-datayerine olarak ayarlanır application/x-www-form-urlencoded. php.net/manual/tr/function.curl-setopt.php
Chloe

2
CURLOPT_RETURNTRANSFER kullanmak curl_exec öğesinin yanıtı çıktılamak yerine dize olarak döndüreceği anlamına gelir.
bnp887

2
Ben trueyerine 1for kullanmanızı öneririm CURLOPT_POST.
FluorescentGreen5

261

Usul

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

Nesne odaklı

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

kullanım

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

Yan not burada: AdapterInterfaceörneğin getResponse()yöntemle adlandırılan bir çeşit arabirim oluşturmak ve yukarıdaki sınıfın onu uygulamasına izin vermek en iyisidir . Ardından, uygulamanızın herhangi bir yan etkisi olmadan bu uygulamayı istediğiniz gibi başka bir adaptörle değiştirebilirsiniz.

HTTPS kullanma / trafiği şifreleme

Genellikle Windows işletim sistemi altında PHP'de cURL ile ilgili bir sorun vardır. Bir https korumalı uç noktaya bağlanmaya çalışırken, bunu söyleyen bir hata alırsınız certificate verify failed.

Çoğu insanın burada yaptığı şey, cURL kütüphanesine sadece sertifika hatalarını göz ardı etmesini ve devam etmesini söylemektir ( curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);). Bu, kodunuzun çalışmasını sağlayacağından, büyük güvenlik açığı sağlar ve kötü niyetli kullanıcıların uygulamanızda Man In The Middle saldırısı veya benzeri çeşitli saldırılar gerçekleştirmesini sağlarsınız .

Asla, asla yapma. Bunun yerine, yalnızca sertifikanızı doğrulaması php.iniiçin CA Certificatedosyanızı değiştirmeniz ve PHP'ye dosyanızın nerede olduğunu söylemeniz yeterlidir :

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

En son cacert.pemInternet'ten indirilebilir veya favori tarayıcınızdan çıkarılabilir . php.iniİlgili ayarları değiştirirken web sunucunuzu yeniden başlatmayı unutmayın.


4
Bu gerçekten kabul edilen cevap olmalıdır, çünkü en iyi uygulama, HTTP kütüphanesinin değişkenlerinizin kodlamasını işlemesine izin vermektir.
Eric Seastrand

4
Bu her zaman böyle değildir. POST değişkenlerinin belirli bir şekilde kodlanmasını bekleyen web sunucularını gördüm, aksi halde başarısız olmalarına neden oldum. Bana öyle geliyor ki http_build_query () aslında bunun için cURL'den daha güvenilir.
César

4
HTTP spesifikasyonu POST parametrelerinin nasıl olması gerektiği konusunda oldukça basittir. Web sunucusu yazılımı yine de standartlara uygun olmalıdır.
emix

1
Bu şekilde cURL'u biraz farklı POST türü kullanmaya zorlayacaksınız. (Beklenti: 100-devam). Bu makaleye göz atın: support.urbanairship.com/entries/…
Oleg Popov

5
@ César'un yorumuna genişleyen PHP belgeleri aşağıdakileri açık bir şekilde not eder: "Bir diziyi CURLOPT_POSTFIELDS dosyasına geçirmek, verileri çoklu bölüm / form verileri olarak kodlarken, URL kodlu bir dizeyi geçmek verileri application / x-www-form olarak kodlar -ürlen kodlanmış . " Kısa bir süre önce, bir cURL çağrısının neden üçüncü taraf uç noktasında neden başarısız olduğunu sorun gidermeye çalışmak için çok fazla zaman harcadım ve sonunda çok parçalı / form verilerini desteklemediğini anladım.
Jake Z

31

HTTP yayını yapmak için php curl_exec kullanımına canlı bir örnek:

Bunu foobar.php adlı bir dosyaya koyun:

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

Sonra komutla çalıştırın php foobar.php, bu tür çıktıları ekrana döker:

<!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>

Böylece www.google.com adresine bir PHP POST yaptınız ve bazı veriler gönderdiniz.

Sunucu değişkenleri okumak için programlanmış olsaydı, buna bağlı olarak farklı bir şey yapmaya karar verebilirdi.


$postvars .= $key . $value;should $postvars .= $key . $value ."&";ya da değil?
Manwal

Bu cevaba tekrar baktığınızda, özel sorgu dizesi dönüştürücü uygulamanızı http_build_query ile de değiştirebilirsiniz , sadece $fieldsdiziyi verin ve bir sorgu dizesi çıktısı alın.

Güvenli bir şekilde gönderilebilmesi için verilerinizi kodlamanız gerektiğini unutmayın.
wtf8_decode

3
Oh hayır yazı dizesini kendiniz oluşturmaya çalışmayın! Bunu kullanın:curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
oriadam

3
-1 gönderi kaçan değil çünkü vars var. OP'nin örneği kimlik doğrulaması için kullanıcı tarafından gönderilen kullanıcı adlarını ve şifreleri göndermektir. Çözümünüzle, şifresi olan bir kullanıcı asla giriş yapamaz. Oriadam'ın yorumu doğrudur, ancak şöyle bırakabilirsiniz http_build_query:curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
Eric Seastrand

26

Kolayca şununla erişilebilir:

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

Kıvrılma Sonrası + Hata İşleme + Üstbilgileri Ayarla [@ mantas-d sayesinde]:

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',
]);

Kodunuz tanıtıcıyı ve serbest kaynakları kapatmaz, çünkü bir istisna attıktan sonra curl_close. Sonunda bir blok içinde curl_close gerekir.
emix

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
Kodunuz tanıtıcıyı ve serbest kaynakları kapatmaz, çünkü bir istisna attıktan sonra curl_close. curl_closeBir finallybloğun içinde olmalısın .
emix

6

Form yeniden yönlendirmeler, kimlik doğrulama, çerezler, SSL (https) veya POST değişkenlerini bekleyen tamamen açık bir komut dosyası dışında bir şey kullanıyorsa, dişlerinizi gerçekten hızlı bir şekilde gıcırdatmaya başlayacaksınız. Bir sürü ek yük kurma ihtiyacını ortadan kaldırırken aklınızdakileri tam olarak yapan Snoopy'ye bir göz atın .


Eğer hisse senedi lib ile sopa istiyorsanız, sadece eklemeyi deneyincurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
MarkHu

Tek dezavantajı, yine de bir çerez kavanozu ve diğer potansiyel sorunları (yeniden yönlendirmeleri takip edip etmeme, HTTP tabanlı olmayan kimlik doğrulama ile nasıl başa çıkılacağı vb.) Ayarlamakla uğraşmanız gerektiğidir. 6 yıl sonra, belirli bir kütüphane (veya sourceforge'daki herhangi bir şey, nasıl tarihli, doğru?) Yerine daha genel bir "başsız tarayıcı" konseptini öneririm ve genellikle doğrudan kıvrılma seçenekleri ile uğraşırken, yine de tavsiye ederim baş ağrısından kaçınmak için PSR-7 uyumlu başsız tarayıcı kütüphanesine bakarken (Guzzle elden tanıdığım tek kişi).
Anthony

3

Kendi web sitenize bilgi aktarıyorsanız, daha basit bir cevap SESSION değişkeni kullanmaktır. Php sayfası ile başlayın:

session_start();

Bir noktada PHP'de oluşturmak ve POST değişkeni kullanmak yerine oturumdaki sonraki sayfaya geçmek istediğiniz bilgiler varsa, bunu bir SESSION değişkenine atayın. Misal:

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

Sonra bir sonraki sayfada bu SESSION değişkenine başvurmanız yeterlidir. NOT: kullandıktan sonra, yok ettiğinizden emin olun, bu yüzden kullanıldıktan sonra da devam etmez:

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

3

İşte PHP + kıvırmak için bazı kaynak kodu http://www.webbotsspidersscreenscrapers.com/DSP_download.php

bu kütüphaneye dahil etmek gelişmeyi kolaylaştıracak

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

Sitede çerezlerle giriş yapmaya çalışırsanız.

Bu kod:

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

Giriş yapmayı denediğinizde çalışmayabilir, çünkü birçok site 200 durumunu döndürür, ancak gönderi başarılı olmaz.

Giriş mesajının başarılı olup olmadığını kontrol etmenin kolay yolu, çerezleri tekrar ayarlayıp ayarlamadığını kontrol etmektir. Çıktıda Set-Cookies dizesi varsa, bu mesajların başarılı olmadığı ve yeni oturum başlatıldığı anlamına gelir.

Ayrıca gönderi başarılı olabilir, ancak durum 200 yerine yeniden yönlendirilebilir.

Gönderinin başarılı olduğundan emin olmak için şunu deneyin:

Gönderinin ardından konumu takip et, böylece yayının yönlendirildiği sayfaya gidecektir:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

Ve istekte yeni çerezlerin mevcut olup olmadığını kontrol etmeden:

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

{echo 'post successful'; }

else { echo 'not successful'; }

1

Form ve ham veri gönderme örnekleri :

$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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.