CURLOPT_POSTFIELDS için curl POST biçimi


99

curlVia POSTve set kullandığımda CURLOPT_POSTFIELD, urlencodeya da herhangi bir özel format gerekir mi?

örneğin: 2 alan göndermek istersem, ilk ve son:

first=John&last=Smith

curl ile kullanılması gereken tam kod / format nedir?

$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$reply=curl_exec($ch);
curl_close($ch);

Yanıtlar:


100

Bir dize gönderiyorsanız, urlencode (). Aksi takdirde dizi ise, anahtar => değer eşleşmeli ve Content-typebaşlık otomatik olarak olarak ayarlanmalıdır multipart/form-data.

Ayrıca, dizileriniz için sorgu oluşturmak için fazladan işlevler oluşturmanız gerekmez, zaten buna sahipsiniz:

$query = http_build_query($data, '', '&');

13
Sadece kullanabilirsiniz http_build_query($data)beri &varsayılan ayırıcı olduğunu.
nullability

6
Tabii ki onları atlayabilirsiniz. Bu, özel ihtiyaçlarınıza uyacak şekilde değiştirebileceğiniz (veya değiştirmeyebileceğiniz) (örneğin varsayılan ayırıcı) diğer iki argümanı göstermek içindir.
kodeart

62

DÜZENLEME : php5'ten itibaren, aşağıdakilerin kullanılması http_build_queryönerilir:

string http_build_query ( mixed $query_data [, string $numeric_prefix [, 
                          string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )

Kılavuzdan basit bir örnek:

<?php
$data = array('foo'=>'bar',
              'baz'=>'boom',
              'cow'=>'milk',
              'php'=>'hypertext processor');

echo http_build_query($data) . "\n";

/* output:
foo=bar&baz=boom&cow=milk&php=hypertext+processor
*/

?>

php5'ten önce:

Gönderen manuel :

CURLOPT_POSTFIELDS

Bir HTTP "POST" işleminde gönderilecek tüm veriler. Bir dosya göndermek için dosya adının başına @ ekleyin ve tam yolu kullanın. Dosya türü, dosya adı '; tür = mimetype' biçimindeki türle izlenerek açıkça belirtilebilir. Bu parametre ya 'para1 = val1 & para2 = val2 & ...' gibi urlencoded bir dize olarak ya da anahtar olarak alan adı ve değer olarak alan verisi olan bir dizi olarak geçirilebilir. Değer bir diziyse, Content-Type başlığı multipart / form-data olarak ayarlanacaktır. PHP 5.2.0'dan itibaren, bu seçeneğe @ öneki ile aktarılan dosyaların çalışması için dizi biçiminde olması gerekir.

Öyleyse bunun gibi bir şey mükemmel çalışmalıdır (ilişkilendirilebilir bir dizide geçirilen parametrelerle):

function preparePostFields($array) {
  $params = array();

  foreach ($array as $key => $value) {
    $params[] = $key . '=' . urlencode($value);
  }

  return implode('&', $params);
}

11
Bir dizi geçirebiliyorsanız neden bir dizge iletirsiniz ...?
ThiefMaster

1
Bence, "ad ve soyad" vb. Gibi olması durumunda, $ key de kodlanmalıdır. Özellikle de veriler son kullanıcı tarafından veriliyorsa
Marius Balčytis

2
@barius, sana katılıyorum. Ve bence http_build_query () aslında yukarıda tanımlanan fonksiyondan daha iyi.
skyfree

1
@skyfree Kabul ediyorum! Bu işlev
php5'e

1
diziyi geçirebildiğiniz halde neden http_build_query gereklidir?
Offenso

39

Bir dizeyi hiç geçirmeyin!

Bir dizi geçirebilir ve php / curl'nin kodlama vb. Kirli işleri yapmasına izin verebilirsiniz.


16
Bir diziyi geçirmek dizgeden farklı bir İçerik türü olacaktır, bu yüzden bunu yapmak için iyi bir neden vardır. Bunu anlamam biraz zaman aldı.
Thomas Vander Stichele

Nedeni hakkında hiçbir fikrim yok, ancak kazan geliştirici bilgisayarımda bir diziyi geçirmenin yaklaşık bir saniye daha uzun sürdüğünü görüyorum (dizi kullanarak 1.029s http_build_query(), aynı dizide 0.016s kullanarak )
kratenko

2
İç içe diziler çalışmaz. cURL bunları dizeye dönüştürmeyi deneyecek ve bir PHP Dizisini dizeye dönüştürme bildirimi izleyecek
7ochem


4

Çünkü CURLOPT_POSTFIELDSparametreler, urlencoded string gibi para1=val1&para2=val2&..veya anahtar olarak alan adı ve değer olarak alan verisi olan bir dizi olarak aktarılabilir.

Aşağıdaki biçimi deneyin:

$data = json_encode(array(
"first"  => "John",
"last" => "Smith"
));

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);

2
Merhaba Shraddha, json_encode()size geçerli bir parametre dizesinden gerçekten farklı bir şey verecektir first=John&last=Smith. json_encode()çıktı: {"first":"John","last":"Smith"}daha sonra POST isteğinizin ham gövdesi olur.
7ochem

1
@ 7ochem'in açıklamasına eklemek için: Alıcı do yerine json ile kodlanmış bir dize içeren tek bir parametre beklemiyorsa . Bu, "&" ile ayrılmış parametreleri içeren beklenen "url kodlamalı dizeyi" oluşturur. json_encode(...)http_build_query(...)
ToolmakerSteve

4

Burada henüz bahsedilmeyen bir diğer önemli fark, CURLOPT_POSTFIELDSiç içe dizilerin işlenememesidir.

İç içe diziyi alırsak, ['a' => 1, 'b' => [2, 3, 4]]bu şekilde parametreleştirilmelidir a=1&b[]=2&b[]=3&b[]=4( [ve ]URL kodlamalı / kodlanmalıdır). Bu, diğer uçta otomatik olarak iç içe geçmiş bir diziye dönüştürülecektir (burada diğer ucun da PHP olduğunu varsayarsak).

Bu çalışacak:

var_dump(http_build_query(['a' => 1, 'b' => [2, 3, 4]]));
// output: string(36) "a=1&b%5B0%5D=2&b%5B1%5D=3&b%5B2%5D=4"

Bu işe yaramayacak:

curl_setopt($ch, CURLOPT_POSTFIELDS, ['a' => 1, 'b' => [2, 3, 4]]);

Bu size bir uyarı verecektir. Kod yürütme devam edecek ve uç noktanız parametreyi bdize olarak alacak "Array":

PHP Bildirimi: Diziye dönüştürme ... on line ...


3

Bağlıdır content-type

url kodlu veya çok parçalı / form verisi

Bir tarayıcının bir formda yapacağı gibi, verileri standart yolla göndermek için, sadece bir ilişkilendirilebilir dizi iletin . PHP'nin el kitabında belirtildiği gibi:

Bu parametre, 'para1 = val1 & para2 = val2 & ...' gibi urlencoded bir dize olarak veya anahtar olarak alan adı ve değer olarak alan verisi olan bir dizi olarak aktarılabilir. Değer bir diziyse, Content-Type başlığı multipart / form-data olarak ayarlanacaktır.

JSON kodlaması

Bununla birlikte, JSON API'leriyle iletişim kurarken POST verilerimizi anlamak için API için içerik JSON olarak kodlanmalıdır.

Bu tür durumlarda, içerik açıkça JSON olarak kodlanmalıdır:

CURLOPT_POSTFIELDS => json_encode(['param1' => $param1, 'param2' => $param2]),

JSON haberleşirken, aynı zamanda, genellikle ayarlanır acceptve content-typebaşlıkları buna göre:

CURLOPT_HTTPHEADER => [
    'accept: application/json',
    'content-type: application/json'
]

2

iç içe diziler için şunları kullanabilirsiniz:

$data = [
  'name[0]' = 'value 1',
  'name[1]' = 'value 2',
  'name[2]' = 'value 3',
  'id' = 'value 4',
  ....
];

0

İlginç bir şekilde Postman'ın POST yapma şekli, bu 2 ek seçenekle eksiksiz bir GET işlemidir:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, '');

Sadece başka bir yol ve çok iyi çalışıyor.


-3

Bu cevabı bulmam da sonsuza kadar sürdü. Yapmanız gereken tek şeyin URL'yi (dosya adı ve uzantısından sonra '?') URL kodlu sorgu dizesiyle birleştirmek olduğunu keşfettim. POST cURL seçeneklerini ayarlamanız gerekmiyor gibi görünüyor. Aşağıdaki sahte örneğe bakın:

//create URL
$exampleURL = 'http://www.example.com/example.php?';

// create curl resource
$ch = curl_init(); 

// build URL-encoded query string
$data = http_build_query(
    array('first' => 'John', 'last' => 'Smith', '&'); // set url
curl_setopt($ch, CURLOPT_URL, $exampleURL . $data); 

// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

// $output contains the output string
$output = curl_exec($ch); 

// close curl resource to free up system resources <br/>
curl_close($ch);

Ayrıca şunları da kullanabilirsiniz file_get_contents():

// read entire webpage file into a string
$output = file_get_contents($exampleURL . $data);

9
POST yerine bir GET yapıyormuşsunuz gibi görünüyor.
grandnasty
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.