CURL ve PHP kullanarak aynı anahtar ve dosya yüklemeleri için birden çok değer Karıştırma

8 Cevap php

Ben PHP için cURL bağları bir sınırlama içine koşuyoruz. Bu postFields için aynı anahtar için aynı birden çok değer göndermek için kolay bir yolu yoktur görünür. Bunun için rastlamak geçici çözümlerden çoğu el tag = foo & etiketi ile kodlanmış URL sonrası alanları oluşturarak yer var = yerine CURLOPT_POSTFIELDS bir ilişkisel dizi sürümünü kullanmanın bar & tag = baz).

Ben bir şey kaçırmış olmalı gibi pek hissediyorum desteklemek gerekiyor oldukça yaygın bir şey gibi görünüyor. Bu gerçekten aynı anahtar için birden çok değer işlemek için tek yolu var mı?

Bu geçici çözüm (gerçekten sinir bozucu değil ise) uygulanabilir kabul edilebilir olsa da, benim asıl sorun aynı anahtar için birden fazla değer yapmak ve ayrıca dosya yükleme desteklemek gerekiyor olmasıdır. Bildiğim kadarıyla söyleyebilirim, dosya yükleme daha fazla veya daha az CURLOPT_POSTFIELDS arasında ortak arravy sürümünü kullanmayı gerektirir. Ben şaşırıp gibi Yani ben hissediyorum.

Birisi bu konuda bazı fikirler var olduğu umuduyla cURL PHP posta listesinde daha ayrıntılı olarak bu sorun hakkında posted var.

Bu konuda daha fazla bilgi için bakabilirsiniz nerede Öneriler veya ipuçları büyük takdir!

8 Cevap

Ben multipart / form-data ile özel bir CURLOPT_POSTFIELDS dizesi oluşturmak için kendi işlevini yazma sona erdi. Ne bir ağrı.

function curl_setopt_custom_postfields($ch, $postfields, $headers = null) {
    // $postfields is an assoc array.
    // Creates a boundary.
    // Reads each postfields, detects which are @files, and which values are arrays
    // and dumps them into a new array (not an assoc array) so each key can exist
    // multiple times.
    // Sets content-length, content-type and sets CURLOPT_POSTFIELDS with the
    // generated body.
}

Ben böyle, bu yöntemi kullanmak mümkün:

curl_setopt_custom_postfields($ch, array(
    'file' => '@/path/to/file',
    'tag' => array('a', 'b', 'c'),
));

Ben CURLOPT_HTTPHEADER yığınları belirli değilim, bu nedenle bu yöntem çağırır beri, ben fonksiyon gerekirse additonal başlıklarını belirtmek için kullanıcı için izin vereceğini belirli yaptı.

Ben mevcut tam kodu var in this blog post.

Eğer adı tag[] yerine tag kullanın, PHP will generate an array Eğer, diğer bir deyişle, çok için

tag=foo&tag=bar&tag=baz

İhtiyacınız

tag[]=foo&tag[]=bar&tag[]=baz

Iletim için urlencoded bu olması gerektiğini not

tag%5B%5D=foo&tag%5B%5D=bar&tag%5B%5D=baz

Ben bir anahtar (veya aynı anahtar) birden değerler için kurulan standart böyle form elemanları opsiyon listeleri birden fazla seçim için olduğu gibi, bir ayırıcı ile birleştirilmiş olması olduğunu düşünüyorum. Ben bu ayraç sekme karakteri (\t) veya boru sembolü olduğuna inanıyorum (|).

Keyname ile sona ererse [] (gibi tag[]), PHP otomatik olarak size kolaylık sağlamak için bir diziye değerleri dönüştürmek olacaktır.

Limbus ve paul, sizin girişi için teşekkür ederiz.

Ben ben ilanıyla formu üzerinde denetim olsaydı, muhtemelen bu soruna alternatif bir çözüm bulabiliriz. Ancak, form üzerinde herhangi bir kontrol yok. Ve ben yazı okuma yazılımı PHP değildir ve etiket [] standartlara uymayanlar neredeyse olumlu duyuyorum.

Eğer olsaydı bile, cURL ya etiket [] sözdizimi itaat görünmüyor. Temelde, ben aşağıdaki denedim ve hiçbiri çalıştı ...

curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => '@/pathtofile', 'tag[]' => array('a', 'b', 'c'));

curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => '@/pathtofile', 'tag' => array('a', 'b', 'c'));

Ve yine, ben [] etiketini geçen Aslında 'etiketi []' tag 'arıyor ve olmayan için ilanıyla form olarak zaten işe yarayacağını sanmıyorum.

Gerçekten cURL PHP bağlamaları gerçekten bunun için hiçbir desteğe sahip hissi almak için başladım. Hangi bana çok şaşırtıcı görünüyor. Bu tam anlamıyla başka bir şey yapabilirim gibi görünüyor, ama bunun gibi basit bir şey yapamaz mı?

Ben aynı sorunu içine koştu. Ama ben bu şekilde çözmeyi başardı.

for($cnt = 0; $cnt < count($siteRows); $cnt++)
{
    $curlParams['site_ids['.$cnt.']'] = $siteRows[$cnt]->site_id; 
}

Çok dosyaları için çalışır:

for($cnt = 0; $cnt < count($imageRows); $cnt++)
{
    $curlParams['product_images['.$cnt.']'] = '@'.$imageRows[$cnt]->full_path;
}

Ben kullanarak çalışma var:

curl_setopt($ch, CURLOPT_POSTFIELDS,array('tag[0]'=>'val0','tag[1]'=>'val1'));

daha sonra $_POST sonuçları: $_POST['tag'][0] = 'val0' ve $_POST['tag'][1] = 'val1'

Ben çevrimiçi bu cevabı buldum ve kaybolmadan önce burada yayınlamak istiyorum:

http://yeehuichan.wordpress.com/2011/08/07/sending-multiple-values-with-the-same-namekey-in-curl-post/

function curl_setopt_custom_postfields($ch, $postfields, $headers = null) {
    $algos = hash_algos();
    $hashAlgo = null;
    foreach ( array('sha1', 'md5') as $preferred ) {
        if ( in_array($preferred, $algos) ) {
            $hashAlgo = $preferred;
            break;
        }
    }
    if ( $hashAlgo === null ) { list($hashAlgo) = $algos; }
    $boundary =
        '----------------------------' .
        substr(hash($hashAlgo, 'cURL-php-multiple-value-same-key-support' . microtime()), 0, 12);

    $body = array();
    $crlf = "\r\n";
    $fields = array();
    foreach ( $postfields as $key => $value ) {
        if ( is_array($value) ) {
            foreach ( $value as $v ) {
                $fields[] = array($key, $v);
            }
        } else {
            $fields[] = array($key, $value);
        }
    }
    foreach ( $fields as $field ) {
        list($key, $value) = $field;
        if ( strpos($value, '@') === 0 ) {
            preg_match('/^@(.*?)$/', $value, $matches);
            list($dummy, $filename) = $matches;
            $body[] = '--' . $boundary;
            $body[] = 'Content-Disposition: form-data; name="' . $key . '"; filename="' . basename($filename) . '"';
            $body[] = 'Content-Type: application/octet-stream';
            $body[] = '';
            $body[] = file_get_contents($filename);
        } else {
            $body[] = '--' . $boundary;
            $body[] = 'Content-Disposition: form-data; name="' . $key . '"';
            $body[] = '';
            $body[] = $value;
        }
    }
    $body[] = '--' . $boundary . '--';
    $body[] = '';
    $contentType = 'multipart/form-data; boundary=' . $boundary;
    $content = join($crlf, $body);
    $contentLength = strlen($content);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Length: ' . $contentLength,
        'Expect: 100-continue',
        'Content-Type: ' . $contentType,
    ));

    curl_setopt($ch, CURLOPT_POSTFIELDS, $content);

}

Ve kullanmak için:

curl_setopt_custom_postfields($ch, array(
    'file' => '@a.csv',
    'name' => array('James', 'Peter', 'Richard'),
));

Only one solution I found. https://gist.github.com/simensen/288242 Hope that will help someone.

Teşekkürler