PHP foreach on nested array - php

I am doing a GET php function on a URL and I get back the resulting response in JSON:
{
"results": [{
"text": "The 2014 BICSI Canadian Conference and Exhibition in Vancouver, British Columbia, Canada is 61 days away on April 27 - 30.",
"createdAt": "2014-02- 24T19:54:08.707Z",
"updatedAt": "2014-02-24T19:54:08.707Z",
"objectId": "ZZrZ9OgyRG"
}, {
"text": "Only 33 more days fro the 2014 BICSI Canadian Conference and Exhibition in Vancouver, Canada!",
"createdAt": "2014-03-24T13:23:56.240Z",
"updatedAt": "2014-03-24T13:23:56.240Z",
"objectId": "ZqxJRiHoJo"
}]
}
I am able to do php json_decode and display the results below on a web page like below
text | The 2014 BICSI Canadian Conference and Exhibition in Vancouver, British Columbia, Canada is 61 days away on April 27 - 30.
createdAt | 2014-02-24T19:54:08.707Z
updatedAt | 2014-02-24T19:54:08.707Z
objectId | ZZrZ9OgyRG
text | Only 33 more days fro the 2014 BICSI Canadian Conference and Exhibition in Vancouver, Canada!
createdAt | 2014-03-24T13:23:56.240Z
updatedAt | 2014-03-24T13:23:56.240Z
objectId | ZqxJRiHoJo
The php code I used to display the results above on the web page is:
$returned_content = get_data('https://api.parse.com/1/classes/Alerts');
$data = json_decode($returned_content, true);
foreach ($data as $array1 => $arrayn) {
foreach ($arrayn as $k => $v) {
foreach ($v as $t => $s) {
echo"<p> $t | $s ";
}
}
}
If I just wanted to display the 'text' key/value info only on the web page, how should I modify the php. Meaning all I want to see displayed on the web page is:
text | The 2014 BICSI Canadian Conference and Exhibition in Vancouver, British Columbia, Canada is 61 days away on April 27 – 30.
text | Only 33 more days fro the 2014 BICSI Canadian Conference and Exhibition in Vancouver, Canada!

$data = json_decode($json);
foreach ($data->results as $item) {
echo '<br>text | '.$item->text;
}
If you don't add the second json_decode() paremeter, you can just use your JSON with the StdClass.

Wrap it inside a simple if condition.
foreach ($data as $array1 => $arrayn) {
foreach($arrayn as $k => $v) {
foreach ($v as $t => $s) {
if($t == 'text') {
echo"<p> $t | $s ";
}
}
}
}

do like this
$returned_content = get_data('https://api.parse.com/1/classes/Alerts');
$data = json_decode($returned_content, true);
foreach ($data as $array1 => $arrayn) {
foreach($arrayn as $k => $v){
foreach ($v as $t => $s)
{
if($t == "text")
echo"<p> $t | $s ";
}
}
}

After this line :
$data = json_decode($returned_content, true);
You have an associative array, so you can change your loop to :
foreach ($data as $array1 => $arrayn) {
foreach($arrayn as $k => $v) {
foreach ($v as $t => $s) {
if('text' === $t) {
echo"<p> $t | $s ";
}
}
}
}

Make it simple and with a check if the key exists, just in case the JSON does not contain the key "text" it will return notice.
$data = json_decode($str,true);
foreach($data["results"] as $key=>$val){
if(array_key_exists("text",$val)){
echo 'text | '.$val["text"];
echo '<br />';
}
}
Here $str is your json string.

Related

How to explode csv array in php?

I'm pulling 5 random rows from a csv file such as an image, year, hint text and caption text:
<?php
$rows = file('Book1.csv');
$len = count($rows);
$rand = array();
while (count($rand) < 5) {
$r = rand(0, $len);
if (!in_array($r, $rand)) {
$rand[] = $r;
}
}
echo 'var cardDeck = [';
foreach ($rand as $r) {
$csv = $rows[$r];
$data = str_getcsv($csv);
echo "{\n";
echo "'image':'".$data[1]."',\n";
echo "'year':'".$data[0]."',\n";
echo "'hint':'".$data[3]."',\n";
echo "'caption':'".$data[2]."'";
echo "\n},\n";
}
?>
My output which is correct and how I want it:
var cardDeck = [{
'image':'<img class="img_card" src="https://www.floridamemory.com/onlineclassroom/game/cards/1898.png">',
'year':'1898',
'hint':'Tampa during the Spanish American War',
'caption':'1898-Early in 1898, President William McKinley sent the battleship Maine to Havana to protect American interests. The war lasted only until August, when the two belligerents signed an armistice. A final treaty was signed in December 1898. Read More'
},
{
'image':'<img class="img_card" src="https://www.floridamemory.com/onlineclassroom/game/cards/1845.png">',
'year':'1845',
'hint':'Act establishing Florida statehood',
'caption':'1845-The Act establishing statehood for Iowa and Florida was approved on March 3, 1845 by the second session of the 28th Congress. Read More'
},
{
'image':'<img class="img_card" src="https://www.floridamemory.com/onlineclassroom/game/cards/1822.png">',
'year':'1822',
'hint':'Territory of Florida Established',
'caption':'1822-This first act of Florida\'s Territorial Legislature in 1822 divided the territory into four counties and established local courts. Read More'
},
{
'image':'<img class="img_card" src="https://www.floridamemory.com/onlineclassroom/game/cards/1904.png">',
'year':'1904',
'hint':'Mary McLeod Bethune opens her school',
'caption':'1904-Mary McLeod Bethune founded the Daytona Normal and Industrial School for Negro Girls. Her school later merged with the Cookman Institute of Jacksonville in 1923 and today is known as Bethune-Cookman University. Read More'
},
{
'image':'<img class="img_card" src="https://www.floridamemory.com/onlineclassroom/game/cards/1912.png">',
'year':'1912',
'hint':'First train in Key West',
'caption':'1912-January 22, 1912 the first passenger train arrived in Key West, marking the completion of Henry Flagler\'s East Coast Railroad from Jacksonville to the Southernmost City. <a hre="https://www.floridamemory.com/blog/2013/01/22/first-train-to-key-west-january-22-1912/">Read More</a>'
},
];
But I was wondering if it was possible to list each year $data[0] and echo them individually for future use elsewhere? Like explode it or something?
Like:
<ul>
<li>1898</li>
<li>1845</li>
<li>1822</li>
<li>1904</li>
<li>1912</li>
</ul>
just walk through the array
$years = [];
foreach ($rand as $r) {
$csv = $rows[$r];
$data = str_getcsv($csv);
if (!in_array($data[0], $years)) {
$years[] = $data[0];
}
}

how can i make the array echo the array 0 if the value was between x && x

I'm doing this for school, but am currently stuck with trying to get the array to echo the car in the budget range, but i cant figure out how to do it
so what ive tried doing so far is;
if ((isset($_POST["one"])) && (!empty($_POST["one"]))) {
$hi = $_POST["one"];
$arrayName = array('2018 Ford Mustang', '2019 Honda Civic Sedan VTi-L', 'Mazda RX-7', '2018 Honda NSX', 'Jeep Cherokee', 'Jeep Grand Cherokee', '2018 Ford Focus', '2018 Ford Fiesta', 'Nissan patrol ST');
$arrayprice = array('40000', '31795', '50000', '380000', '44000', '54990', '34490', '20525', '19990');
foreach ($arrayprice as $key => $value)
{
switch ($arrayprice)
{
case $hi >= $value: echo "<p>".$arrayName[$key]."</p>"; break;
case $hi <= '20000' && $hi >= '30000': echo $arrayName["0"];
and the same thing, but instead of the zero i had [$key] '0'
if ((isset($_POST["one"])) && (!empty($_POST["one"]))) {
$hi = $_POST["one"];
$arrayName = array('2018 Ford Mustang', '2019 Honda Civic Sedan VTi-L', 'Mazda RX-7', '2018 Honda NSX', 'Jeep Cherokee', 'Jeep Grand Cherokee', '2018 Ford Focus', '2018 Ford Fiesta', 'Nissan patrol ST');
$arrayprice = array('40000', '31795', '50000', '380000', '44000', '54990', '34490', '20525', '19990');
foreach ($arrayprice as $key => $value)
{
switch ($arrayprice)
{
case $hi >= $value: echo "<p>".$arrayName[$key]."</p>"; break;
case $hi <= '20000' && $hi >= '30000': echo $arrayName[$key]'0';
i want it to output the array index that I put in as the car in that budget range. for example if the budget range is between 20000 and 30000 then it should output the ford fiesta, whereas, if the budget is between 10000 and 20000 it should output the nissan patrol st.
(I'm new to programming and all that and just asking for a friend, sorry if you can't understand what I'm trying to say or explain)
Use database and make a table with column names containing this data.
car_model_name,
price
you can easily manage those things that you want to make.
Then connect to your table and display the list of all car models
then create a condition or statement that will check if the price is in between the $hi price.
It was hard to fix your problem because you don't have any identifier connected to the car_model_name.
if (!empty($_POST["one"])) {
$hi = $_POST["one"];
$arrayName = array('2018 Ford Mustang', '2019 Honda Civic Sedan VTi-L', 'Mazda RX-7', '2018 Honda NSX', 'Jeep Cherokee', 'Jeep Grand Cherokee', '2018 Ford Focus', '2018 Ford Fiesta', 'Nissan patrol ST');
$arrayprice = array('40000', '31795', '50000', '380000', '44000', '54990', '34490', '20525', '19990');
$cars_that_fits = []; // every car you can get for your money
$max_fit = 0; // best car for your money
$max_fit_name = '';
foreach ($arrayprice as $key => $value) {
if ($value < $hi) {
$cars_that_fits[] = $arrayName[$key];
if ($max_fit < $hi) { $max_fit = $hi; $max_fit_name = $arrayName[$key]; }
}
}
}

Grouping similar records with php

I need help writing the logic of the php script which sorts data into a certain format...
Firstly the script needs to loop through each s1 value and ping an endpoint to get the ml values (more like) which are actually referencing other s1 records. this is the easy part! the data is returned like so;
Table 1
s1 | ml
----------
1 | -
2 | 3,4
3 | 2,8,9
4 | -
5 | 2
6 | 1
7 | 10
8 | -
9 | -
10 | -
Condition 1: As you can see the endpoint returns data for the s1 value telling it other s1 records are similar to other ones, but the direction of ml is not always bidirectional. sometimes, like when s1=6 the ml value is 1 however when s1=1 there isn't a ml value.
Condition 2: Again just to explain the ml records, look above and below where s1=5 (above) and where s1=2 + rec=5 (below), this script needs to realise there is already an s1 record for it's value and that it should be added there.
Condition 3: Note how when s1=2,ml=3 this is stored but when s1=3,ml=2 this is ignored because we have the reverse record.
I basically want to match all the data into 1 sorted 'profile' so it ends up in the below format which i will store in another db table of 'sorted' records.
Table 2
s1 | rec
----------
2 | 3
2 | 4
2 | 8
2 | 9
2 | 9
2 | 5
6 | 1
7 | 10
This has been racking my brains for days now, I need something thats efficient because in the end it will deal with millions of records and I'm sure there is an easy solution but i just can't figure how to start it.
I tried the following, but I'm stuck and don't know how to go further;
public function getrelated($id='', $t=''){
if($id != ""){
$get = Easytest::where('s1','=',$id)->get();
if(count($get) > 0){
$ret= array();
foreach($get as $go){
$v = explode(",", $go->s2);
foreach ($v as $e) {
if($e != $t){
$ret[$e] = $this->getrelated($e, $id);
}
}
}
if(count($ret) > 0){
return $ret;
}else{
return "";
}
}else{
return $id;
}
}else{
return "";
}
}
public function easytest(){
ob_start();
$a = array(
array("s1"=>1,"s2"=>implode(",",array()).""),
array("s1"=>2,"s2"=>implode(",",array(3,4)).","),
array("s1"=>3,"s2"=>implode(",",array(2,8,9)).","),
array("s1"=>4,"s2"=>implode(",",array()).""),
array("s1"=>5,"s2"=>implode(",",array(2)).","),
array("s1"=>6,"s2"=>implode(",",array(1)).","),
array("s1"=>7,"s2"=>implode(",",array(10)).","),
array("s1"=>8,"s2"=>implode(",",array()).""),
array("s1"=>9,"s2"=>implode(",",array()).""),
array("s1"=>10,"s2"=>implode(",",array()).""),
array("s1"=>11,"s2"=>implode(",",array(12)).","),
array("s1"=>12,"s2"=>implode(",",array(2)).",")
);
//return Easytest::insert($a);
$records = Easytest::all();
foreach ($records as $record) {
$id = $record->s1;
echo "ROW: ".$id." > ";
$record->s2 = ltrim($record->s2,",");
$ml = explode(",",$record->s2);
if(count($ml) >= 1){
foreach ($ml as $t) {
echo "RESULT: ".$t." -".print_r($this->getrelated($t, $id), true);
echo ",\n";
}
}
echo " <br><br>\n\n";
}
return ob_get_clean();
}
Ok, so I eventually solved this... esentially this is the code below;
improvements welcome :)
You need to call the function like so
related(array('searched'=>array(),'tosearch'=>array(13)));
function:
public function related($input){
$searched = $input['searched'];
$ar = array();
$bits = array();
if(count($input['tosearch']) != 0){
$get = Easytest::orWhere(function($query) use ($input)
{
foreach ($input['tosearch'] as $k=>$v) {
$query->orWhere('s2', 'LIKE', '%,'.$v.',%')->orWhere('s1', '=', $v);
}
})
->orderBy('s1', 'ASC')->get();
foreach ($input['tosearch'] as $k=>$v) {
unset($input['tosearch'][$k]);
$input['searched'][$v] = $v;
}
foreach ($get as $result) {
$thesebits = explode(",", trim($result->s2,","));
foreach ($thesebits as $smallbit) {
if($smallbit != ""){
$bits[] = $smallbit;
}
}
$bits[] = $result->s1;
$bits = array_unique($bits);
foreach ($bits as $k=>$v) {
if(($key = array_search($v, $input['searched'])) == false) {
$input['tosearch'][$v] = $v;
}else{
unset($input['tosearch'][$v]);
}
}
$input['tosearch'] = array_unique($input['tosearch']);
}
return $this->related($input);
}else{
return $input;
}
}

Consecutive dateranges in PHP

This is a follow-up question for my earlier question here:
Some help "syncing" two loops in PHP
I want to take a list of dates and show them as ranges if their date is the same or max 1 day apart.
This is the output of my database:
+-----+------------+
| uid | date |
+-----+------------+
| 39 | 2014-09-17 |
| 46 | 2014-09-18 |
| 40 | 2014-09-19 |
| 48 | 2014-09-19 |
| 45 | 2014-09-20 |
| 47 | 2014-12-05 |
+-----+------------+
This is the HTML I want to generate:
Contract from 17/09/2014 to 20/09/2014
UIDS: 39-46-40-48-45
Contract from 05/12/2014
UIDS: 47
This is my sourcecode
<?php
$output = '';
$list = array();
$lastitem = $lastdate = null;
$query = 'SELECT * FROM project_dates';
$sth = $dbh->prepare($query);
$sth->execute();
if($sth->rowCount() > 0) {
$i = 0;
while($row = $sth->fetch()) {
// CURRENT DATE
$date = new DateTime($row['date']);
// STORAGE
$item = array(
'date' => array(),
'var' => $row['uid'], // A '-' delimited variable of all the uids in the range (40-41-...)
'uids' => array() // An array of all the uids in the range
);
// IF THE DATE DIFF IS LESS THAN OR EQUAL TO ONE DAY
if ($item['date'] === $lastitem['date'] && $date->diff($lastdate)->days <= 1) {
// Problem here: looking for last date in set!
$list[$i-1]['date']['end'] = $date;
//Add current uid to the '-' delimited variable of uids of this range
$list[$i-1]['uid'] = $list[$i-1]['uid'].'-'.$item['uid'];
// Add current uid to the array of uids of this range
array_push($list[$i-1]['uids'],$item['uid']);
} else {
// Next range
$list[$i] = $item;
$list[$i]['date']['start'] = $date;
$lastitem = $item;
$lastdate = $date;
array_push($list[$i]['uids'],$item['uid']);
$i++;
}
}
}
if(count($list)){
// Show text with first date and last date of the range
$output .= 'Contract from '.$item['date']['start']->format('d/m/Y');
$output .= isset($item['date']['end']) ? ' to ' . $item['date']['end']->format('d/m/Y') : '';
$output .= '<br />Uids: '.$item['var'];
}
foreach ($list AS $item) {
// Loop over the dates in this range
$output .= $item['date'].'<br />';
}
if(count($list)) {
// Line under this range
$output .= '<hr />';
}
echo $output;
?>
For some reason, my code returns 4 ranges instead of 2. I've been trying to figure out for hours why. Can someone help me? This is the faulty HTML:
Contract from 17/09/2014 to 18/09/2014
UIDS: 39-46
Contract from 19/09/2014
UIDS: 40
Contract from 19/09/2014 tot 20/09/2014
UIDS: 48-45
Contract van 05/12/2014
UIDS: 47
Can anyone be of assistance?

Trying to use foreach loop inside while loop, keep getting infinite loop

I'm still very new to PHP, so I was wondering if I could get some help? I'm supposed to create a chart by iterating through an associative array using a while loop with a foreach loop inside it. But I keep getting an infinite loop and I'm not entirely sure how to fix it. I also suspect that the if statement conditions aren't helping, but I don't know either. What am I missing and is there a better way to go about this?
Here's the code in question:
<?php
include 'davesinventory.php';
$delimiter = " \n";
$inventory['name'] = rtrim(strtok($data, $delimiter));
$inventory['year'] = rtrim(strtok($delimiter));
$inventory['serial'] = rtrim(strtok($delimiter));
$inventory['seats'] = rtrim(strtok($delimiter));
$inventory['charge'] = rtrim(strtok($delimiter));
$inventory['days'] = rtrim(strtok($delimiter));
$inventory['rev'] = rtrim(strtok($delimiter));
$inventory['orig'] = rtrim(strtok($delimiter));
$inventory['miles'] = rtrim(strtok($delimiter));
$inventory['deprec'] = rtrim(strtok($delimiter));
$inventory['freq'] = rtrim(strtok($delimiter));
printf("<b> VEHICLE\tYEAR\t SERIAL#\t RENT COST\t DAYS OUT\t REVENUE\t ORIG. PRICE\t MILEAGE\t NOTES\n</b>");
?>
<hr>
<?php
while($inventory['name']){
foreach($inventory as $key => $vehicles){
if ($key !== ['seats'] || ['deprec'] || ['freq'])
{
print $vehicles;
}
else if($key == ['seats'] || ['deprec'] || ['freq'])
{
echo " ";
}
}
}
?>
<pre>
Here is the file that the 'include' calls for:
<?php
$data =
"DodgeAvenger 2006 DA111-9 4 35.50 105 3727.50 21297.00 8795 .20 Monthly
Olds_Alero 2004 OA340-1 5 29.95 126 3773.70 23335.00 36010 .20 Monthly
Chry_PT_Crsr 2003 CPTC-MW2 4 37.95 26 986.70 15405.00 29020 .20 Weekly
Cadillac_Limo 1999 1999-01 18 142.50 4 570.00 38900.00 187419 .10 Weekly
Chev_M_Carlo 1997 CMC-21 6 27.30 55 1501.50 19437.50 113689 .20 Monthly
Chev_Suburban 1997 CSB-011 8 42.75 17 726.75 29999.00 137560 .20 Monthly
VW_Bus_T2A 1977 VWB-09 32 15.00 16 240.00 12000.00 397800 NA Daily
Ford_Stn_Wgn 1976 FSW-67 8 10.95 6 65.70 9899.00 149379 NA Whenever
Toy_Forklift 1997 6FGCU-45 1 61.25 65 3981.25 8795 732 .10 Yearly
Cat_Dozer(D7H) 1989 1989-11 1 98.00 5 490.00 67850.00 1304 .10 Yearly
";
?>
No need to use while loop here. Foreach is enough
<?php
if(isset($inventory['name'])){
foreach($inventory as $key => $vehicles){
if ($key !== 'seats' || $key !=='deprec' || $key !=='freq')
{
print $vehicles;
}
else{
echo " ";
}
}
}
?>
Blank's answer should work for you. Mine should actually be a comment but it's much easier to format code in an answer.
If using while is just an annoying requirement for a homework or test (according to your comment...) you can simply work around it:
$finished = false;
while (!$finished)
{
//do all the work here - foreach loop and so on
$finished = true;
}

Categories