ekno
ekno

Reputation: 69

cURL request won't work with data from fetch API

I'm sending some data with the fetch API to a translate.php file, here is my JS code:

const translation = {
  word: 'Hello'
};

fetch('http://yandex.local/translate.php', {
  method: 'POST',
  body: JSON.stringify(translation),
  headers: {
    'Content-Type': 'application/json'
  }
}).then(res => {
  return res.text();
}).then(text => {
  console.log(text);
})

Here is how I try to get the data on the translate.php:

$postData = json_decode(file_get_contents("php://input"), true);

$word = $postData['word'];

Here is my cURL request:

$word = $postData['word'];

$curl = curl_init();
$request = '{
  "texts": "Hello",
  "targetLanguageCode": "ru",
  "sourceLanguageCode": "en"
}';
curl_setopt($curl, CURLOPT_URL, 'https://translate.api.cloud.yandex.net/translate/v2/translate');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  "Authorization: Api-Key 123456",
  "Content-Type: application/json"
));
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($curl);
$err = curl_error($curl);
if($err) {
  echo 'Curl Error: ' . $err;
} else {
  $response = json_decode($result, true);
  print_r($response['translations']['0']['text']);
}
curl_close($curl);

When I'm runing this code I get the translation of Hello in russian which is Привет. But if I replace "Hello" in the request object by $word I got the error: Trying to access array offset on value of type null

Here is the way I rewrite the request object:

$request = '{
  "texts": $word,
  "targetLanguageCode": "ru",
  "sourceLanguageCode": "en"
}';

When I check the XHR of my translate.php all seems ok, I have a status 200 and the request payload shows my data. Also the word "hello" displays correctly in the console of my index.php

Upvotes: 1

Views: 864

Answers (1)

ADyson
ADyson

Reputation: 61859

Don't ever create JSON strings by hand (i.e. I mean by hard-coding the JSON text directly into a string variable). It can lead to all kinds of syntax issues accidentally.

Please replace

$request = '{
  "texts": "Hello",
  "targetLanguageCode": "ru",
  "sourceLanguageCode": "en"
}';

with

$requestObj = array(
  "texts" => $word, 
  "targetLanguageCode" => "ru", 
  "sourceLanguageCode" => "en"
);
$request = json_encode($requestObj);

This will produce a more reliable output, and also include the $word variable correctly.

P.S. Your actual issue was that in PHP, variables are not interpolated inside a string unless that string is double-quoted (see the manual). Your $request string is single-quoted.

Therefore $word inside your $request string was not changed into "Hello" but left as the literal string "$word". And also since you removed the quotes around it, when the remote server tries to parse that it will not be valid JSON, because a text variable in JSON must have quotes around it. This is exactly the kind of slip-up which is easy to make, and why I say not to build your JSON by hand!

Your version would output

{"texts":$word,"targetLanguageCode":"ru","sourceLanguageCode":"en"}

whereas my version will (correctly) output:

{"texts":"Hello","targetLanguageCode":"ru","sourceLanguageCode":"en"}

(Of course I should add, given the comment thread above, that regardless of my changes, none of this will ever work unless you send a correct POST request to translate.php containing the relevant data to populate $word in the first place.)

Upvotes: 1

Related Questions