8

I have following code:

// $postfields = array();
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);

My $postfields variable is an array of parameters. And i have a notice there is array to string conversion. It works tho.

I could use http_build_query() function to nullify notice, however i use @path_to_file to include post files. and http_build_query() breaks file includes.

I'm wondering if there is more "proper" way to do this. Without generating a notice.

4 Answers 4

16

Are some values of $postfields arrays themselves? This is most likely what's causing the notice. curl_setops expects its third parameter to be an array whose keys and values are strings, as is stated in PHP's manual page for the function, though it might not be very clear:

This parameter can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value.

In this quote, the key point is that para1/2 and val1/2 are strings, and if you want, you can provide them as an array where keys are para1 and para2, and values are val1 and val2.

There are two ways to eliminate the notices.

The first is to use http_build_query() and replace your uses of @filepath by CURLFile objects. This is only possible if you're using PHP 5.5 or above, unfortunately. The manual's page has a pretty clear and simple example of use.

If using CURLFiles is not an option for you, then the second way is to json_encode() the values of your $postfields array which are arrays themselves. This isn't elegant, and it requires you to decode the JSON on the other side.

Sign up to request clarification or add additional context in comments.

2 Comments

Indeed, 3 values of this array are arrays themselves... I don't use them so those are probably not exported properly. Didn't think those could be inner arrays.
using http_build_query with CURLFiles doesn't work. The CURLFiles will get converted into arrays and just come across as regular $_POST data.
10

j11e's answer won't work if you want to send multidimensional arrays

Try this recursive function.

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

And you can use it like this.

curl_setopt($ch, CURLOPT_POSTFIELDS, build_post_fields($postfields));

1 Comment

That is what I needed. In order to use <input name="field[]" value="1"> <input name="field[]" value="2"> etc. in curl request this is the right answer. Thanks Yysrael
5

Using Laravel one thing that worked for me was to use the tag 'Content-Type: application/json' in the request header, and sending my data json encoded like this:

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

In the function that receives the parameters in the request I had no need to use the json decode function, I access to the parameters just like

$request->something

Comments

0

After research for an hour, here the way i fixed my code:

$strVar = '';
if ($data) {
        $ea = build_post_fields($data);
        foreach($ea as $key=>$val) {
                $strVar.= "$key=$val&";
        }
}


/* eCurl */
$curl = curl_init($url);

/* Set Array data to POST */
curl_setopt( $curl, CURLOPT_POSTFIELDS, ($strVar) );

And here is the function I take from @Yisrael Dov below:


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

That work perfectly! You can post a deep array like:

$post_var = array(
'people' => array('Lam', 'Hien', 'Nhi'),
'age' => array(12, 22, 25)
);

Good day!

2 Comments

Welcome to SO. Thanks for your answer, but you should credit Yisrael Dov for coming with the function build_post_fields in his own answer, posted previously. And beware, your function build a query string with an unnecessary trailing &.
Thank you for your note, i am sorry, build_post_fields is belong to @yisrael-dov

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.