how to check Foreach loop is working - php

Im very new to PHP coding.
Just im getting values from object (class Project)and im iterating all object items to calculate duration of each project.
$projectDet = new Project();
$projectList = $projectDet->Find("name = ?",array($requ['name'] ));
if($projectList==false)
return 0;
foreach($projectList as $proj)
{
$reportData = array();
$reportData[] = array("Project","TotalTime"); //Testing
$key = $proj->id;
$EstDUR[$key] = (strtotime($proj->Enddt) - strtotime($proj->Startdt));
}
return $reportData;
But reportData returns null even projectList is not null.

Initate $reportData before foreach:
$reportData = array()
foreach($projectList as $proj) {
(..)

Related

PHP cant add new object keys in foreach loop

I want to create new object keys in foreach loop so I write:
$all_variants = $p->variants;
foreach ($all_variants as $a) {
$a->discount_price = $a->price;
$a->original_price = $a->price;
$a->button_text = 'BUY';
}
but this code wont create new keys (discount_price, original_price, button_text) ... $all_variants->discount_price is undefinded ....
Whats bad in my code?
You can use next trick for this
$all_variants = $p->variants;
foreach ($all_variants as &$a) {
$tmp = (array)$a;
$tmp['discount_price'] = $tmp['price'];
$tmp['original_price'] = $tmp['price'];
$tmp['button_text'] = 'BUY';
$a = (object)$tmp;
}
Here object converted to array modified and converted to object again
php code online test
This works for me:
foreach ($p->variants as $a) {
$a['discount_price'] = $a['price'];
$a['original_price'] = $a['price'];
$a->button_text = 'BUY';
$all_variants[] = $a;
}
You can modify the original array, but not the copy of the element you get in the loop...
foreach($p->variants as $i => $a) {
// $p->variants[ $i ] corresponds to $a
$p->variants[ $i ]['discount_price'] = $a['price'];
}

Iterating over an XML file in PHP

I'm using Laravel to parse an XML file and store it into the DB. Now, it's probably some sort of a stupid mistake I can't put my finger on, but I would really appreciate if someone could check the code and the weird results I'm getting.
The XML has a deep and complex structure, here's a little piece from that's bugging me:
I'm dumping the $nizXMLsp in the end to see what's inside the array of objects:
public function upload(){
$dom = new DomDocument();
$nizBaza = DB::table('offers')->orderBy('id', 'DESC')->first();
$nizXML = array();
$objekat = new stdClass();
$dom->load("storage/X_Lista.xml");
$domXpath = new DomXPath($dom);
$upit = $domXpath->query('//offer');
foreach($upit as $of){
$objekat->Time = $of->getAttribute('Time');
$objekat->Date = $of->getAttribute('Date');
$objekat->betRound = $of->getAttribute('betRound');
$objekat->timestamp = $of->getAttribute('timestamp');
array_push($nizXML, $objekat);
}
if(is_null($nizBaza) or $nizBaza->id != $nizXML[0]->betRound) {
$kolo = new Offer();
$kolo->id = $objekat->betRound;
$kolo->ts = $objekat->Date . " " . $objekat->Time;
$kolo->posix = $objekat->timestamp;
$kolo->save();
//
$nizBaza = DB::table('sportovi')->get();
$nizXMLsp = array(); $objekat_sp = new stdClass();
foreach($dom->getElementsByTagName('sport') as $k=>$v){
$objekat_sp->id = $v->getAttribute('id');
$objekat_sp->name = $v->getAttribute('name');
$objekat_sp->betRound = $v->parentNode->getAttribute('betRound');
$nizXMLsp[$k] = $objekat_sp;
}
}
elseif($nizBaza->id == $nizXML[0]->betRound){
echo 'break1';
exit;
}
else {
echo 'break2';
exit;
}
return var_dump($nizXMLsp);
}
Now, what I see in the end is this:
instead of 4 objects with different sets of data, I get 4 objects with same set of data (all of the data comes from the last node). What could it be?
Possibly a very simple adjustment. Just reset $objekat_sp inside the loop:
foreach($dom->getElementsByTagName('sport') as $k=>$v){
$objekat_sp = "";
$objekat_sp->id = $v->getAttribute('id');
$objekat_sp->name = $v->getAttribute('name');
$objekat_sp->betRound = $v->parentNode->getAttribute('betRound');
$nizXMLsp[$k] = $objekat_sp;
}
Move
$objekat = new stdClass();
and
$objekat_sp = new stdClass();
inside their respective foreach loops.
Right now you're pushing the same object (after modifying its properties) into the array multiple times.

php stdClass/object build

i want to build an object (for angular) so it will look like so
user:{
{education:
{high school:'some school'},
{faculty:'faculty of science'}
},
{skills:
{skill1:'sk1'},
{skill2:'sk2'}
}
}
and this is my php and mysql query:
$testArr = array();
$user = new stdClass();
$params = DB::select( DB::raw("SELECT param.*, sys_param_values.*,param_value.*,type_user.*,
param.name AS paramName,
doc_param.name AS docParamName
FROM param
LEFT JOIN doc_param ON param.doc_param_id = doc_param.id
LEFT JOIN sys_param_values ON param.id = sys_param_values.param_id
LEFT JOIN param_value ON sys_param_values.value_ref = param_value.id
LEFT JOIN type_user ON sys_param_values.ref_user_id = type_user.id"));
query result:
"params":[{"id":21,"name":"faculty","type_id":5,"doc_param_id":14,"created_at":"2015-05-17 14:13:12","updated_at":"2015-06-04 08:19:43","doc_type":12,"ref_user_id":21,"param_id":48,"iteration":null,"value_short":null,"value_long":null,"value_ref":74,"value":"some High","type":"tech-admin","email":"xxxxxxx8#gmail.com","password":"$2y$10$6L8voJ3DgZuADHZLaBh4jei\/U.svVdcN4B02XFc9mF\/p8m5RpfJtG","password_new":null,"first_name":"jon","last_name":"snow","street_1":"shiv","street_2":"tey","city":"123456","state":"aa","zipcode":"47252","country":"usa","phone_1":"123456","phone_2":"123456","mobile":"123456789","date_of_birth":"2015-05-18 11:25:42","registration":"0000-00-00 00:00:00","last_login":"2015-05-20 09:14:52","send_newsletters":1,"send_notifications":1,"remember_token":"dtlimLNZBWdCxcqKR7NdDblMiafkZOxywN4jjUac53v7NI4e1t6eokJXdsoy","paramName":"faculty","docParamName":"education"}
after the query witch is good, i loop :
foreach($params as $k=>$v) {
$paramName = $v->paramName;
$value = $v->value;
$testArr[$v->docParamName] = array();
$testArr[$v->docParamName][$paramName] = $v->value;
}
and the result is :
"test":{
"education":
{"high_school":"some High"},
"skills":
{"skill_1":"skill_1 Value"},
"experience":
{"xp_1":"xp1 value"}
}
the thing is i have more if these parameters for example "skill_2" and "skill_3" that are suppose to go in the "skills" object.
but this loop anly gets the last parameter..
where am i suppose to specify a key or something so that all of the skills go to the skills object and so on..
You need to define like this:-
foreach($params as $k=>$v) {
$paramName = $v->paramName;
$value = $v->value;
// $testArr[$v->docParamName] = array(); // comment the line
$testArr[$v->docParamName][$paramName] = $v->value;
}
Note:- the line is commented because you already defined $testArr as an array before foreach loop.thanks
You are re-initializing your sub-object on each iteration:
$testArr[$v->docParamName] = array(); // <- By this, you remove all previously
// assigned values
$testArr[$v->docParamName][$paramName] = $v->value;
Initializing an array before appending elements to it is a good idea, because it will otherwise trigger a warning when you try to append to a non-initialized array. But you should only initialize the array if it was not initialized before:
if (!array_key_exists($v->docParamName, $testArr)) {
$testArr[$v->docParamName] = array();
}
$testArr[$v->docParamName][$paramName] = $v->value;

php function not returning all results from a MySQL query in a foreach

Hey guys I have a little issue with a function that retrieves data from a MySQL Database and then I iterate over the results with a foreach loop, checking a value to see if it is null and if it is, replacing it with another value.
The problem with this function is this, that after returning the data I'm only able to view one record retrieved from the database. Probably something simple but it's beyond me.
I would like to do this before passing it to the controller or view. Maybe this isn't possible with the foreach loop? What am I missing?
Here is an example of my code.
public function get_basic_user_data(){
$sql = 'SELECT Account.First_Name, Account.Last_Name, Account.User_Name, Profile_Photos.Thumb_Url
FROM Account
LEFT JOIN Profile_Photos ON Account.idAccount = Profile_Photos.Account_Id
AND Profile_Photos.Active = 1
WHERE Account.idAccount != ?';
$account_id = $this->get_account_id();
$data = $this->db->query($sql, $account_id);
foreach($data->result() as $row){
if($row->Thumb_Url == NULL){
$image = base_url().'assets/images/no_photo_thumb.png';
}else{
$image = $row->Thumb_Url;
}
$new_data = new stdClass;
$new_data->First_Name = $row->First_Name;
$new_data->Last_Name = $row->Last_Name;
$new_data->User_Name = $row->User_Name;
$new_data->Thumb_Url = $image;
}
return $new_data;
}
Hopefully someone can help me with this? Thanks!
At the moment you are just returning the last data row. Change your code like this to return an array of all your rows from that function:
$rows = array()
foreach($data->result() as $row){
if($row->Thumb_Url == NULL){
$image = base_url().'assets/images/no_photo_thumb.png';
}else{
$image = $row->Thumb_Url;
}
$new_data = new stdClass;
$new_data->First_Name = $row->First_Name;
$new_data->Last_Name = $row->Last_Name;
$new_data->User_Name = $row->User_Name;
$new_data->Thumb_Url = $image;
$rows[] = $new_data;
}
return $rows;
This way every row returned from the database will be added to an array named $rows. At the end you have to return your new array.
You are overwriting $new_data each iteration. Try this
$new_data = new stdClass
...
$all_data[] = $new_data;
Instead of checking for null value in the code, you could just use a IFNULL statement in the SQL query, this does separate the logic a bit but it might just be worth it in this case.
The function returns only the last row in the result because the new_data variable is overwritten in every step of your loop. Declare new_data an array at the start of your function and add rows as array elements
...
$new_data[] = new stdClass;
...
Each iteration of the foreach overwrites $new_data so in the end when the function returns, only the last fetched row will be returned. To return more than one row you could store all the rows in an array and then return the array in the end. It would look something like this:
public function get_basic_user_data(){
$sql = 'SELECT Account.First_Name, Account.Last_Name, Account.User_Name, Profile_Photos.Thumb_Url
FROM Account
LEFT JOIN Profile_Photos ON Account.idAccount = Profile_Photos.Account_Id
AND Profile_Photos.Active = 1
WHERE Account.idAccount != ?';
$account_id = $this->get_account_id();
$data = $this->db->query($sql, $account_id);
$data = array();
foreach($data->result() as $row){
if($row->Thumb_Url == NULL){
$image = base_url().'assets/images/no_photo_thumb.png';
}else{
$image = $row->Thumb_Url;
}
$new_data = new stdClass;
$new_data->First_Name = $row->First_Name;
$new_data->Last_Name = $row->Last_Name;
$new_data->User_Name = $row->User_Name;
$new_data->Thumb_Url = $image;
$data[] = $new_data;
}
return $data;
}
To be able to use this function you have to change the code that uses it to loop through the array of objects.

store objects in an array during foreach?

I am looking to store some objects in an array during a foreach loop. The problem is creating a unique object each time. I have to have some kind of index appending the name of each object. Here is what I have:
function table_rows($html) {
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
($check_object . $key) = new check_class;
($check_object . $key)->check_method1($table_row);
($check_object . $key)->check_method2($table_row);
($check_object . $key)->check_method3($table_row);
$check_array[] = (check_object . $key);
}
}
Am I even close?
You could use variables for that:
function table_rows($html) {
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
$object = new check_class;
$object->check_method1($table_row);
$object->check_method2($table_row);
$object->check_method3($table_row);
$check_array[] = $object;
}
}
Of course naming the variable for an object instance $object is not very descriptive, but I hope you get the idea.
This works because the first assignment in the for-loop overwrites the "old" instance, so $object unique for each iteration.
In case Jared Drake is right and what you mean is unique array keys, not object (variable) names.
$dom = new Zend_Dom_Query($html);
$table_rows = $dom->query('tr');
$check_array = array();
foreach ($table_rows as $key=>$table_row) {
$check_object = new check_class;
$check_object->check_method1($table_row);
$check_object->check_method2($table_row);
$check_object->check_method3($table_row);
$check_array['check_object' . $key] = $check_object;
}
}
Maybe I'm misunderstanding the question, but can't you just use the array_push method to add each object to the end of the array in your foreach loop?

Categories