PHP: Sending multiple queries with the same key with POST request

I use stream_context_create() to send a POST request.

The problem is that the API I am using requires multiple queries to be sent with the same request, using the same key.  I know this is crazy but I did not create the API.

How can I send multiple queries with the same key?
<?php

$url = 'https://www.googleapis.com/language/translate/v2?key=xyz&source=en&target=de';
$data = array('q' => 'Hello','q' => 'World','q' => 'Smile');

$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\nX-HTTP-Method-Override: GET\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data),
    ),
);
$context = stream_context_create($options);

$result = file_get_contents($url, false, $context);

var_dump($result);

?>

Open in new window

I do NOT want to use cURL.
LVL 10
skijAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
do NOT want to use cURL.
Why not?  It's a much better solution than file_get_contents() and would be my preferred solution, so if you're ruling it out, it would be helpful to know where it is incapable of meeting your needs.

Also, is this really a request to the GoogleAPIs for language translation, or is that just an example?  It would be helpful to know what the real API is, so we can check the online man pages.
skijAuthor Commented:
The server I am using supports PHP but not cURL.

Here is the documentation for the API:
https://cloud.google.com/translate/v2/using_rest

Back to my original question: how can q be repeated?
Ray PaseurCommented:
I don't believe that q can be repeated.  You can use a longer string for q in a POST request.  GET requests are limited, often to something as small as 1024 characters.  But the length of the q value is not really the issue - it's the way that the request variables are processed on the API.  

This is a guess, but it is an informed guess, from experience of having written and consumed many APIs.  The API treats the request variables as an array, with the keys in the array being the argument names, and the values in the array being the argument values.  This will be true whether the request method is GET or POST (or any other method, for that matter).  To see the effect of using more than one q argument, run this script:
http://iconoun.com/demo/temp_skij.php
http://iconoun.com/demo/temp_skij.php?q=ABC
http://iconoun.com/demo/temp_skij.php?q=ABC&q=XYZ

<?php // demo/temp_skij.php
/**
 * http://www.experts-exchange.com/questions/28690166/PHP-Sending-multiple-queries-with-the-same-key-with-POST-request.html
 */
error_reporting(E_ALL);

var_dump($_GET);

Open in new window

TL;DR Version: You can't send a request with more than one instance of the same key.  You have to send multiple requests.
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Julian HansenCommented:
The API interpretation is correct - the 'q' parameter can be specified multiple times.

You have almost nailed the solution - you are tripping up on the http_build_query call which takes an array of key value pairs and produces a query string. Naturally, using this method you cannot duplicate the 'q' key. The answer is simple. Create the query string yourself like this

$opts = array(
  'http'=>array(
    'method'=>"POST",
    'header'=>"Content-type: application/x-www-form-urlencoded\r\nX-HTTP-Method-Override: GET\r\n",
	'content' => 'q=Hello&q=World&q=Smile'
  )
);

Open in new window


You can now use your code as it is.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ray PaseurCommented:
@Julian:  Good catch!  Looks like Google processes the raw post string.  This would seem to work, if I had an API key ;-)

<?php // demo/temp_skij.php
/**
 * http://www.experts-exchange.com/questions/28690166/PHP-Sending-multiple-queries-with-the-same-key-with-POST-request.html
 */
error_reporting(E_ALL);
echo '<pre>';

// BASE URL
$url = 'https://www.googleapis.com/language/translate/v2?key=xyz&source=en&target=de&content=';

// ARRAY OF DESIRED TRANSLATIONS
$dat = array('Hello','World','Smile');

// APPEND TO THE URL
foreach ($dat as $txt)
{
    $url .= 'q=' . urlencode($txt) . '&';
}
$url = rtrim($url, '&');

// TEST LENGTH
if (strlen($url) > 2047) trigger_error('URL TOO LONG', E_USER_ERROR);

// SHOW THE URL
var_dump($url);

// TRY THE TRANSLATION
$jso = file_get_contents($url);

// SHOW THE RESULT
var_dump($jso);

Open in new window

Julian HansenCommented:
Thanks Ray,

Your code is still using a GET where the author specifically requires a POST which means the query vars need to go in the header as per the authors original post.

What you can do is use your loop to replace the http_build_query so
$qs = '';
foreach ($dat as $key => $txt)
{
    $qs .= "{$key}=" . urlencode($txt) . '&';
}

Open in new window

Then add $qs to the opts array like so
$opts = array(
  'http'=>array(
    'method'=>"POST",
    'header'=>"Content-type: application/x-www-form-urlencoded\r\nX-HTTP-Method-Override: GET\r\n",
	'content' => $qs
  )
);

Open in new window

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.