php loop through json, differing property names - php

I'm not to comfortable with json, and there has to be an easier way of doing what I am doing.
Here is a sample of the json feed I'm working with.
"goalie": [
{
"position": "Goalie",
"id": 8476945,
"weight": 207,
"height": "6' 4\"",
"imageUrl": "http://3.cdn.nhle.com/photos/mugs/8476945.jpg",
"birthplace": "Commerce, MI, USA",
"age": 22,
"name": "Connor Hellebuyck",
"birthdate": "May 19, 1993",
"number": 30
}
],
"defensemen": [
{
"position": "Defenseman",
"id": 8470834,
"weight": 260,
"height": "6' 5\"",
"imageUrl": "http://2.cdn.nhle.com/photos/mugs/8470834.jpg",
"birthplace": "Roseau, MN, USA",
"age": 30,
"name": "Dustin Byfuglien",
"birthdate": "March 27, 1985",
"number": 33
}
]
There is a lot more data than shown above, multiple goalies, defensemen and forwards. Currently I'm using a for loop to loop through goalies, then another one to loop through defensemen and so on. Is there a way to loop through every player regardless of the property name, not sure if that's the right term... if not please correct me.
Thanks

Yes there is! In PHP, looping over objects ( or associative arrays, or dictionaries ) is done in the same way as looping over arrays ( indexed arrays, or lists ). So nested looping is your friend. Let's say your huge data structure was saved to a variable called $everyone
<?php
foreach ($everyone as $playergroup => $players) {
foreach ($players as $player) {
// now you can operate on each player
}
}
?>

Related

pagination with this json data using php

i am sending this to the API and receiving this in return
URL/list?limit=10&page=1
{
"code": 1,
"data": {
"current_page": 1,
"data": [
{
"id": 30,
"first_name": "jack",
"last_name": null,
},
{
"id": 31,
"first_name": "Bean",
"last_name": null,
},
{
"id": 32,
"first_name": "Stock",
"last_name": null,
},
{
"id": 33,
"first_name": "Tangled",
"last_name": null,
},
{
"id": 34,
"first_name": "Anna",
"last_name": null,
},
{
"id": 104,
"first_name": "Tom",
"last_name": "M",
}
],
"from": 1,
"last_page": 2,
"last_page": 2,
"next_page_url": "URL/list?page=2",
"path": "URL/list",
"per_page": "10",
"prev_page_url": "NULL",
"to": 10,
"total": 19
},
"msg": "Success"
}
now what i want to do is do a simple pagination but i do not know how to go about it using this particular data can some one please help me out what i think should be used is a bit of PHP jquery(AJAX) and html
but i can no seem to get it i am very new to this and if some one could help me out it would be great
Please note i have no control over what the JSON Data thus i can not change it
Cannot post as a comment due to low reputation but I do want to say this.
StackOverflow isn't a place where you can just pawn off your dirty work on others here. You have to at least give your best shot and tell us where you're stuck with in order for people to help you.
Here's a few resources on learning Pagination with PHP as well as several other answers on this site that help others with Pagination.
http://www.phpfreaks.com/tutorial/basic-pagination
Simple PHP Pagination script
http://codingcyber.org/simple-pagination-script-php-mysql-5882/
Most of these scripts you find will include MySQL, but for your array you would use array_split() in your case. Unless the data you're providing is also from MySQL then these will work great for you.

PHP - Best Way to Construct Timeline Data From Sets of Beginning and Ending Timestamps

I have a series of array items that looks like:
[{
"id": 1,
"start": "2017-04-05 16:27:08",
"end": "2017-04-05 16:30:45"
}, {
"id": 2,
"start": "2017-04-05 16:15:08",
"end": "2017-04-05 16:22:45"
}, {
"id": 2,
"start": "2017-04-05 16:10:08",
"end": "2017-04-05 16:17:45"
}]
I would like to build an array off of this array that will allow me to display a timeline of my items. The timeline will always have one line on the Y axis. If there are multiple items that overlap each other in the original array, those multiple items would be combined into one item.
For the above array, the result array I am looking for would look like:
[{
"start": "2017-04-05 16:10:08",
"end": "2017-04-05 16:22:45"
}, {
"start": "2017-04-05 16:27:08",
"end": "2017-04-05 16:30:45"
}]
What's the best way to do this?
This is scarily complex. If its a small number of items then maniuplating the data in PHP or Javascript will suffice, but if its a large number of items, then doing it in a database would be the way to go.
Regarding the smal number of items - you just need to
sort by start
iterate through the array and, for each item
iterate through later entries in the array to see if they intersect - and if they do merge them
This has order O(n^2) which does not scale well.
Doing this in a database with a conventional index isn't going to help much - these are great for queries filtered by (e.g.)
SELECT *
FROM table t
WHERE t.value BETWEEN $a_literal AND $another_literal
But such indices do not work for
SELECT *
FROM table t
WHERE $a_literal BETWEEN t.start and t.end
unless the ranges defined in each record are much smaller than total span of the data held in the table.
At that point the solution is to use geospatial indexing and map your time intervals to areas in a 2-D space (because MySQL does not support 1 dimensional geospatial indexing).
Hence a full solution for the problem can be implemented with order O(nlog(n)) but I've wittered on enough about that here.
DBMS are good at handling bulk operations quickly - so the brute force method described originally would run faster in the database than in PHP / Javascript - but the computing resource is easier to scale in PHP and in Javascript.
Here we are using simple foreach loop, for achieving desired output. additionally we are checking for timestamp and comparing them
Try this code snippet here
<?php
ini_set('display_errors', 1);
$json='[{
"id": 1,
"start": "2017-04-05 16:27:08",
"end": "2017-04-05 16:30:45"
}, {
"id": 2,
"start": "2017-04-05 16:15:08",
"end": "2017-04-05 16:22:45"
}, {
"id": 2,
"start": "2017-04-05 16:10:08",
"end": "2017-04-05 16:17:45"
}]';
$array= json_decode($json,true);
$result=array();
foreach($array as $key => $value)
{
if(isset($result[$value["id"]]))
{
//checking which start-time is less
if(strtotime($result[$value["id"]]["start"]) > strtotime($value["start"]))
{
$result[$value["id"]]["start"]=$value["start"];
}
//checking which end-time is greater
if(strtotime($result[$value["id"]]["end"]) < strtotime($value["end"]))
{
$result[$value["id"]]["start"]=$value["end"];
}
}
else
{
$id=$value["id"];
unset($value["id"]);
$result[$id]=$value;
}
}
print_r($result);
Output:
Array
(
[1] => Array
(
[start] => 2017-04-05 16:27:08
[end] => 2017-04-05 16:30:45
)
[2] => Array
(
[start] => 2017-04-05 16:10:08
[end] => 2017-04-05 16:22:45
)
)

Is there a way to check if value in object is set without using foreach?

I have the following JSON object:
{
"screen": 1,
"parameters": {
"title": "Fill in the form:",
"values": [
{
"id": 13,
"type": 2,
"name": "A",
"label": "Lorem ipsum",
"value": 10
},
{
"id": 14,
"type": 2,
"name": "B",
"label": "Lorem ipsum",
"value": 20
}
]
}
}
In the code I access the values using $screen = /*object*/; $screen->parameters->values.
Is there a fast way to check if the values of answer A and B are filled in? I tought something like this:
if(isset(A) && isset(B)) { ... }
For those who are interested, I use laravel 5, maybe there is a method for it?
It looks like I need an foreach, but I rather avoid those in this case...
Nope, not with the current structure. You could however change the structure a bit to support this. You could use an object instead of an array and use the name as keys:
{
"screen": 1,
"parameters": {
"title": "Fill in the form:",
"values": {
"A":{
"id": 13,
"type": 2,
"label": "Lorem ipsum",
"value": 10
},
"B":{
"id": 14,
"type": 2,
"label": "Lorem ipsum",
"value": 20
}
]
}
}
You could then use your isset method.
isset( $screen->parameters->values->A );
You can still loop over the values as you can turn this whole thing in an associative array by passing true to json_decode as a second parameter. I for one am not a big fan of my own answer, and would probably just loop the thing, but it may still answer your question.
edit: I forgot that if you add true to json_decode, you also access your properties like this:
isset( $screen['parameters']['values']['A'] );

Remove the {1} from an array of objects

I want my $row->responses object to look like so:
"responses": [
{
"id": 1381822,
"user_id": 45313,
"respondent_name": "JP Pullen",
"response_time": 1424127673,
"is_root_response": true,
"response_tree_id": 1377018,
"project_users_id": 74311,
"display_name": "Mobile 2",
"lft": 1,
"rgt": 2,
"response_read": true,
"body": "Sure it really is was great I purchased choclate at my local grocery store.",
"answers": [ ],
"avatar_url": null,
"mtime": null,
"media_list": [ ]
},
Yet my $row->responses object looks like:
"responses": {
"1": {
"id": 1381825,
"user_id": 45167,
"respondent_name": "First Name Last Name",
"response_time": 1424128177,
"is_root_response": true,
"response_tree_id": 1377021,
"project_users_id": 74312,
"display_name": "SimonSays",
"lft": 3,
"rgt": 4,
"response_read": false,
"body": "What's up!",
"answers": [ ],
"avatar_url": "https:\/\/portalvhds5kcv8nfhdz8zn.blob.core.windows.net\/user-45167\/avatar-50x50",
"mtime": 1420206441,
"media_list": [ ]
}
}
How do you get rid of the stupid {1} in the object. I didn't get it until I had to loop through the objects and unset one of them. I am not a PHP expert. Strongly Typed FTW lol.
foreach($row->responses as $elementKey => $element)
^ That is how I looped through the responses object to unset one:
unset($row->responses{$elementKey});
When arrays are encoded using json_encode() PHP will determine whether it should use array syntax (square brackets) or object syntax (curly brackets). In this case, the first array index is 1 instead of 0 so it can't reliably be encoded as a JavaScript array.
To prevent this from happening, you can use array_values() to renumber the array to be 0-based again:
$row->responses = array_values($row->responses);

json_encode() on a multidimensional array - with string keys

I am creating an very large multidimensional array using PHP. Each object contains Name, ID, ParentID and Children. Children is an array of more objects in the same format.
It is critical I name the IDs of each object - this helps me put each object under the correct parent. (In the code below, I use 101, 102 etc.)
However, the problem I am having is when I return the array in JSON using json_encode. Each 'Children' array is being printed as an object, not an array - as shown in the JSON code below.
As I read on another SO thread here, they "are made as objects because of the inclusion of string keys" - although they are numbers, they are still strings.
{
"101": {
"ID": "101",
"ParentID": "0",
"Name": "Root One"
"Children": {
"102": {
"ID": "102",
"ParentID": "101",
"Name": "Child One"
},
"103": {
"ID": "103",
"ParentID": "101",
"Name": "Child Two",
"Children": {
"104": {
"ID": "104",
"ParentID": "103",
"Name": "Child Child One"
}
}
},
Does anyone know how to overcome this issue?
Edit: The JSON should look like this (the square brackets are important!):
[
{
"ID": "101",
"ParentID": "0",
"Name": "Root One",
"Children": [
{
"ID": "102",
"ParentID": "101",
"Name": "Child One",
"Children": [
A JSON array has no explicit indexes, it's just an ordered list. The only JSON data structure that has named keys is an object. The literal should make this quite obvious:
["foo", "bar", "baz"]
This array has no named indices and there isn't any provision to add any.
PHP conflates both lists and key-value stores into one array data type. JSON doesn't.
This is your object:
$parent=new StdClass();
$parent->ID=101;
$parent->ParentID=0;
$parent->Name='Root One';
$child1=new StdClass();
$child1->ID=1011;
$child1->ParentID=$parent->ID;
$child1->Name='Child One';
$parent->Children[]=$child1;
$child1_1=new StdClass();
$child1_1->ID=10111;
$child1_1->ParentID=$child1->ID;
$child1_1->Name='Child One One';
$child1->Children[]=$child1_1;
This is your JSON convert function:
echo json_encode($parent,JSON_PRETTY_PRINT);
and this is your object coded into JSON format:
{
"ID": 101,
"ParentID": 0,
"Name": "Root One",
"Children": [
{
"ID": 1011,
"ParentID": 101,
"Name": "Child One",
"Children": [
{
"ID": 10111,
"ParentID": 1011,
"Name": "Child One One"
}
]
}
]
}
The answer came later because I started learning PHP later. Anyway, some day, someone might find it useful.
I have now got a working solution which is fast and works well.
Firstly, as written in SO link from the question;
In JSON, arrays only have numeric keys, whereas objects have string
properties. The inclusion of a array key forces the entire outer
structure to be an object by necessity.
In JSON; Curly braces hold objects ({}), Square brackets hold arrays ([]).
So using a string as a key will result in the json_encode function returning objects, whereas reseting the keys will ensure it creates arrays.
Therefore, just before I return my JSON encoded string, I run a function to reset all the array keys. The code I found on this SO thread (Reset array keys in multidimensional array) was particularly useful!
http://php.net/manual/en/function.json-decode.php
Set 2nd parameter of json_decode to true to atleast get assoc arrays.
Aside from that: javascript can't handle non-sequential/non-contiguous array indexes, so as soon as the id's are not sequential, json has no other option then to convert it into "string" indexes.

Categories