I am making use of an available API to send requests and receive the results which is in json and xml formats. I am able to do so but how do I display the returned data properly?
I used json_decode and assign the xml data to an array and print_r those. It shows up in a huge junk of data.
How do I show it on a table form? Or must I save the data into individual files or database first before displaying?
I am new to PHP, thus not sure how to implement this.
JSON is a multidimensional-array, the easiest way to view it, in my opinion, is to just
var_dump($json_array);
Though, this may be the chunk of data you're referring to.
It's not a very table friendly format, as a table is inherently 2-dimensional, and JSON can be many-dimensional.
You can flatten the array, and then display it as a table.
function flatten_json($json, &$flat, $key) {
// First check the base case: if the arg is not an array,
// then it's data to be inserted in the flat array.
if (!is_array($json)) {
$flat[$key] = $json;
} else {
// It's an array, to reduce the depth of the json,
// we remove this array, by iterating through it,
// sending the elements to be checked if they're also arrays,
// or if they're data to be inserted into the flat array.
foreach ($json as $name => $element) {
flatten_json($element, $flat, $key.'_'.$name);
}
}
}
To use this function, you first declare you flat array:
$flat = array();
Then pass it to the function, with your json, and a key you want to be the outer key, if you are sure that your json is an array, which is pretty much guaranteed, you can leave the key empty.
flatten_json($json_array, $flat, '');
Now $flat will have the flattened json, and you can print it as a table, maybe into a csv if you have many json results to print.
If your json was:
array(
'person' => array(
'name' => 'timmy',
'age' => '5'
),
'car' => array(
'make' => 'ford',
'engine' => array(
'hp' => 260,
'cyls' => 8
)
)
)
Then $flat will look like:
array(
'person_name' => 'timmy',
'person_age' => 5,
'car_make' => 'ford',
'car_engine_hp' => 260,
'car_engine_cyls' => 8
)
and if you wanted printed in a nice html table:
echo "<table><tr>";
foreach ($flat as $header => $value) {
echo "<th>$header</th>;
}
echo "</tr><tr>";
foreach ($flat as $header => $value) {
echo "<td>$value</td>";
}
echo "</tr></table>";
I am slight confuse. but if you're referring to an xml file that will appear somethign like this :
<books>
<book published="2011-07-24 19:40:26">
<title>I left my heart on Europa</title>
<author>Ship of Nomads</author>
< /book>
<book published="2011-07-24 19:40:26">
<title>I left my liveron Europa</title>
<author>Ship of Nomads</author>
< /book>
</books>
You can do some php trick here by using simplexml_load_file.
Example from the above xml you can have this code :
$mybooks= simplexml_load_file('books.xml');
echo "<ul id="booklist">";
foreach ($mybooks as $bookinfo):
$title=$bookinfo->title;
$author=$bookinfo->author;
$date=$bookinfo['published'];
echo "<li><div class="title">".$title."</div><div class="author">by ".$author."</div><b>".$date."</b></li>";
endforeach; echo "</ul>";
Hope this helps.
Related
An app developer would like to receive data from my API in the following JSON format:
{"response":1,"values":[{"brid": 31,"description": "Painter"},{"brid":33,"description":"Plumber"}]}
I managed to produce this:
{"result":[{"response":1},{"brids":["1","2","3","4","5"]},{"descriptions":["Plumber","Carpenter","Electrician","Mason","Painter"]}]}
By using this code:
$result=array();
$result[]['response']=intval(1);
$result[]['brids']=$brids;
$result[]['descriptions']=$descriptions;
$response["result"]=$result;
echo json_encode($response);
And I managed to produce this:
{"response":1,"0":{"brid":1,"description":"Plumber"},"1":{"brid":2,"description":"Carpenter"},"2":{"brid":3,"description":"Electrician"},"3":{"brid":4,"description":"Mason"},"4":{"brid":5,"description":"Painter"}}
by using this code:
$test=array();
$test['response']=intval(1);
for ($i=0;$i<count($brids);$i++)
{
$value=array();
$value['brid']=intval($brids[$i]);
$value['description']=$descriptions[$i];
$test[]=$value;
}
echo json_encode($test);
How do I satisfy the developer?
Albert
Loop over one of the arrays (both have to be of the same size) a foreach is simplest using the form that captures the key $i in your code.
Build a temp array containing the inner objects
Then simpy add them to the outer array
$descriptions = ["Plumber","Carpenter","Electrician","Mason","Painter"];
$brids = [31,32,33,34,35];
$out['response'] = 1;
foreach ( $brids as $i => $brid ){
$t = ['brid' => $brid, 'description' => $descriptions[$i]];
$out['values'][] = $t;
}
echo json_encode($out);
RESULT
{
"response":1,
"values":[
{"brid":31,"description":"Plumber"},
{"brid":32,"description":"Carpenter"},
{"brid":33,"description":"Electrician"},
{"brid":34,"description":"Mason"},
{"brid":35,"description":"Painter"}
]
}
You were almost there. You just need to wrap your values array into a key in existing response.
$test=array();
$test['response']=intval(1);
$testValues=array()
for ($i=0;$i<count($brids);$i++)
{
$value=array();
$value['brid']=intval($brids[$i]);
$value['description']=$descriptions[$i];
$testValues[]=$value;
}
$test['values']=$testValues;
echo json_encode($test);
you're pretty close, this should work:
$test = [
'response' => 1,
'values' => []
];
for ($i=0;$i<count($brids);$i++){
$test['values'][] = (object) [
'brid' => intval($brids[$i]),
'description' => $descriptions[$i]
];
}
echo json_encode($test);
so instead of pushing directly to $test with $test[], you push to its value attribute
Be aware that $descriptions[$i] inside the for it's a bit risky, there might be few elements in $descriptions than in $birds (at least for the code you have provided)
Originally I was taking an uploaded .csv file and iterating through the values one row at a time.. with the below while loop.
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
var_dump($data);
$importIt = $repo->impThreeCSV($which, $data);
}
I have redone the .csv upload functionality to now be a web form where I send json to the PHP file on a 'save button'. I now have a variable with multiple associative arrays in it..
$fd = json_decode($df, true);
var_dump($fd);
For instance the dump above contains multiple arrays such as below: i.e. (~300 similar arrays as below).
array (size=806)
0 =>
array (size=18)
'ATM_ID' => string 'AFF-MIL-TWR' (length=11)
'FAC_IDENT' => string 'AFF' (length=3)
'LG_NAME' => string 'BLACH BLAH ACADEMY' (length=20)
'BASIC_TP' => string 'MIL-TWR' (length=7)
.................
How can I iterate through the VALUES only in these arrays, one at a
time in the same fashion as my original while loop.. (this would be
ideal so I don't have to redo the whole back-end).
I am having issues handling the multiple arrays and getting the
values only out..
I have tried the below two attempts, I just get 'arrayarrayarray' or
similar in var_dump. Do I need to break out each array into it's
own var? What am I doing wrong here? Do I need to run a count on how
many arrays consist in my var?
$fd = json_decode($df, true);
var_dump($fd);
$data = array_values($fd);
foreach ($data as $array_key) {
echo $array_key;
}
$array_keys = array_keys($fd);
foreach ($array_keys as $array_key) {
echo $array_key;
}
P.S. No, I can't use pandas, I wish.
Assuming you want to process the data in the same way as your original piece of code, you would just use something like:
foreach ($fd as $data) {
$importIt = $repo->impThreeCSV($which, array_values($data));
}
Note I've used array_values to convert $data from an associative array to a numerically indexed one, i.e. the same format as fgetcsv returns. This may - dependent on your $repo->impThreeCSV code - not be necessary.
You need to do a foreach to loop through each array, and then do another foreach to loop through every value of the array you're looping through.
$decodedJson = [
[
'ATM_ID' => 'AFF-MIL-TWR 1',
'FAC_IDENT' => 'AFF',
'LG_NAME' => 'BLACH BLAH ACADEMY',
'BASIC_TP' => 'MIL-TWR',
],
[
'ATM_ID' => 'AFF-MIL-TWR 2',
'FAC_IDENT' => 'AFF',
'LG_NAME' => 'BLACH BLAH ACADEMY',
'BASIC_TP' => 'MIL-TWR',
],
];
foreach ($decodedJson as $array) {
foreach ($array as $item) {
print $item; # => AFF-MIL-TWR 1
}
}
I am trying to access data from a multidimensional array. Array $o contains arrays of with the key: product_id. The child array 'data' contains key => value pairs (or at least I think it does). The problems is that when I try to access the data later on: nothing is working.
Question: How can I access this data as expected in a key => value pair method that works (like foreach($o[$_product_id]['data'] as $_attr => $_value))
Original data
$_product_id=1;
$h = array('header1','header2','header3');
$line= array(1,2,3);
$o[$_product_id]['data'] = array_combine($h,array_map('trim', $line));
I var_dumped $o[$_product_id]['data'] and I can see the data is there
$data =
array (
'header1' => 1,
'header2' => 2,
'header3' => 3,
);
Help appreciated
=======================
Loading data original method
$o[$_product_id]['data'] = array_combine($h,array_map('trim', $line));
Loading data alternative method
foreach ($h as $_atr) {
$o[$_product_id]['data'][$_atr] = trim(array_shift($line));
}
Accessing data: not working as expected
foreach($o[$_product_id]['data'] as $_attr => $_value)
echo $_attr;
echo $_value;
Okay, your problem is that your code:
foreach($o[$_product_id]['data'] as $_attr => $_value)
echo $_attr;
echo $_value;
is equivalent to:
foreach($o[$_product_id]['data'] as $_attr => $_value) {
echo $_attr;
}
echo $_value;
See? You iterate over array, but output only keys, and last value after the end.
And yes, this is the standard behaviour of a foreach without {} - after foreach definition only one line runs in a loop. All other lines are considered out of the loop. Yep, that's not like in python).
So the fix is simple - add {}:
foreach($o[$_product_id]['data'] as $_attr => $_value) {
echo $_attr;
echo $_value;
}
I want to find a way to drill down into the $_FILES array and retrieve the [type] => Array in its entirety. I have tried a number of approaches can't get anywhere with this:
$result = preg_grep('/\image\b/', $_FILES);
When I output $result in this manner:
echo '<pre>';
print_r($result);
echo '</pre>';
I get the following:
Array (
)
Which is of course useless. I've been going through the Manual, looking at all the array functions, but haven't found anything that works. Is there a PHP function for this? Any help would be very much appreciated!
Cheers,
shackleton
PS I've also tried to use:
foreach ($_FILES['userfile']['type'] as $key => $value) {
to create my own array with both the key and value of each file uploaded. The problem with that is the variable will not create an array with more than one - [0] - index because the array construct is referencing the variable. That seems to be a dead end.
If you're sending multiple files, you should iterate using $_FILES only, as this:
$types=array();
foreach($_FILES as $filename=>$arrayofvalues){
$types[]=$arrayofvalues['type'];
}
Holla Ricardo,
Thanks so much, that works like a charm. I had to go find a way to flatten the resulting array, but did find a function online that works. I had been looking for that function too for several days. Here's what I came up with:
// Create an array of only the file type
$types = array();
foreach ($_FILES as $filename => $arrayofvalues) {
$types[] = $arrayofvalues['type'];
}
// Create a sub-array of types
foreach($types as $subArray) {
foreach($subArray as $val){
$simple[] = $val;
}
}
echo "Simple images array:";
echo '<pre>';
print_r($simple);
echo '</pre>';
"<br />";
// Get the key & value of just image files
$images = preg_grep('/\image\b/', $simple);
// Use the differenc array function to find the indices I want
$dif = array_diff($simple, $images);
echo "Difference:";
echo '<pre>';
print_r($dif);
echo '</pre>';
"<br />";
Of course the print_r() is only so I can see what the code is producing. The output looks like this:
html Output
Thanks again for you assistance!
Cheers,
shackleton
Your approach is a bit heavy-handed with the foreach loops. I have prepared a shorter way to accomplish your task.
Using this array:
$FILES=array(
"file1"=>array("type"=>array("text/plain")),
"file2"=>array("type"=>array("image/tiff")),
"file3"=>array("type"=>array("")),
"file4"=>array("type"=>array("image/png")),
"file5"=>array("type"=>array("image/gif")),
"file6"=>array("type"=>array("image/jpeg"))
);
You can have your output with these two one-liners:
$simple_images=array_column(array_column($FILES,"type"),0);
var_export($simple_images);
echo "\n";
$difference=array_filter($simple_images,function($v){return strpos($v,"image")===false;});
var_export($difference);
Output:
array (
0 => 'text/plain',
1 => 'image/tiff',
2 => '',
3 => 'image/png',
4 => 'image/gif',
5 => 'image/jpeg',
)
array (
0 => 'text/plain',
2 => '',
)
Referring to your preg_grep() function, it is best to avoid using regex when another string manipulation will suffice. This is will improve performance.
Basically I currently put a bunch of values into an array like so:
$flavors = array('Original','Cherry','Chocolate','Raspberry','Mango');
and from this I might execute a foreach like so:
foreach($flavors as $flav) {
echo doSomething($flav);
}
This all works a treat, until I get to the next stage of my learning which is to perhaps put 2 variables into doSomething().
For example, say I want to include the ingredients of Cherry e.g
echo doSomething($flav, $ingredient_of_this_flav);
I'm not sure if there is any way to go about doing this... I imagine I might need a second array entirely where I use the values above as my keys? e.g
$ingredients = array('Original' => 'boring stuff', 'Cherry' => 'cherries and other stuff') etc
And then I would doSomething() like so
foreach($flavors as $flav) {
echo doSomething($flav, $ingredients[$flav]);
}
I suppose I should go try this now. Is this the best approach or is there a better way to go about this? Ideally I would just have the one array not have to set $flavors and $ingredients.
Thanks for your time.
Arrays in php are associative, as you've noticed. And if I understand correctly, you're looking for the syntax to loop through each key/value pair?
foreach($ingredients as $flav => $ingredient) {
echo doSomething($flag, $ingredient);
}
Is this what you're looking for?
If you're looking to have complex values for each key, than you might want to look into objects, or the more brutal version, arrays of arrays.
$ingredients = array('Cherry' => array('Cherries', 'Other stuff'));
And your $ingredient in the loop above will be an array.
You can foreach over the keys and values of an array.
foreach ($ingredients as $flav => $ingredients)
{
echo doSomething($flav, $ingredients);
}
I would use an associative array (aka hash table) with a flavor => ingredients approach. Something like this:
$flavors = array ('Cherry' => array('stuff1', 'stuff2'),
'Mango' => array('stuff1', 'stuff3'));
echo $flavors['Cherry'][0]; // stuff1
foreach($flavors as $flavor => $ingredients)
{
print $flavor;
// $ingredients is an array so we need to loop through it
foreach($ingredients as $ingredient)
{
print $ingredient;
}
}
This is known as a nested loop and will print the flavor and each ingredient.
You are nearly there. I would set the array to be something like:
$ingredients = array('Original' => array('boring stuff', 'boring stuff2'), 'Cherry' => array('cherries', 'other stuff'));
And then loop as follows:
foreach($flavors as $flav => $ingredient) {
echo doSomething($flav, $ingredient);
}
Of course, it all depends on what you do in "doSomething()"