2010-08-10 9 views
6

मुझे PHP और CURL का उपयोग करके फ़ाइल अपलोड के साथ एक बहुआयामी सरणी पोस्ट करने में समस्याएं आ रही हैं।पीएचपी और कर्ल का उपयोग कर बहुआयामी POSTFIELDS के साथ फ़ाइलों (मल्टीपार्ट/फॉर्म-डेटा) को कैसे अपलोड करें?

बहुआयामी सरणी उदाहरण के लिए है:

$post['question'] = 'Are you human?'; 
$post['answers'] = array('yes', 'no', 'maybe'); 
$post['file'] = '@/path/to/file'; 

// Output: 

Array(
    'question' => Are you human?, 
    'answers' => Array(
     '0' => yes, 
     '1' => no, 
     '2' => maybe 
     ), 
    'file' => @/path/to/file 
) 

कुछ चीजें क्यों यह अगर आप बस इस तरह कर्ल में CURLOPT_POSTFIELDS के साथ इस पोस्ट करने की कोशिश काम नहीं होता हैं:

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_URL, 'http://example.com'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 

$response = curl_exec($ch); 

सभी सरकारी पीएचपी पहले CURLOPT_POSTFIELDS की description का कहना है:

पूरा डेटा पोस्ट करने के लिए एक HTTP "पोस्ट" ऑपरेशन में। फ़ाइल पोस्ट करने के लिए, फ़ाइल नाम @ के साथ प्रीपेन्ड करें और पूर्ण पथ का उपयोग करें। यह या तो की तरह एक urlencoded स्ट्रिंग 'para1 = VAL1 & para2 = val2 & ...' या के रूप में पारित किया जा सकता मूल्य के रूप में कुंजी और क्षेत्र डेटा के रूप में क्षेत्र के नाम के साथ एक सरणी के रूप में। यदि मान सरणी है, तो सामग्री-प्रकार शीर्षलेख मल्टीपार्ट/फॉर्म-डेटा पर सेट होगा।

ऐसा लगता है कि आप POSTFIELDS को किसी भी प्रकार की सरणी पास कर सकते हैं? गलत। POSTFIELDS केवल गैर-स्केलर मान स्वीकार करता है और बहु-आयामी सरणी पर गुजरते समय Array to string conversion त्रुटि के साथ चकित करेगा। तो, आपके पास एकमात्र अन्य विकल्प http_build_query() है जो आपके सरणी को चकित करने वाले बहुआयामी सरणी को पार करने में सक्षम होने के लिए है।

लेकिन .. आप PHP पृष्ठ पर नोट में पढ़ सकते हैं के रूप में:

नोट: CURLOPT_POSTFIELDS को एक सरणी पासिंग, बहुखण्डीय/फार्म डेटा के रूप में डेटा सांकेतिक शब्दों में बदलना होगा, जबकि एक यूआरएल गुजर -encoded स्ट्रिंग डेटा को एप्लिकेशन/x-www-form-urlencoded के रूप में एन्कोड करेगा।

पोस्ट अगर आप POSTFIELDS के लिए एक urlencoded स्ट्रिंग गुजरती हैं, आपकी फ़ाइल अपलोड विफल कर रही हो बहुखण्डीय/फार्म-डेटा इनकोडिंग नहीं होंगे।

तो कर्ल के साथ दोनों को गठबंधन करना लगभग असंभव प्रतीत होता है, जबकि यदि आप एक नियमित HTML फॉर्म का उपयोग करते हैं तो यह कोई समस्या नहीं होगी।

मेरा प्रश्न है: क्या बहुआयामी सरणी और फ़ाइल अपलोड पोस्ट करने में सक्षम होने के लिए कर्ल के इस अजीब क्विर्क को बाईपास करना संभव है?

उत्तर

6

मल्टीपार्ट/फॉर्म-डेटा नेस्टेड मानों का समर्थन नहीं करता है। और मुझे विश्वास नहीं है कि कर्ल इसे भी कर सकता है।

मुझे संदेह है कि आपके अनुरोध का प्राप्त अंत भी एक PHP स्क्रिप्ट है। है, तो आप एक नेस्टेड सरणी में से एक मान के रूप में, प्रस्तुत कर सकते हैं अगर आप बस इसे अपने आप को तैयार:

$post['answers[0]'] = "yes"; 
$post['answers[1]'] = "no"; 
$post['answers[2]'] = "maybe"; 
सैद्धांतिक रूप से आप सिर्फ 'answers[]' सूचकांक बिना आवश्यकता होगी, लेकिन वह पूर्ववर्ती मूल्य अधिलेखित कर देगा

- और इस तरह केवल http_build_query के साथ काम करता है।

मुझे यकीन नहीं है कि PHP में कोई HTTP लाइब्रेरी है जो स्वचालित रूप से ऐसा कर सकती है।

+0

मुझे यह कामकाज पसंद है, धन्यवाद। – Melvin

+0

ग्रेट चाल, यह एक आकर्षण की तरह काम करता है! – aknatn

2

एक और तरीका है पहले उत्तर पूरा करने के लिए:

foreach(array("yes","no","maybe") as $key=>$value) 
    $post["answers[$key]"] = $value;
+0

यह बहुआयामी सरणी के लिए काम नहीं करेगा –

1

इस पुनरावर्ती क्रिया का प्रयास करें।

https://gist.github.com/yisraeldov/ec29d520062575c204be7ab71d3ecd2f

<?php 
function build_post_fields($data,$existingKeys='',&$returnArray=[]){ 
    if(($data instanceof CURLFile) or !(is_array($data) or is_object($data))){ 
     $returnArray[$existingKeys]=$data; 
     return $returnArray; 
    } 
    else{ 
     foreach ($data as $key => $item) { 
      build_post_fields($item,$existingKeys?$existingKeys."[$key]":$key,$returnArray); 
     } 
     return $returnArray; 
    } 
} 

और तुम इस तरह इसका इस्तेमाल कर सकते हैं।

curl_setopt($ch, CURLOPT_POSTFIELDS, build_post_fields($postfields)); 
संबंधित मुद्दे