17

I'm working with a third party API that receives several parameters which must be encoded like this:

text[]=Hello%20World&text[]=How%20are%20you?&html[]=<p>Just%20fine,%20thank%20you</p>

As you can see this API can accept multiple parameters for text, and also for HTML (not in the sample call).

I have used http_build_query to correctly build a query string for other APIs

$params['text'][] = 'Hello World';$params['text'][] = 'How are you?';$params['html'][] = '<p>Just fine, thank you</p>';$http_query = http_build_query($params);

The problem with this approach is that it will build a query string with the numeric index:

text[0]=Hello%20World&text[1]=How%20are%20you?&html[0]=<p>Just%20fine,%20thank%20you</p>

unfortunately the API I'm working with doesn't like the numeric index and fails.

Is there any php function/class-method that can help me build a query like this quickly?

Thank you

RiaD's user avatar
RiaD
47.8k12 gold badges85 silver badges128 bronze badges
askedAug 16, 2012 at 22:53
Onema's user avatar

4 Answers4

13

I don't know a standard way to do it (I think there is no such way), but here's an ugly solution:

Since[] is encoded byhttp_build_query, you may generate string with indices and then replace them.

preg_replace('/(%5B)\d+(%5D=)/i', '$1$2', http_build_query($params));
Walf's user avatar
Walf
9,4393 gold badges47 silver badges67 bronze badges
answeredAug 16, 2012 at 23:06
RiaD's user avatar
Sign up to request clarification or add additional context in comments.

2 Comments

Idea was here, but this is the correct implementation (cf. php online manual's comments): preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $http_query);
Agree with @ErdalG. You could also do the following:$httpQuery = http_build_query($params, null, '&'); $httpQueryDecoded = urldecode($httpQuery); $requestDataFormatted = urlencode(preg_replace('#\[[\d]+\]#', '[]', $httpQueryDecoded));
5

I very much agree with the answer by RiaD, but you might run into some problems with this code (sorry I can't just make this a comment due to lack of rep).

First off, as far as I knowhttp_build_query returns an urlencode()'d string, which means you won't have [ and ] but instead you'll have %5B and %5D.

Second, PHP's PCRE engine recognizes the '[' character as the beginning of a character class and not just as a simple '[' (PCRE Meta Characters). This may end up replacing ALL digits from your request with '[]'.

You'll more likely want something like this:

preg_replace('/\%5B\d+\%5D/', '%5B%5D', http_build_query($params));

In this case, you'll need to escape the % characters because those also have a special meaning. Provided you have a string with the actual brackets instead of the escapes, try this:

preg_replace('/\[\d+\]/', '[]', $http_query);
answeredAug 30, 2012 at 22:13
michaelxor's user avatar

Comments

4

There doesn't seem to be a way to do this withhttp_build_query. Sorry. On the docs page though, someone has this:

function cr_post($a,$b=0,$c=0){    if (!is_array($a)) return false;    foreach ((array)$a as $k=>$v){        if ($c) $k=$b."[]"; elseif (is_int($k)) $k=$b.$k;        if (is_array($v)||is_object($v)) {            $r[]=cr_post($v,$k,1);continue;        }        $r[]=urlencode($k)."=" .urlencode($v);        }    return implode("&",$r);}$params['text'][] = 'Hello World';$params['text'][] = 'How are you?';$params['html'][] = '<p>Just fine, thank you</p>';$str = cr_post($params);echo $str;

I haven't tested it. If it doesn't work then you're going to have to roll your own. Maybe you can publish a github gist so other people can use it!

Nir Alfasi's user avatar
Nir Alfasi
53.6k11 gold badges93 silver badges138 bronze badges
answeredAug 16, 2012 at 23:04
Explosion Pills's user avatar

1 Comment

I fixed the example that you posted, now it works only that it also encodes the[].
1

Try this:

$params['text'][] = 'Hello World';$params['text'][] = 'How are you?';$params['html'][] = '<p>Just fine, thank you</p>';foreach ($params as $key => $value) {    foreach ($value as $key2 => $value2) {                $http_query.= $key . "[]=" . $value2 . "&";    }}$http_query = substr($http_query, 0, strlen($http_query)-1); // remove the last '&'$http_query = str_replace(" ", "%20", $http_query); // manually encode spacesecho $http_query;
answeredAug 16, 2012 at 23:11
Nir Alfasi's user avatar

3 Comments

not only spaces are encoded, it's better to use urlencode in loop
urlencode will replace[] with%5B%5D%3D - and according to the example the OP provided above - it's not the expected output.
@RiaD well, that's your solution :))))

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy 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.