How to do conditioning in foreach loop - php

I have a foreach loop for array $students where I am trying to compare a paramater $find that I get from a form to $students array's $key value -> if they match it checks if the student is enrolled (this works) and if not it should print "Not found" but it doesn't do anything.. I have tried a lots of things but nothing works, please help!
I translated this from finnish so there might be typo's but the problem is in the syntax..
//values come from a file
$students[$key] = array('key' => $key, 'name' => $name, 'occ' => $occ);
foreach ($students as $value) {
//This doesn't work - $find comes from a form
if ($value["key"] != $find) {
$phase= "Not found";
$enroll= "";
//echo "$phase $enroll";
continue;
}
//This works
elseif ($value["key"] == $find) {
$phase= $value["name"] . "(" . $value["key"] . "):";
if ($value["occ"] == "1") {
$enroll= " yes";
continue;
}
elseif ($value["occ"] == "0") {
$enroll= "no";
continue;
}
}
//It prints out for example "John(1234): yes"
//But nothing if the studentnumber = key doesn't match..
echo "$phase $enroll";
}

You don't need to check $value["key"] twice
$students[$key] = array('key' => $key, 'name' => $name, 'occ' => $occ);
foreach ( $students as $value ) {
$phase= "Not found";
$enroll= "";
if ( $value["key"] == $find ) {
$phase= $value["name"] . "(" . $value["key"] . "):";
$enroll = ( $value["occ"] == "1" ) ? " yes" : "no";
}
echo "$phase $enroll";
}

Related

Not able to parse nested Json array in PHP while print_r function is printing all values properly

I am trying to parse a json array string. Though print_r prints all the values properly but while fetching the records I failed.
I must be doing something very terribly wrong. Could you please help to correct it.
So here is my code
<?
$str ='
{
"tenant_view_details": [
{
"status":"S",
"tenant_general":[
{"tenant_id":"6003","code":"ICI001","type":"BANK","category":"SM","gstn":"IWSDFS7372","pan":"KSAH9876AS","cin":"ASHED456","name":"ICICI Bank","address_line_1":"23, Hertz Plaza, Rajiv Chowk","address_line_2":" ","address_city":"New Delhi","address_distict ":"New Delhi","address_state ":"DL","address_state_code ":"07","address_pin ":"119923","contact_name ":"contact_name","contact_phone ":"1234567890","contact_std_code ":"11","contact_landline ":"1234567890","contact_email_id ":"contact#email.com"} ],
"tenant_bank": [
{ "bank_name ":"xyz","bank_account_no ":"12345","account_type ":"abc","ifsc_code ":"xx123","address_line_1 ":"qwer","address_line_2 ":"23","address_city ":"abc","address_district ":"xyz","address_state_name ":"asd","address_state_code ":"02","address_pin ":"123456" } ],
"tenant_agreement": [
{ "category ":"OM","tenancy_type ":"EXT","echarge_type ":"FIX","total_tenancy_value ":"32900.00","energy_charge_value ":"16543.00","rev_share_pct ":"0.05","start_dt":"10-1-2018","end_dt":"31-12-2020","attachment_path ":"na","change_value ":"na","latest_flag ":"Y","w_status ":"20","status ":"ACT"} ],
"tenant_sites": [
{"tenant_id":"6003","site_master_id":"1020","tn_site_code":"UPWMORA00069473","tn_site_name":"Deendayal Nagar","tn_cluster":"CLUSTER-03","circle_code":"UW","tower_type":"MAST","site_type":"ID","tenancy_type":"EXT","echarge_type":"FIX","primary_tenant":"N","latest_flag ":"Y"}, {"tenant_id":"6003","site_master_id":"1019","tn_site_code":"UPWGHAZ00069467","tn_site_name":"DJ College Newari Road, Modina","tn_cluster":"CLUSTER-03","circle_code":"UW","tower_type":"MAST","site_type":"ID","tenancy_type":"EXT","echarge_type":"FIX","primary_tenant":"N","latest_flag ":"Y"}, {"tenant_id":"6003","site_master_id":"1018","tn_site_code":"UPWMORA00069464","tn_site_name":"Bazar Makhbra","tn_cluster":"CLUSTER-03","circle_code":"UW","tower_type":"RTT","site_type":"OD","tenancy_type":"EXT","echarge_type":"FIX","primary_tenant":"N","latest_flag ":"Y"}, {"tenant_id":"6003","site_master_id":"1016","tn_site_code":"UPWGHAZ00069454","tn_site_name":"Hoshdarpur Garhi","tn_cluster":"CLUSTER-03","circle_code":"UW","tower_type":"RTT","site_type":"OD","tenancy_type":"EXT","echarge_type":"FIX","primary_tenant":"N","latest_flag ":"Y"}, {"tenant_id":"6003","site_master_id":"1011","tn_site_code":"UPWMUZN00069430","tn_site_name":"Sikanderpur","tn_cluster":"CLUSTER-03","circle_code":"UW","tower_type":"RTT","site_type":"ID","tenancy_type":"EXT","echarge_type":"FIX","primary_tenant":"N","latest_flag ":"Y"}, {"tenant_id":"6003","site_master_id":"1008","tn_site_code":"UPWALIG00069299","tn_site_name":"Mukund Vihar","tn_cluster":"CLUSTER-03","circle_code":"UW","tower_type":"RTT","site_type":"","tenancy_type":"EXT","echarge_type":"FIX","primary_tenant":"N","latest_flag ":"Y"} ]
}
]
}
';
$dataset = json_decode($str, true);
//print_r ($dataset);
foreach ($dataset['tenant_view_details'] as $newdata) {
$general = $newdata['tenant_general'];
$bank = $newdata['tenant_bank'];
$agreement = $newdata['tenant_agreement'];
$sites = $newdata['tenant_sites'];
}
//prinitng data
echo "<br/>";
print_r($general);
echo "<br/>";
print_r($bank);
echo "<br/>";
print_r($agreement);
echo "<br/>";
foreach($general as $general_data){
(isset($general_data['tenant_id']) && !empty($general_data['tenant_id']))? $tenant_id=$general_data['tenant_id'] : $tenant_id="not set";
echo "<br/>tenant_id::" . $tenant_id;
}
foreach($bank as $bank_data){
(isset($bank_data['bank_name']) && !empty($bank_data['bank_name']))? $bank_name=$bank_data['bank_name'] : $bank_name="not set";
echo "<br/>bank_name:" . $bank_data['bank_name'];
}
foreach($agreement as $agreement_data){
(isset($agreement_data['category']) && !empty($agreement_data['category']))? $category=$agreement_data['category'] : $category="not set";
(isset($agreement_data['tenancy_type']) && !empty($agreement_data['tenancy_type']))? $tenancy_type=$agreement_data['tenancy_type'] : $tenancy_type="not set";
(isset($agreement_data['echarge_type']) && !empty($agreement_data['echarge_type']))? $echarge_type=$agreement_data['echarge_type'] : $echarge_type="not set";
echo "<br/>category:" . $category;
echo "<br/>tenancy_type:" . $tenancy_type;
echo "<br/>echarge_type:" . $echarge_type;
}
?>
Your problem is that in your $bank and $category arrays, all the keys have trailing spaces on them. If you change the references to include those spaces, your code works fine. See https://3v4l.org/GX5iC
Alternatively you can trim the array keys, using something like this code inside your foreach loops:
$bank_keys = array_map('trim', array_keys($bank_data));
$bank_data = array_combine($bank_keys, array_values($bank_data));
You could also create a recursive function to trim the entire $dataset value. For example:
function trim_keys($array) {
foreach ($array as $key => $value) {
echo "trimming key '$key' to '" . trim($key) . "'\n";
unset($array[$key]);
$array[trim($key)] = $value;
if (is_array($value))
$array[trim($key)] = trim_keys($value);
else
$array[trim($key)] = $value;
}
return $array;
}
Then, by using
$dataset = trim_keys($dataset);
Your code will work fine. Demo on 3v4l.org

Finding values in second array if specific key from first array is found

I have written a code, that finds value in second array if it finds specific key from first array, but my question is - is it possible to do it better? for example without 3 loops ?
For example here are keys and values to search for, which user has checked at form and submitted ($tegoszukamy):
array (
'kolor' =>
array (
0 => 'bialy',
1 => 'zielony',
),
'rozmiar' =>
array (
0 => '60',
1 => '70',
),
'rozdzielczość' =>
array (
0 => '1200x1800',
),
'moc' =>
array (
0 => '500W',
),
);
Here is array with products IDs where searching is performed ($tuszukamy):
array (
47 =>
array (
'rozmiar' => '50,60,70,80,90,100',
'kolor' => 'bialy,czarny',
),
48 =>
array (
'rozmiar' => 'L,M,XS,S,L',
'kolor' => 'zielony,niebieski,czerwony,zolty,bialy,czarny',
),
49 =>
array (
'rozdzielczość' => '1200x1800',
'prędkość' => '60str/min',
)
)
Here is my code that is working fine:
foreach ($tegoszukamy as $atrybut=>$wartosci_szukane) {
foreach ($tuszukamy as $numer_posta=>$wartosci_zbioru ) {
if (array_key_exists($atrybut, $wartosci_zbioru) !== FALSE){
foreach ($wartosci_szukane as $ws) {
if (strpos($wartosci_zbioru[$atrybut],$ws) !== FALSE) {
echo
'We have found'
.$ws.
'in'
.$wartosci_zbioru[$atrybut].
'where product id is'
.$numer_posta.
''
;}
else {
echo
'We found not'
.$ws.
'in'
.$wartosci_zbioru[$atrybut].
''
;}
}
}
}
}
Is it possible to do it better/with better code performance/speed, because I dont know if these 3 loops will be good when user filters through eg. 10000 products.
I came up with the following alternatives:
1.
class Subject {
private $attr_name;
private $attr_values;
function __construct($attr_name, $attr_values) {
$this->attr_name = $attr_name;
$this->attr_values = $attr_values;
}
public function check($key, $item) {
$found = array();
if (isset($item[$this->attr_name])) {
foreach($this->attr_values as $val) {
strstr($item[$this->attr_name], $val) && array_push($found, $val);
}
}
count($found) > 0 ?
$message = "Found attribute <u>" . $this->attr_name . "</u> with value <b>" . implode(", ", $found) . "</b> in ID: " . $key . "."
:
$message = "No matches for <u>" . $this->attr_name . "</u> found in ID: " . $key;
return $message;
}
}
foreach ($tegoszukamy as $attr_name=>$attr_values) {
$filtered = array_map(array(new Subject($attr_name, $attr_values), "check"), array_keys($tuszukamy), $tuszukamy);
foreach($filtered as $result) {
echo $result . '<br>';
}
}
2.
foreach ($tegoszukamy as $attr_name=>$attr_values) {
$filtered = array_filter($tuszukamy, function ($item, $key) use($attr_name, $attr_values) {
$found = array();
if (isset($item[$attr_name])) {
// var_dump($item[$attr_name]);
foreach($attr_values as $val) {
strstr($item[$attr_name], $val) && array_push($found, $val);
}
}
count($found) > 0 ?
$message = "Found attribute <u>" . $attr_name . "</u> with value <b>" . implode(", ", $found) . "</b> in ID: " . $key . "."
:
$message = "No matches for <u>" . $attr_name . "</u> found in ID: " . $key;
echo $message . "<br>";
return count($found) > 0;
}, ARRAY_FILTER_USE_BOTH);
// something to do with $filtered;
}
I'm not sure whether either of them is faster than yours. I'll leave the testing to you. :)
The first one was inspired by jensgram's answer to this question: PHP array_filter with arguments

How to modifying the data structure of array list as per key value using PHP

I need to modify the data structure of json array list as per some key value using PHP. I am explaining my code below.
<?php
$output=array(
array(
"first_name"=>"robin",
"last_name"=>"sahoo",
"reg_no"=>12,
"paper_code"=>"BA001"
),array(
"first_name"=>"robin",
"last_name"=>"sahoo",
"reg_no"=>12,
"paper_code"=>"BA002"
),array(
"first_name"=>"Rama",
"last_name"=>"Nayidu",
"reg_no"=>13,
"paper_code"=>"BA001"
)
);
//echo json_encode($output);
$result=array();
foreach ($output as $key => $value) {
if (count($result)==0) {
$result[]=array(
"name"=>$value["first_name"].' '.$value['last_name'],
"reg_no"=>$value['reg_no'],
"paper1"=>$value['paper_code'],
"paper2"=>"",
"paper3"=>"",
"paper4"=>""
);
}
}
The output of the input array is given below.
// Output:
[
{
"first_name":"robin",
"last_name":"sahoo",
"reg_no":12,
"paper_code":"BA001"
},
{
"first_name":"robin",
"last_name":"sahoo",
"reg_no":12,
"paper_code":"BA002"
},
{
"first_name":"Rama",
"last_name":"Nayidu",
"reg_no":13,
"paper_code":"BA001"
}
];
The above is my array list. Here I need to modify the all row value by reg_no means if there are multiple rows including same reg_no then those will merge with joining the both name and my expected output should like below.
expected output:
[
{
'name':"robin sahoo",
"reg_no":12,
"paper1":"BA001",
"paper2":"BA002",
"paper3":"",
"paper4":""
},
{
'name':"Rama Nayidu",
"reg_no":13,
"paper1":"BA001",
"paper2":"",
"paper3":"",
"paper4":""
}
]
Here paper1,paper2,paper3,paper4 will be selected serially means suppose same reg_no=12 has first row paper_code= BA001 then it will be paper1=BA001 and second row paper_code=BA002 then it will be paper2=BA002 and so on. Here I am using PHP to map this array.
Try the following, Let me know..
$output=array(array("first_name"=>"robin","last_name"=>"sahoo","reg_no"=>12,"paper_code"=>"BA001"),array("first_name"=>"robin","last_name"=>"sahoo","reg_no"=>12,"paper_code"=>"BA002"),array("first_name"=>"Rama","last_name"=>"Nayidu","reg_no"=>13,"paper_code"=>"BA001"));
//echo json_encode($output);
$result=array();
$temp=array();
if(!empty($output)){
foreach ($output as $key => $value) {
if(isset($temp[$value['reg_no']])){
if(empty($temp[$value['reg_no']]["paper1"]) || $temp[$value['reg_no']]["paper1"] == ""){
$temp[$value['reg_no']]["paper1"] = $value['paper_code'];
}else if(empty($temp[$value['reg_no']]["paper2"]) || $temp[$value['reg_no']]["paper2"] == ""){
$temp[$value['reg_no']]["paper2"] = $value['paper_code'];
}else if(empty($temp[$value['reg_no']]["paper3"]) || $temp[$value['reg_no']]["paper3"] == ""){
$temp[$value['reg_no']]["paper3"] = $value['paper_code'];
}else if(empty($temp[$value['reg_no']]["paper4"]) || $temp[$value['reg_no']]["paper4"] == ""){
$temp[$value['reg_no']]["paper4"] = $value['paper_code'];
}
}else{
$temp[$value['reg_no']] = array("name"=>$value["first_name"].' '.$value['last_name'],"reg_no"=>$value['reg_no'],"paper1"=>$value['paper_code'],"paper2"=>"","paper3"=>"","paper4"=>"");
}
}
}
if(!empty($temp)){
foreach ($temp as $key => $value) {
$result[] = $value;
}
}
This Code May help you
<?php
$output=array(array("first_name"=>"robin","last_name"=>"sahoo","reg_no"=>12,"paper_code"=>"BA001"),array("first_name"=>"robin","last_name"=>"sahoo","reg_no"=>12,"paper_code"=>"BA002"),array("first_name"=>"Rama","last_name"=>"Nayidu","reg_no"=>13,"paper_code"=>"BA001"));
//echo json_encode($output);
$result=array();
foreach ($output as $key => $value) {
if (count($result)==0) {
$output[$key]=array("name"=>$value["first_name"].' '.$value['last_name'],"reg_no"=>$value['reg_no'],"paper1"=>$value['paper_code'],"paper2"=>"","paper3"=>"","paper4"=>"");
}
}echo "<pre>";print_r($output);
?>
You can try with this
$result = []; // Initialize result array
foreach ($output as $key => $value) {
$name = $value['first_name'] . ' ' . $value['last_name'];
// check if same name already has entry, create one if not
if (!array_key_exists($name, $result)) {
$result[$name] = array(
'name' => $name,
'reg_no' => $value['reg_no'],
'paper1' => '',
'paper2' => '',
'paper3' => '',
'paper4' => ''
);
}
// count array elements with value, then set paper number and value
$paper = 'paper' . (count(array_filter($result[$name])) - 1);
$result[$name][$paper] = $value['paper_code'];
}
$result = array_values($result); // reindex result array
$result = json_encode($result); // Encode to json format
print_r($result); // print result
This assumes that first_name and last_name is always same for each reg_no

Check for empty values in associative array

I'm having a hard time checking for empty values in my associative array. And if a value is empty/null replace it with the wording "not entered"
My $_SESSION['gift'] array:
Array
(
[0] => Array
(
[giftGiveMy] => 1a
[giftTo] => 2a
)
[1] => Array
(
[giftGiveMy] => 1b
[giftTo] => '' //### empty ###
)
)
if (empty($_SESSION['gift']) && 0 !== $_SESSION['gift']) {
$gifts = "No specific gifts identified.\n";
} else {
$gifts = [];
foreach( $_SESSION['gift'] as $value) {
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". $value['giftTo'] .".\n";
}
$gifts = join($gifts);
}
The above outputs:
I give my 1a to 2a.
I give my 1b to .
I would like it read:
I give my 1a to 2a.
I give my 1b to not entered.
You can replace all empty and NULL value with not entered with the help of array_walk_recursive and use you code as it is
array_walk_recursive($arrayMain, 'not_entered');
function not_entered(& $item, $key) {
if (($item === "") || ($item ==NULL)){
$item = "not entered";
}
}
var_dump($arrayMain);
Just use foreach to loop all values and check if it's empty
$emptyText = '<b>not entered</b>';
// `empty` will also be true if element does not exist
if (empty($_SESSION['gift'])) {
$gifts = "No specific gifts identified.\n";
} else {
$gifts = [];
foreach($_SESSION['gift'] as $value) {
$myGive = !empty($value['giftGiveMy']) ? $value['giftGiveMy'] : $emptyText;
$giftTo = !empty($value['giftTo']) ? $value['giftTo'] : $emptyText;
$gifts[] = "I give my {$myGive} to {$giftTo}.";
}
$gifts = implode("\r\n", $gifts); // Or `<br/>` if outputted to HTML
}
You should modify your code and write it this way:
if (!isset($_SESSION['gift']) || empty($_SESSION['gift'])) {
$gifts = "No specific gifts identified.\n";
} else {
foreach( $_SESSION['gift'] as $value) {
$gift_to = !empty($value['giftTo']) ? $value['giftTo'] : '<strong>Not entered<strong>';
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". $gift_to .".\n";
}
}
You might want to try this:
if (empty($_SESSION['gift']) && 0 !== $_SESSION['gift']) {
$gifts = "No specific gifts identified.\n";
} else {
$gifts = [];
foreach( $_SESSION['gift'] as $value) {
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". (!empty($value['giftTo']) ? $value['giftTo'] : '<b>not entered</b>') .".\n";
}
$gifts = join($gifts);
}
If you would like to make it a little cleaner you could extract the ternary operator into something like this;
$giftTo = !empty($value['giftTo']) ? $value['giftTo'] : '<b>not entered</b>';
$gifts[] = "I give my ". $value['giftGiveMy'] ." to ". $giftTo .".\n";
Try:
$arr = $_SESSION['gift'];
foreach($arr as $key => $array) {
if($array['giftGiveMy'] == null || empty($array['giftGiveMy'])) {
$arr[$key]['giftGiveMy'] = 'not entered.';
}
if($array['giftTo'] == null || empty($array['giftTo'])) {
$arr[$key]['giftTo'] = 'not entered.';
}
}
I'd write that this way:
$gifts = "No specific gifts identified.\n";
$filter = function($str) {
return empty($str) ? 'not entered' : $str;
};
if(!empty($_SESSION['gift'])) {
$gifts = '';
array_walk($_SESSION['gift'], function($given) use(&$gifts,$filter){
$gifts .= 'I give my ' . $filter($given['giftGiveMy']) . ' to ' . $filter($given['giftTo']) . ".\n";
});
}
You can use for the below code also there is no need any extra Php functions.
$arr = array(
0 => array(
'giftGiveMy' => '1a',
'giftTo' => '2a'
),
1 => array(
'giftGiveMy' => '1b',
'giftTo' => ''
)
);
$str = '';
if (!empty($arr)) {
foreach ($arr as $key => $value) {
if ($value['giftGiveMy'] == '')
$value['giftGiveMy'] = 'not entered';
if ($value['giftTo'] == '')
$value['giftTo'] = '<strong>not entered</strong>';
//$new[$key] = $value;
$str .= "I give my " . $value['giftGiveMy'] . " to " . $value['giftTo'] . "<br />";
}
}else {
$str = 'No specific gifts identified.<br />';
}
echo $str;
This validates an associative array with empty() (see array_filter), but may not respond to the original question.
<?php
$var = array();
$var['position'] = 'executive';
$var['email'] = 'a#email.com';
$var['message'] = 'This is the message';
$var['name'] = 'John Doe';
$var['telephone'] = '123456789';
$var['notneededparam'] = 'Nothing';
$expectedParams = ['position', 'email', 'message', 'name', 'telephone'];
$params = array_intersect_key($var, array_flip($expectedParams));
// check existence of keys and that they are valid
if(count($params) != count($expectedParams) || count(array_filter($params)) != count($expectedParams)){
echo "not valid\n";
die();
}
extract($params);
var_dump($name);
Other functions used here: array_flip(), array_intersect_key(), count(), extract(), var_dump(),

Extract values in one line based on key json decode and foreach

I need to work out how i can get showBtn(3) to match up against the first result in every other key.
ShowBtn/3
btnMenulink/101
btnArticleLink/2
btnPhone/036244789
btnUrl/
btnName/Office
PHP:
$jsonresult = '{"showBtn":["3","3"],"btnMenuLink":["101","101"],"btnArticleLink":["2","2"],"btnPhone":["036244789","0404256478"],"btnURL":["",""],"btnName":["Office","Mobile"]}';
$array = json_decode($jsonresult,true);
foreach ($array as $key => $value) {
foreach ($value as $next_key => $next_value) {
echo $key . ":" . $next_key . ":" . $next_value . "\n";
}
}
I want this:
if (showBtn == 3) {
echo '<a href='tel:btnPhone'>btnName</a>';
}
the result would be
Office Mobile
I almost have it!
$jsonresult = '{"showBtn":["3","3"],"btnMenuLink":["101","101"],"btnArticleLink":["2","2"],"btnPhone":["036244789","0404256478"],"btnURL":["",""],"btnName":["Office","Mobile"]}';
$parsed = json_decode($jsonresult,true);
echo 'Showbtn: '.$parsed['showBtn'][0].' Phone: '.$parsed['btnPhone'][0].' Name: '.$parsed['btnName'][0];
echo '<hr/>Showbtn: '.$parsed['showBtn'][1].' Phone: '.$parsed['btnPhone'][1].' Name: '.$parsed['btnName'][1];
Now i just gotta get that [0] [1] into the loop somehow
I have it but can it be done better?
$jsonresult = '{"showBtn":["3","3"],"btnMenuLink":["101","101"],"btnArticleLink":["2","2"],"btnPhone":["036244789","0404256478"],"btnURL":["",""],"btnName":["Office","Mobile"]}';
$parsed = json_decode($jsonresult,true);
$i=0;
foreach ($parsed as $key => $value) {
if ($parsed['showBtn'][$i] == 3) {
echo 'Showbtn: '.$parsed['showBtn'][$i].' Phone: '.$parsed['btnPhone'][$i].' Name: '.$parsed['btnName'][$i].'<hr/>';
}
$i++;
}
This'll work for you. You need to work it as this way
$jsonresult = '{"showBtn":["3","3"],"btnMenuLink":["101","101"],"btnArticleLink":["2","2"],"btnPhone":["036244789","0404256478"],"btnURL":["",""],"btnName":["Office","Mobile"]}';
$array = json_decode($jsonresult,true);
foreach($array['showBtn'] as $key => $value){
if($value == 3){
echo ''.$array['btnName'][$key].'<br>';
}
}
Output:
Office
Mobile

Categories