Link to home
Start Free TrialLog in
Avatar of skij
skijFlag for Canada

asked on

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.
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

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.
Avatar of skij

ASKER

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?
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.
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@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

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