Creating Multiple JSON Object Elements Programmatically using PHP - php

I need to create a JSON object, in PHP, with the following form
{
"Routes": [{
"route_ID": "49",
"geom": [{
"lat": "-30.63607",
"lng": "147.499935"
}, {
"lat": "-30.63631",
"lng": "147.499868"
}]
},
{
"route_ID": "50",
"geom": [{
"lat": "-30.63607",
"lng": "147.499935"
}, {
"lat": "-30.63631",
"lng": "147.499868"
}]
}
]
}
The problem with my code is that I can't seem to find a way of concatenating the JSON elements from the $jsonString, The code as it is just produces "route_ID": "50".
(Yes I agree there are a great many questions on stackoverflow on this question, but they just about all refer to single elements derived from a static array). By the way, I am given the $jsonString and need to preprocess it in the code below.
$jsonString = "[{\"route_ID\":\"49\",\"geom\":\"<LineString><coordinates>147.499935,-30.63607 <\\/coordinates><\\/LineString>\"},{\"route_ID\":\"50\",\"geom\":\"<LineString><coordinates>147.499935,-30.63607<\\/coordinates><\\/LineString>\"}]";
/* PHP Code */
$jsonArray = json_decode($jsonString, true);
$json = new stdClass();
$json_Routes = new stdClass();
$route_geom_Array = array();
foreach ($jsonArray as $record) {
print_r($record);
$geomString = $record["geom"];
$geomString = str_replace('<LineString><coordinates>', ' ', $geomString);
$geomString = str_replace('</coordinates></LineString>', ' ', $geomString);
$geomString = trim($geomString);
$route_geom_Array = explode(' ', $geomString);
for ($i = 0; $i < sizeof($route_geom_Array); $i++) {
$var = explode(',', $route_geom_Array[$i]);
$route_geom[] = array('lat' => $var[1], 'lng' => $var[0]); // lat long
}
$json->route_ID = $record["route_ID"]; //<- Problem area
$json->geom = $route_geom; //<- Problem area
}
$json_Routes->Routes = $json;
$jsonArray = json_encode($json_Routes);
echo $jsonArray;
exit ();`
Can someone give me a clue on how do this.
Thanks

You need to make $json_Routes->Routes an array and push the $json structures within the foreach block, e.g.:
$json_Routes->Routes = [];
foreach ($jsonArray as $record) {
// Existing code ...
$json_Routes->Routes[] = $json;
}

You need to push objects to array, here solution :
$jsonArray = json_decode($jsonString, true);
$json_Routes = new stdClass();
$route_Array = [];
$route_geom_Array = [];
$route_ID_Array = [];
$items = [];
$index = 0;
foreach ($jsonArray as $record) {
//print_r($record);
$geomString = $record["geom"];
$geomString = str_replace('<LineString><coordinates>', ' ', $geomString);
$geomString = str_replace('</coordinates></LineString>', ' ', $geomString);
$geomString = trim($geomString);
$route_geom_Array = explode(' ', $geomString);
for ($i = 0; $i < sizeof($route_geom_Array); $i++) {
$var = explode(',', $route_geom_Array[$i]);
$route_geom[] = array('lat' => $var[1], 'lng' => $var[0]); // lat long
}
$json = new stdClass();
$json->route_ID = $record["route_ID"]; //<- Problem area
$json->geom = $route_geom; //<- Problem area
array_push($route_Array,$json);
}
$json_Routes->Routes = $route_Array;
$result = json_encode($json_Routes);
echo $result;
exit();

Related

Why my code insert only one to DB when i use foreach

I need to insert data to database by use foreach
But my code only insert last one, Please help me to find out why?
Post Data
{
"APIPassword": "Test",
"Method": "Transfer",
"Data": [
{
"Account": "Test01",
"Amount": 100,
"TransactionNo": "Test1",
"dbID": "Bet1"
},
{
"Account": "Test02",
"Amount": -100,
"TransactionNo": "Test2",
"dbID": "Bet2"
}
]}
My Code
$apiPassword = $data['APIPassword'];
$method = $data['Method'];
$datas = $data['Data'];
$db = new db();
foreach ($datas as $data) {
$db->userId = '1';
$db->account = $data['Account'];
$db->amount = (float) $data['Amount'];
$db->transactionNo = $data['TransactionNo'];
$db->dbID = $data['dbID'];
$db->save();
}
Result when submit
"Account": "Test02",
"Amount": -100,
"TransactionNo": "Test2",
"db": "Bet2"
You need to instantiate a new db object each time in the for loop, in your current code you are using the same object on each iteration of the loop.
Change your code to this:
$apiPassword = $data['APIPassword'];
$method = $data['Method'];
$datas = $data['Data'];
foreach ($datas as $data) {
$db = new db();
$db->userId = '1';
$db->account = $data['Account'];
$db->amount = (float) $data['Amount'];
$db->transactionNo = $data['TransactionNo'];
$db->dbID = $data['dbID'];
$db->save();
}
What is $db = new db();, does db corresponds to a model? Try like this:
foreach ($datas as $data) {
$db = new db(); // <-- Important part
$db->userId = '1';
$db->account = $data['Account'];
$db->amount = (float) $data['Amount'];
$db->transactionNo = $data['TransactionNo'];
$db->dbID = $data['dbID'];
$db->save();
}
Perhaps in a later stage of your app you may want to update records. If dbID is your unique record key, you will do something like:
foreach ($datas as $data) {
$item = db::findFirst([
'conditions' => 'dbID = :dbID:',
'bind' => [
'dbID' => $data['dbID']
]
]);
// Record does not exist in our DB - skip or even create it?
if ($item === false) {
continue;
}
// Proceed with updating data
$item->account = $data['Account'];
$item->amount = (float) $data['Amount'];
$item->transactionNo = $data['TransactionNo'];
$item->save();
}

JSON decode any value - $var1 = $data['val1']['anyvalue']['val2'];

I am pulling in JSON data for a mySQL import and in setting the variables after my JSON decode statements of my JSON file I am struggling with something. My variable setting looks like so
$name = $data['available_channels']['3']['name'];
and the relevant JSON like this
"available_channels": {
"3": {
"num": 152,
"name": "Sky Sports 3",
"stream_type": "live",
"type_name": "Live Streams",
"stream_id": "3",
"stream_icon": "http://www.tv-logo.com/pt-data/uploads/images/logo/sky_uk_sports3.jpg",
"epg_channel_id": "Sky Sports 3",
"added": "0",
"category_name": "Sports UK",
"category_id": "5",
"series_no": null,
"live": "1",
"container_extension": null,
"custom_sid": ":0:86:EEE:7F2:2:11A0000:0:0:0:",
"tv_archive": 0,
"direct_source": "",
"tv_archive_duration": 0
},
My problem is that each channel for the service begins with a new number. So i need my variables to be pulled in like so,
$name = $data['available_channels']['ANY VALUE HERE']['name'];
any thoughts? I know it must be simple and I am having a blonde moment here
Thanks
UPDATE 1
//convert json object to php associative array
$data = json_decode($jsondata, true);
//get the values and asign variables
$name = $data['available_channels']['3']['name'];
UPDATE 2
Full Code Now
$data = json_decode($jsonFile, true);
for($i = 0; $i <= count($data['available_channels']); $i++){
$name = $data['available_channels'][$i]['name'];
$num = $data['available_channels'][$i]['num'];
$epg_channel_id = $data['available_channels'][$i]['epg_channel_id'];
$category_name = $data['available_channels'][$i]['category_name'];
$stream_icon = $data['available_channels'][$i]['stream_icon'];
//insert into mysql table
$sql = "INSERT INTO channels(name, num, epg_channel_id, category_name, stream_icon)
VALUES('$name', '$num', '$epg_channel_id', '$category_name', '$stream_icon')";
if(!mysql_query($sql,$con))
{
die('Error : ' . mysql_error());
}
}
Gets about 117 of 234 rows in but the other rows are blank... any thoughts
$name = array_values($data['available_channels'])[0]['name'];
array_values returns a new array consisting of the values of the source array, renumbered from 0.
You can count the number of channels inside the array, then loop through each channel.
for($i = 0; $i <= count($data['available_channels']); $i++) {
$name = $data['available_channels'][$i]['name'];
// TODO: Do something with the name
}
Or you could do what #cske said:
$channels = [];
foreach($data['available_channels'] as $k => $v) {
// this will keep the key's the same
$channels[$k] = $v['name'];
}
Or you could choose a more OO styled approach, see it working at 3v4l:
class Channel {
private $_data;
public function __construct($json) {
$this->_data = json_decode($json, true);
}
public function parse() {
$parsed = [];
foreach($this->_data['available_channels'] as $k => $v) {
$parsed[$k] = $v['name'];
}
$this->_data['available_channels'] = $parsed;
return $this;
}
public function getByKey($key) {
return $this->_data['available_channels'][$key];
}
}
$c = new Channel($json_response);
echo 'Name for Channel 3 is: ' . $c->parse()->getByKey('3');
So after update 2, this will work
foreach($data['available_channels'] as $d) {
$name = $d['name'];
$num = $d['num'];
$epg_channel_id = $d['epg_channel_id'];
$category_name = $d['category_name'];
$stream_icon = $d['stream_icon'];
//insert into mysql table
$sql = "INSERT INTO channels(name, num, epg_channel_id, category_name, stream_icon)
VALUES('$name', '$num', '$epg_channel_id', '$category_name', '$stream_icon')";
if (!mysql_query($sql, $con)) {
die('Error : ' . mysql_error());
}
}
Or if with for loop #KDOT answer, but corrected by #Niet the Dark Absol code
$data['available_channels'] = array_values($data['available_channels']);
for($i = 0; $i <= count($data['available_channels']); $i++) {
$name = $data['available_channels'][$i]['name'];
...
}
That is simply not true if a php array has count()=5 then it's keys are 0,1,2,3,4 what couses missing rows with KDOT's answer

Filtering JSON data with php

I am trying to iterate over this json file and filter out the unwanted elements I would like to split the result so I have have a list of Customers or a list of Suppliers
json File:
{
"$descriptor": "Test",
"$resources": [
{
"$uuid": "281d393c-7c32-4640-aca2-c286f6467bb1",
"$descriptor": "",
"customerSupplierFlag": "Customer"
},
{
"$uuid": "87a132a9-95d3-47fd-8667-77cca9c78436",
"$descriptor": "",
"customerSupplierFlag": "Customer"
},
{
"$uuid": "8a75345c-73c7-4852-865c-f468c93c8306",
"$descriptor": "",
"customerSupplierFlag": "Supplier"
},
{
"$uuid": "a2705e38-18d8-4669-a2fb-f18a87cd1cc6",
"$descriptor": "",
"customerSupplierFlag": "Supplier"
}
]
}
for example
{
"$uuid": "281d393c-7c32-4640-aca2-c286f6467bb1",
"$descriptor": "",
"customerSupplierFlag": "Customer"
},
{
"$uuid": "87a132a9-95d3-47fd-8667-77cca9c78436",
"$descriptor": "",
"customerSupplierFlag": "Customer"
},
my php code is
$array = json_decode($result, true);
for ($i = 0; $i < count($array['$resources']); $i++){
foreach ($array['$resources'][$i]['customerSupplierFlag'][Customer] as $item)
{
// do what you want
echo $item['customerSupplierFlag' ]. '<br>';
echo $item['$uuid'] . '<br>';
}
}
I have been struggling with this for a few days now an appear to be going over the same articles and getting now were any suggestions would be appreciated.
$data = file_get_contents('./your_json_data.txt');
$json = json_decode($data, 1);
$resources = $json['$resources'];
$suppliers = array();
$customers = array();
foreach ($resources as $rkey => $resource){
if ($resource['customerSupplierFlag'] == 'Customer'){
$customers[] = $resource;
} else if ($resource['customerSupplierFlag'] == 'Supplier') {
$suppliers[] = $resource;
}
}
header('Content-Type: application/json');
echo json_encode($customers);
echo json_encode($suppliers);
die();
$array = json_decode($json, true);
$flag = "Supplier";
$resources = array_filter($array, function ($var) use ($flag) {
return ($var['customerSupplierFlag'] == $flag);
});
print_r($resources);
$json_a = json_decode($string, true);
foreach($json_a as $jsonDataKey => $jsonDataValue){
foreach($jsonDataValue as $jsonArrayKey => $jsonArrayValue){
print_r($jsonArrayValue['id']);
print_r($jsonArrayValue['name']);
}
}

foreach inside static array

How can I replace the locations here with a foreach loop? When I put the foreach inside of the array, the code breaks. I guessing the answer has to do with creating a foreach variable and then entering that for the levels value instead?
This is my array
$data = array(
'name' => Locations,
'data' => '{
"title":"USA",
"location":"World",
"levels":[
{
"id":"states",
"title":"States",
"locations":[
{
"id":"ca",
"title":"California",
"pin":"hidden",
"x":"0.0718",
"y":"0.4546",
},
{
"id":"wa",
"title":"Washington",
"pin":"hidden",
"x":"0.1331",
"y":"0.0971"
}
]
}
]
}'
Here is my current foreach.
foreach ($response->records as $record) {
$id = $record->Id;
$title = $record->Title;
$pin = $record->Pin;
$x = $record->X;
$y = $record->Y;
echo {
"id": $id,
"title": $title,
"pin": $pin,
"x": $x,
"y": $y
}
}
Any help would be appreciated.
$arr = array();
foreach ($response->records as $record) {
$r['id'] = $record->Id;
$r['title'] = $record->Title;
$r['pin'] = $record->Pin;
$r['x'] = $record->X;
$r['y'] = $record->Y;
$arr[] = $r;
}
echo json_encode($arr);

Need help php to json array

I am having a string below
$string = ot>4>om>6>we>34>ff>45
I would like the JSON output be like
[{"name":"website","data":["ot","om","we","ff"]}]
and
[{"name":"websitedata","data":["4","6","34","45"]}]
what I've tried
$query = mysql_query("SELECT month, wordpress, codeigniter, highcharts FROM project_requests");
$category = array();
$category['name'] = 'website';
$series1 = array();
$series1['name'] = 'websitedata';
while($r = mysql_fetch_array($query)) {
$category['data'][] = $r['month'];
}
$result = array();
array_push($result,$category);
array_push($result,$series1);
print json_encode($result, JSON_NUMERIC_CHECK);
but the above code is applicable only if the data are present in rows from a mysql table, what i want is achieve the same result with the data from the above string. that is
$string = ot>4>om>6>we>34>ff>45
NEW UPDATE:
I would like to modify the same string
$string = ot>4>om>6>we>34>ff>45
into
json output:
[
{
"type" : "pie",
"name" : "website",
"data" : [
[
"ot",
4
],
[
"om",
6
],
[
"we",
34
]
]
}
]
I have updated the answer please check the json part, I would like the php code.
regards
You can explode() on the >s, and then loop through the elements:
$string = "ot>4>om>6>we>34>ff>45";
$array1 = [
'name'=>'website',
'data'=>[]
]
$array2 = [
'name'=>'websitedata',
'data'=>[]
]
foreach(explode('>', $string) as $index => $value){
if($index & 1) //index is odd
$array2['data'][] = $value;
else //index is even
$array1['data'][] = $value;
}
echo json_encode($array1); //prints {"name":"website","data":["ot","om","we","ff"]}
echo json_encode($array2); //prints {"name":"websitedata","data":["4","6","34","45"]}
A solution using preg_match_all():
$string = "ot>4>om>6>we>34>ff>45";
preg_match_all('/(\w+)>(\d+)/', $string, $matches);
$array1 = [
'name'=>'website',
'data'=> $matches[1]
];
$array2 = [
'name'=>'websitedata',
'data'=> $matches[2]
];
echo json_encode($array1); //prints {"name":"website","data":["ot","om","we","ff"]}
echo json_encode($array2); //prints {"name":"websitedata","data":["4","6","34","45"]}
Update:
To get the second type of array you wanted, use this:
//since json_encode() wraps property names in double quotes (which prevents the chart script from working), you'll have to build the json object manually
$string = "ot>4>om>6>we>34>ff>45";
preg_match_all('/(\w+)>(\d+)/', $string, $matches);
$data = [];
foreach($matches[1] as $index => $value){
if(isset($matches[2][$index]))
$data[] = '["' . $value . '",' . $matches[2][$index] . ']';
}
$type = 'pie';
$name = 'website';
echo $jsonString = '[{type:"' . $type . '",name:"' . $name . '",data:[' . implode(',', $data) . ']}]'; // prints [{type:"pie",name:"website",data:[["ot",4],["om",6],["we",34],["ff",45]]}]
Update #2:
This code uses explode(), and although it's probably not the most efficient way of doing it, it works.
//since json_encode() wraps property names in double quotes (which prevents the chart script from working), you'll have to build the json object manually
$string = "ot>4>om>6>we>34>ff>45";
$keys = [];
$values = [];
foreach(explode('>', $string) as $key => $value){
if(!($key & 1)) //returns true if the key is even, false if odd
$keys[] = $value;
else
$values[] = $value;
}
$data = [];
foreach($keys as $index => $value){
if(isset($values[$index]))
$data[] = '["' . $value . '",' . $values[$index] . ']';
}
$type = 'pie';
$name = 'website';
echo $jsonString = '[{type:"' . $type . '",name:"' . $name . '",data:[' . implode(',', $data) . ']}]'; // prints [{type:"pie",name:"website",data:[["ot",4],["om",6],["we",34],["ff",45]]}]
This should work, though there are probably better ways to do it.
$string = "ot>4>om>6>we>34>ff>45";
$website = ["name" => "website", "data" => []];
$websiteData = ["name" => "websitedata", "data" => []];
foreach(explode(">", $string) as $i => $s) {
if($i % 2 === 0) {
$website["data"][] = $s;
} else {
$websiteData["data"][] = $s;
}
}
echo json_encode($website);
echo json_encode($websiteData);
A regex alternative:
preg_match_all("/([a-z]+)>(\d+)/", $string, $matches);
$website = ["name" => "website", "data" => $matches[1]];
$websiteData = ["name" => "websitedata", "data" => $matches[2]];
Try this code:
$string = 'ot>4>om>6>we>34>ff>45';
$string_split = explode('>', $string);
$data = array("name" => "website");
$data2 = $data;
foreach ($string_split as $key => $value)
{
if (((int)$key % 2) === 0)
{
$data["data"][] = $value;
}
else
{
$data2["data"][] = $value;
}
}
$json1 = json_encode($data, JSON_NUMERIC_CHECK);
$json2 = json_encode($data2, JSON_NUMERIC_CHECK);
echo $json1;
echo $json2;
Output:
{"name":"website","data":["ot","om","we","ff"]}
{"name":"website","data":[4,6,34,45]}
Regards.
Try this snippet:
$strings = explode('>', 'ot>4>om>6>we>34>ff>45');
// print_r($string);
$x = 0;
$string['name'] = 'website';
$numbers['name'] = 'websitedata';
foreach ($strings as $s)
{
if ($x == 0) {
$string['data'][] = $s;
$x = 1;
} else {
$numbers['data'][] = $s;
$x = 0;
}
}
print_r(json_encode($string));
echo "<br/>";
print_r(json_encode($numbers));
As usual - it is long winded but shows all the steps to get to the required output.
<?php //https://stackoverflow.com/questions/27822896/need-help-php-to-json-array
// only concerned about ease of understnding not code size or efficiency.
// will speed it up later...
$inString = "ot>4>om>6>we>34>ff>45";
$outLitRequired = '[{"name":"website","data":["ot","om","we","ff"]}]';
$outValueRequired = '[{"name":"websitedata","data":["4","6","34","45"]}]';
// first: get a key / value array...
$itemList = explode('>', $inString);
/* debug */ var_dump(__FILE__.__LINE__, $itemList);
// outputs ------------------------------------
$outLit = array();
$outValue = array();
// ok we need to process them in pairs - i like iterators...
reset($itemList); // redundant but is explicit
// build both output 'data' lists
while (current($itemList)) {
$outLit[] = current($itemList);
next($itemList); // advance the iterator.
$outValue[] = current($itemList);
next($itemList);
}
/* debug */ var_dump(__FILE__.__LINE__, $itemList, $outLit, $outValue);
// make the arrays look like the output we want...
// we need to enclose them as arrays to get the exact formatting required
// i do that in the 'json_encode' statements.
$outLit = array('name' => 'website', 'data' => $outLit);
$outValue = array('name' => 'websitedata', 'data' => $outValue);
// convert to JSON.
$outLitJson = json_encode(array($outLit));
$outValueJson = json_encode(array($outValue));
// show required and calculated values...
/* debug */ var_dump(__FILE__.__LINE__, 'OutLit', $outLitRequired, $outLitJson);
/* debug */ var_dump(__FILE__.__LINE__, 'OutValue', $outValueRequired, $outValueJson);

Categories