Troubleshoot PHP file_get_contents() POST with JSON body - php

I can't figure out how to make my PHP script work and I'm not allowed to use debugging tools on the server or run it locally. Please help.
It is targeting an open data API (Statistics Norway / SSB), specifically this one:
$url = "http://data.ssb.no/api/v0/no/table/08940";
The API is queried with POST and provides output according to posted message body which must be formatted as JSON.
I build the $body with a nested array in PHP, and the output of json_encode($body, JSON_PRETTY_PRINT); is provided below (truncated).
This runs just fine in the SSB API Console as well as in Restlet Client.
{
"query": [
{
"code": "UtslpTilLuft",
"selection": {
"filter": "item",
"values": [
"1",
"2"
]
}
},
{
"code": "ContentsCode",
"selection": {
"filter": "item",
"values": [
"UtslippCO2ekvival"
]
}
},
{
"code": "Tid",
"selection": {
"filter": "item",
"values": [
"1990",
"1991"
]
}
}
],
"response": {
"format": "json"
}
}
Here is the script for the file_get_contents():
$json_body = json_encode($body);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $json_body
)
);
$context = stream_context_create($options);
$file = file_get_contents($url, false, $context);
$output = json_decode($file, true);
I have looked at the answers given in How to post data in PHP using file_get_contents?, tried to replace json_encode() with http_build_query() and http_build_query(json_encode()), experimented with different 'header' but print_r($output) gives me nothing.
Edit: I removed $output = json_decode($file, true); and now it prints the JSON array! Still need to figure out how to turn that into a PHP variable but how can I do that without json_decode...?
Edit 2: I figured out the data is actually not regular JSON, but JSON-STAT, in the form of a unidimensional array. The proper call in the message body (response: format) is not "json" but "json-stat". With "json", the returned data was incompatible for json_decode().
Any tips on how to parse that to a regular associative array in PHP is highly appreciated!

Related

Catch request errors openapi-validation-middleware and change jsooutput

I use this repository hkarlstrom/openapi-validation-middleware to verify incoming and outgoing json requests and responses in my api build on php slim.
I want to rework the error output to another json format.
Currently it is, as example:
Error 400:
{
"message": "Request validation failed",
"errors": [
{
"name": "catalogus",
"code": "error_format",
"value": "",
"in": "query",
"type": "string",
"format": "uri"
}
]
}
I tried to catch this error so i can modify the repsonse like this:
$mw = new HKarlstrom\Middleware\OpenApiValidation(__DIR__.'/catalog_openapi.json');
$options = [
'validateRequest'=> false,
'exampleResponse' => true,
'beforeHandler' => function (\Psr\Http\Message\ServerRequestInterface $request, array $errors) : \Psr\Http\Message\ServerRequestInterface {
// Alter request modifiy the json reponse here !!!
echo "tadaaaa"; <- never outputted
return $request;
}
];
And finally in my route:
$app->get('/v1/dosomething[/{params:.*}]',\App\Action\DoSomething::class)->add($mw,$options);
But it never touches the before- or errorHandler.
Any ideas how to get this working?

Decoding and looping through PHP JSON array

I have the following deocoded JSON array.
I need to access the "type" inside the context, as well as I need to loop through each of the values in the payload. How do I do that?
{
"RequestHeader":
{
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context" :
{
"type": "friends,circles"
}
"payload" [ {12345},{12345} ,{2345} ]
}
I tried the following, but it doesn't work
$decoded = json_decode($json_string);
for ($i=0;$i<payload.length;++$i)
{
$id=$decoded->payload[$i];
//do some operation with the id
}
First of all the JSON you provided is invalid. Supposedly the valid one should look like this
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
After you've fixed the problem with JSON provider it will be quite easy to access data
<?php
$json = <<<'JSON'
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
JSON;
$data = json_decode($json, true);
$type = $data['context']['type'];
var_dump($type);
foreach($data['payload'] as $id) {
var_dump($id);
}
Remember to make sure you check that the data actually exists before accessing it, e.g. isset($data['context']['type']) unless you are absolutely sure in it's integrity.
When you use json_decode method, the output will be nested arrays
So for example to access context type you need to do the following
echo $decoded["context"]["type"];
And to loop on payload you need to do the following
for ($i=0;$i<$decoded["payload"].length;++$i)
{
$id=$decoded["payload"][$i];
//do some operation with the id
}

EmberJS API questions using PHP

I'm using Laravel/PHP to output some JSON for Ember to pick up.... a couple of things here.
First, my PHP looks like this (is there another way to send the data)
return Response::json([
'articles' => $articles->toArray()
], $statusCode);
This is what I am used to doing.
foreach($articles as $article) {
$response['articles'][] = [
'id' => $article->id,
'body' => $article->body,
'title' => $article->title
];
}
return Response::json([
'articles' => $articles->toArray()
], $statusCode);
The first PHP snippet works fine, but the second does not. I get all kinds of errors about resource types by Ember.
Next question is for Ember heads. Right now I am getting everything working with RESTAdapter but should I be using JSONAPIAdapter instead? When I try to get it working with JSONAPIAdapter and JSONAPISerializer I get this error
One or more of the following keys must be present: \"data\",
\"errors\", \"meta
. I can get that error to go away but then I get an error about an undefined type or an unknown resource.
Its not mandatory to use JSONAPIAdapter, but if you have control over the API then you can very well using it. API response should follow the format (http://jsonapi.org/format/)
Sample format for single resource object,
{
"data": {
"type": "articles",
"id": "1",
"attributes": {
// ... this article's attributes
}
}
}
Sample format for multiple resource objects,
{
"data": [{
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!"
}
}, {
"type": "articles",
"id": "2",
"attributes": {
"title": "Rails is Omakase"
}
}]
}

Posting a JSON object to a REST API using PHP

I have found a couple of helpful links on stackoverflow but they haven't helped me complete my task because I am a complete beginner in trying to write PHP or use curl etc.
Send json post using php
Posting JSON data to API using CURL
I have been using Postman in Chrome to test API calls but I now want to put together a demo system on my Apache web server.
Does anyone have an example of a PHP webform posting to a json Object to a REST API?
Here is an example of what I want to send:
<?php
$url = "https://api.url/api/v1//accounts/create";
$jdata = json_encode($data);
$data = [{
"status": "active",
"username": ["uname"],
"password": ["pword"],
"attributes": {
"forenames": ["fname"],
"surname": ["lname"],
"emailAddress": ["email"]
},
}]
?>
Any advice would be fantastic. Like I said, I am new to curl and php, am unfamiliar with the array approach mentioned in the other articles and the ["info"] elements should be populated with the information filled in on my webform.
I hope I have been concise and explanitory but please let me know if you need anymore information.
Snook
Try something like the following, modifying steps 1 and 2 accordingly:
function sendRequest($data,$url)
{
$postdata = http_build_query(array('data'=>$data));
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded \r\n",
//"X-Requested-With: XMLHttpRequest \r\n".
//"curl/7.9.8 (i686-pc-linux-gnu) libcurl 7.9.8 (OpenSSL 0.9.6b) (ipv6 enabled)\r\n",
'content' => $postdata,
'ignore_errors' => true,
'timeout' => 10,
)
);
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
// 1.- add your json
$data = '[{
"status" : "active",
"username" : ["uname"],
"password" : ["pword"],
"attributes" : {
"forenames" : ["fname"],
"surname" : ["lname"],
"emailAddress": ["email"]
},
}]';
// 2.- add api endpoint
$url= "https://api.url/api/v1//accounts/create";
// 3.- fire
$result = sendRequest($data,$url);
// 4.- dump result
echo $result;
die();
Good luck!!

add data to json (php)

can someone please help me to add data to following json.
$temp='{
"custId": 123,
"data": [
{
"code": "abc1"
},
{
"code": "abc2"
}
],
"id": 102
}';
data to be added
$data1='{
"code": "abc3"
}';
Desired result
$temp='{
"custId": 123,
"data": [
{
"code": "abc1"
},
{
"code": "abc2"
},
{
"code": "abc3"
}
],
"id": 10
}';
I can append data to $temp, but can someone please help to add data to specific position with php. Thank you in advance. (I've tried json_decode($temp, true) and then finding the location where data1 is to be added but failed).
You can convert your data to a normal PHP array:
$array = json_decode($temp, true);
then just add or change anything you want:
$array["data"][] = array(["code"] => "abc3");
and re-encode to json:
$temp = json_encode($array);// encode to json
http://php.net/manual/en/function.json-decode.php
first, you need to convert the JSON into PHP array like this:
$array = json_decode($temp, true);
Then, it's as simple as:
$array['data']['code'] = 'abc3';
If the string that you want to add is still a JSON, you have to convert that one in an array as well so:
$arr_to_add = json_decode($data1, true);
$array['data'][] = $arr_to_add;
In the end, of course, encode again like this:
$final_json = json_encode($array);
Hope this helps! :D
First you need to decode the json with json_decode. This returns a PHP variable.
Add desired values.
Use json_encode to get the json with new values. Returns a string containing the JSON.
you can try this:
<?php
$temp='{
"custId": 123,
"data": [
{
"code": "abc1"
},
{
"code": "abc2"
}
],
"id": 102
}';
$data1='{
"code": "abc3"
}';
$jarr=json_decode($temp,true);
$appArr=json_decode($data1,true);
$desire=array_merge($jarr,$appArr);
//print_r($desire);
echo json_encode($desire);

Categories