improving loop throw a schema on php - php

This is working, but feels really "dirty"
I have a schema json like:
[
{
"url": "http://www.google.com/api/updateVariable",
"verb": "POST",
"bodySchema": {
"type": "object",
"properties": {
"StoreId": {
"sync": "True",
"type": "integer"
},
"SKU": {
"sync": "True",
"type": "string"
},
"WareHouseId": {
"sync": "False",
"type": "integer"
},
"Stock": {
"sync": "True",
"type": "integer"
}
},
"required": [
"StoreId",
"SKU",
"Stock"
]
}
},
{
"url": "http://www.google.com/api/insertVariable",
"verb": "POST",
"bodySchema": {
"type": "object",
"properties": {
"StoreId": {
"sync": "True",
"type": "integer"
},
"SKU": {
"sync": "True",
"type": "string"
},
"WareHouseId": {
"sync": "False",
"type": "integer"
},
"Description": {
"sync": "True",
"type": "integer"
}
},
"required": [
"StoreId",
"SKU",
"Description"
]
}
}
]
And I want to loop throw all the properties (once again, this is working)
$result=json_decode($result, true);
while($item = array_shift($result)){
foreach ($item as $key => $value){
if($key=="bodySchema"){
foreach ($value as $key2 => $value3){
if($key2==properties)
var_dump($value3);
}
}
}
}
What I would like to have is something like:
$result=json_decode($result, true);
foreach($result as $mydata){
foreach($mydata->bodySchema->properties as $values){
var_dump($values->value);
}
}
is this possible?, I want to keep this code as clean and neat as possible

Yes, you can do it the way you want. You just have some syntax to cleanup to do.
In this example, $result is an associative array, so you can index into it just like any array.
$result = json_decode($result, true);
foreach ($result as $mydata) {
foreach ($mydata["bodySchema"]["properties"] as $propertyName => $schema){
var_dump([$propertyName, $schema]);
}
}
If you prefer object syntax, drop the true from json_decode.
$result = json_decode($result);
foreach ($result as $mydata) {
foreach ($mydata->bodySchema->properties as $propertyName => $schema){
var_dump([$propertyName, $schema]);
}
}

Related

parse extended json output file from cucumber with php

i am tring to parse a special json content. I got this as an output file from a cucumber execution. The goal is it to decode some values like the name the status and some other content. How can i encode that.
Another concern would be a transformation of json into a CSV.
It is not important for me to use php. Java or Perl would be an alternative.
This file I am gonna call in php with:
$jsonconntent = file_get_contents("/home/xxx/test1.json");
The json conten looks like this (I posted only the beginning):
[
{
"uri": "features/complete_ski.feature",
"id": "complete_ski_with_time",
"keyword": "Feature",
"name": "Complete_Ski_with_time",
"description": "",
"line": 1,
"elements": [
{
"id": "complete_ski_with_time;time_part_preamble",
"keyword": "Scenario",
"name": "time_part_preamble",
"description": "",
"line": 3,
"type": "scenario",
"before": [
{
"output": [
"Default Timestamp start: 1516024716000"
],
"match": {
"location": "features/support/env.rb:32"
},
"result": {
"status": "passed",
"duration": 191690
}
},
{
"match": {
"location": "capybara-2.17.0/lib/capybara/cucumber.rb:13"
},
"result": {
"status": "passed",
"duration": 52117
}
},
{
"match": {
"location": "capybara-2.17.0/lib/capybara/cucumber.rb:21"
},
"result": {
"status": "passed",
"duration": 25885
}
}
],
"steps": [
{
"keyword": "Given ",
"name": "a Android A-Party",
"line": 4,
"output": [
"Got handset with number unvisable, IMSI: notfor, android-Id: yourfone, VNC: 11111, port: 9981"
],
"match": {
"location": "features/step_definitions/idrp_steps.rb:11"
},
"result": {
"status": "passed",
"duration": 1415024760
},
"after": [
{
"match": {
"location": "features/support/env.rb:24"
},
"result": {
"status": "passed",
"duration": 264339
}
}
]
}
Use:
$data = json_decode($jsonconntent, true);
You will have the data with javascript objects as arrays, not PHP objects.
To save it as CSV, it depends on the structure of the data. In this case, it is complicated:
{
"uri": "features/complete_ski.feature",
"id": "complete_ski_with_time",
"keyword": "Feature",
"name": "Complete_Ski_with_time",
"description": "",
"line": 1,
"elements": [
{
"id": "complete_ski_with_time;time_part_preamble",
"keyword": "Scenario",
"name": "time_part_preamble",
"description": "",
"line": 3,
...
How do you put the data in the column elements? Data is so nested that it cannot be transformed into a tabular format with column headers and one value per column in each row.
As to how to access the data, you can do this:
$first_element_id = $data[0]['elements'][0]['id'];
foreach ( $data as $item ) {
$uri = $item['uri'];
foreach ( $item['elements'] as $element ) {
$name = $element['name'];
}
}
As asked in one of the comments, this is how to access the 'Default Timestamp start':
foreach ($data as $item) {
foreach ($item['elements'] as $element) {
foreach ($element['before'] as $before) {
if (isset($before['output'])) {
foreach ($before['output'] as $output) {
echo sprintf("%s\n", $output);
}
}
}
}
}

How to validate required items of JSON SCHEMA array

I have a JSON Schema for new orders, that consists of order list and address.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"properties": {
"order": {
"type": "array",
"items": {
"type": "array",
"properties": {
"product_id": {
"type": "integer"
},
"quantity": {
"type": "integer"
}
},
"required": [
"product_id",
"quantity"
]
}
},
"address": {
"type": "array",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "integer"
},
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"city": {
"type": "string"
},
"state_or_region": {
"type": "string"
},
"country": {
"type": "string"
}
},
"required": [
"name",
"phone",
"address1",
"city",
"state_or_region",
"country"
]
}
},
"required": [
"order",
"address"
]
}
But it doesn't seem to actually validate the items at all (I'm using Laravel 5.2 with "justinrainbow/json-schema": "~2.0" ):
$refResolver = new \JsonSchema\RefResolver(new \JsonSchema\Uri\UriRetriever(), new \JsonSchema\Uri\UriResolver());
$schema = $refResolver->resolve(storage_path('schemas\orders.post.json'));
$errors = [];
$input = Request::input();
// Validate
$validator = new \JsonSchema\Validator();
$validator->check($input, $schema);
$msg = [];
if ($validator->isValid()) {
return Response::json(['valid'], 200, [], $this->pritify);
} else {
$msg['success'] = false;
$msg['message'] = "JSON does not validate";
foreach ($validator->getErrors() as $error) {
$msg['errors'][] = [
'error' => ($error['property'] = ' ') ? 'wrong_data' : $error['property'],
'message' => $error['message']
];
}
return Response::json($msg, 422, [], $this->pritify);
}
A request like this always comes valid:
{
"order": [
{
"product_id": 100,
"quantity": 1
},
{
"product_id": 0,
"quantity": 2
}
],
"address": []
}
Any ideas what am I doing wrong?
You have messed array and object types. The only array value in your scheme must be order. Fixed scheme:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"order": {
"type": "array",
"items": {
"type": "object",
"properties": {
"product_id": {
"type": "integer"
},
"quantity": {
"type": "integer"
}
},
"required": [
"product_id",
"quantity"
]
}
},
"address": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"phone": {
"type": "integer"
},
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"city": {
"type": "string"
},
"state_or_region": {
"type": "string"
},
"country": {
"type": "string"
}
},
"required": [
"name",
"phone",
"address1",
"city",
"state_or_region",
"country"
]
}
},
"required": [
"order",
"address"
]
}
And validation errors I got with you test data:
JSON does not validate. Violations:
[address.name] The property name is required
[address.phone] The property phone is required
[address.address1] The property address1 is required
[address.city] The property city is required
[address.state_or_region] The property state_or_region is required
[address.country] The property country is required

PHP json_decode error: Array value found, but an object is required

I am trying to decode following JSON file
{
"email": "mail#gmail.com",
"password": "12345",
"languageProficiency": {
"language": "English",
"proficiency": 4
},
"tags": [
{
"name": "singing"
},
{
"name": "dance"
}
]
}
When I do this
$data = json_decode($jsonContent, true);
echo $data;
die();
I have following error:
Array value found, but an object is required
Question
1) How can I view data from JSON
2) How can I access property of each object in tags array
I am validating Json content againsts this schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"languageProficiency": {
"type": "object",
"properties": {
"language": {
"type": "string"
},
"proficiency": {
"type": "integer"
}
},
"required": [
"language",
"proficiency"
]
},
"tags": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
}
}
},
"required": [
"email",
"password",
"languageProficiency",
"tags"
]
}
UPDATE
I tried following to view json content
print_r($data)
But I still get same error
$data = json_decode($jsonContent, true);
Above line of code will return Array, for which you can not use echo directly to print an array.
To print specific value of an array (e.g. email), do it like this:
echo $data["email"];
Tip:
Use print_r() to know the array structure like this,
echo "<pre>";
print_r($data);
you can try print_r($data) to explore values

Parsing an array with PHP in a foreach loop

I want to parse an array with PHP's foreach loop to get the object names and values inside the 'ques' array.
[
{
"ques": [
{
"name": "comment",
"value": "comment me for the reason",
"sur_id": "1",
"user_id": "admin#gmail.com",
"pagename": "question_response"
},
{
"name": "check-box[]",
"value": "1"
},
{
"name": "radio",
"value": "radio 2"
},
{
"name": "yes",
"value": "no"
}
]
"ques":[
{
"name": "date",
"value": "2015-10-23"
},
{
"name": "select-deopdown",
"value": ""
},
{
"name": "true",
"value": "false"
},
{
"name": "number",
"value": "55"
}
]
}
]
I want to separate the value from the 'ques' array:
while ($fetch = mysql_fetch_array($query1)) {
$content = $fetch['CONTENT_VALUES'];
// print_r($content);
$content_value= mb_convert_encoding($content ,"UTF-8");
$datas = json_decode($content, true);
foreach($datas->ques as $values)
{
echo $values->value . "\n";
print_r($values);
}
$test[] = array('ques' => $datas ,'answer'=>$values);
}

Flatten a Multidimensional Array with key, value and object from a JSON

For 2 days, I'm trying to extract informations from a multidimensional array and I think I'm stuck after trying a lot of things
Here is my json
{
"profile": [
{
"id": "123456",
"hostId": null,
"description": [
{
"id": "name",
"value": "foo"
},
{
"id": "name2",
"value": "foo2"
},
{
"id": "bio",
"value": "heyyyy"
},
{
"id": "location",
"value": "somewhere"
}
],
"ishere": true
}
]
}
I want to manipulate it to have this
{
"id": "123456",
"host": null,
"name": "foo",
"name2": "foo2",
"bio": "heyyyy",
"location": "somewhere",
"ishere": true
}
with this (after a json_decode)
foreach ($array->profileUsers[0]->settings as $item) {
$out2[$item->id] = $item->value;
}
I only have
{
"name": "foo",
"name2": "foo2",
"bio": "heyyyy",
"location": "somewhere"
}
Thank you
This should do the trick:
$obj = json_decode($your_json);
$obj = $obj->profile[0];
foreach($obj->description as $d)
$obj->{$d->id} = $d->value;
unset($obj->description);
$data = json_decode($your_json, true);
$new_array = [];
foreach($data['profile'] as $key=>$item) {
if(is_array($item)) {
$new_array[$item['id']] = $item['value'];
}
else {
$new_array[$key] = $item;
}
}
Hardcoded this, hope it will help.

Categories