Check if property exists, if it does build off of the property - php

I have the following PHP code:
$alignments = new StdClass();
if ($query->num_rows > 0)
{
foreach($query->result() as $row){
$alignments->{$row->table_id} = new StdClass();
$alignments->{$row->table_id}->table_id = isset($row->table_id)?$row->table_id:NULL;
$alignments->{$row->table_id}->title = isset($row->title)?$row->title:NULL;
$alignments->{$row->table_id}->url = isset($row->url)?$row->url:NULL;
$alignments->{$row->table_id}->state_id = isset($row->state_id)?$row->state_id:NULL;
$alignments->{$row->table_id}->cross_discipline_alignment = isset($row->cross_discipline_alignment)?$row->cross_discipline_alignment:NULL;
$alignments->{$row->table_id}->common_core = isset($row->common_core)?$row->common_core:NULL;
$alignments->{$row->table_id}->grade_level = isset($row->grade_level)?$row->grade_level:NULL;
$alignments->{$row->table_id}->indicators = new StdClass();
$alignments->{$row->table_id}->indicators->{$row->indicator_id} = new StdClass();
$alignments->{$row->table_id}->indicators->{$row->indicator_id}->indicator_id = isset($row->indicator_id)?$row->indicator_id:NULL;
$alignments->{$row->table_id}->indicators->{$row->indicator_id}->indicator = isset($row->indicator)?$row->indicator:NULL;
$alignments->{$row->table_id}->indicators->{$row->indicator_id}->key = isset($row->key)?$row->key:NULL;
$alignments->{$row->table_id}->indicators->{$row->indicator_id}->extra_data = isset($row->extra_data)?$row->extra_data:NULL;
$alignments->{$row->table_id}->indicators->{$row->indicator_id}->uri_k5 = isset($row->uri_k5)?$row->uri_k5:NULL;
$alignments->{$row->table_id}->indicators->{$row->indicator_id}->uri_612 = isset($row->uri_612)?$row->uri_612:NULL;
}
return $alignments;
}
The problem is that in the foreach loop if there are multiple items with the same $row->table_id then the last one in the loop is set (ignoring all others). I have tried the !isset($alignments->{row->table_id}) and it is still overriding. I am trying to say that if the variable of $alignments->{$row->table_id} exists, use it, if not, set it to a new StdClass()

Maybe you need to wrap your initialization like this:
if (!property_exists($alignment, $row->table_id)) {
$alignments->{$row->table_id} = new StdClass();
}

Related

Laravel reuse of variable with nested relationships does not keep original data

While trying to reuse a variable in two different classes, the first class affects the data of the variable passed to the second class.
Example of problem:
class SampleA
{
public function __construct($products)
{
// Has 3 rows since it's the first class being called
unset($products[0]);
}
}
class SampleB
{
public function __construct($products)
{
// Should have 3 rows, only has 2
unset($products[1]);
}
}
$collection = \App\Models\Products::with('barcodes')->with('stock')->limit(3)->get(); // 3 rows for test purposes
$first = new SampleA($collection);
$second = new SampleB($collection);
// The $collection should have 3 rows and only has 1
print_r($collection);
What have I tried without success:
Use of collect:
$collection = \App\Models\Products::with('barcodes')->with('stock')->limit(3)->get();
$copyCollectionFirst = collect($collection);
$copyCollectionSecond = collect($collection);
$first = new SampleA($copyCollectionFirst);
$second = new SampleB($copyCollectionSecond);
Use of clone:
$collection = \App\Models\Products::with('barcodes')->with('stock')->limit(3)->get();
$copyCollectionFirst = clone $collection;
$copyCollectionSecond = clone $collection;
$first = new SampleA($copyCollectionFirst);
$second = new SampleB($copyCollectionSecond);
Use of replicate:
$collection = \App\Models\Products::with('barcodes')->with('stock')->limit(3)->get();
$copyCollectionFirst = [];
$copyCollectionSecond = [];
foreach ($collection as $row)
{
$copyCollectionFirst[] = $row->replicate();
$copyCollectionSecond[] = $row->replicate();
}
$copyCollectionFirst = collect($copyCollectionFirst);
$copyCollectionFirst = collect($copyCollectionSecond);
$first = new SampleA($copyCollectionFirst);
$second = new SampleB($copyCollectionSecond);
Whatever I do in the SampleA class, it will affect the SampleB class variable data.
What works:
Query multiple times the database:
$collectionFirst = \App\Models\Products::with('barcodes')->with('stock')->limit(3)->get();;
$collectionSecond = \App\Models\Products::with('barcodes')->with('stock')->limit(3)->get();;
$first = new SampleA($collectionFirst);
$second = new SampleB($collectionSecond);
Is there any way to avoid query DB multiple times? In my case this is important, since I might have thousands of records & use it more than 2 times.
try
$collection = \App\Models\Products::with('barcodes')->with('stock')->limit(3)->get()->toArray();
$first = new SampleA(collect($collection));
$second = new SampleB(collect($collection));
Solved.
Solution:
$copyCollectionFirst = unserialize(serialize($collection));
$copyCollectionSecond = unserialize(serialize($collection));

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.

Calling a variable from another script

im trying assign values to my variables in ascript by calling a function and variables from another script, but currently im getting errors saying
Undefined property: stdClass::$Boys in
Undefined property: stdClass::$Girls in
im calling a function in a script called report.php from my script
report.php
public function projectReport($ID){
$get_con = $this->getConnection();
$result = mysql_query($query, $get_con);
$rep = new stdClass();
if(false !== $result){
$multis = array();
while($row = mysql_fetch_array($result, MYSQL_ASSOC)){
$count = new stdClass();
$count->Boys = (int)$row['males'];
$count->Girls = (int)$row['females'];
$multis[] = $count;
}
$rep->multiples = $multis;
}
return $rep;
}
function body of my script
$report = new Report();
$log = $report->projectReport($ID);
if($log != false){
$Boys = $log->Boys;
$Girls = $log->Girls;
print_r($Boys);
print_r($Girls);
}
return $log;
your $log can never be false so you don't need to check that. Alhtough multiples attribute might be missing.
Try this:
$report = new Report();
$log = $report->projectReport($ID);
if(property_exists($log, 'multiples')){ //check if multiples attribute exists
foreach ($log->multiples as $m) //walk through every multiples record
{
$Boys = $m->Boys; //get Boys and Girls attributes values and print them
$Girls = $m->Girls;
print_r($Boys);
print_r($Girls);
}
}
I'm pretty sure that's not what you wanna achieve, but that how it should work based on what you've got so far.

First array element getting overwritten by the second when getting data from db using PHP

I have a few lines of code that start something like this:
$trailheads = array();
// Then a db call with a query. Then loop through the results.
// This gives a diff value every time, so here we are still ok
$trailhead->trailhead_name = $row['trailhead_name'];
// Before the look iteration ends, I do something like this:
array_push ( $trailheads , $trailhead );
// But I could have done this with the same result:
$trailheads[] = $trailhead;
And once I exit the loop, I do print_r and it shows that the second of the two rows returned by the query over-wrote the first.
Here is the full version of the loop:
while($row = mysql_fetch_assoc($trailhead_result))
{
$trailhead->trailhead_name = $row['trailhead_name'];
$trailhead->park_id = $row['park_id'];
$trailhead->trailhead_id = $row['trailhead_id'];
$trailhead->trailhead_description = $row['trailhead_description'];
$trailhead->parking = $row['parking'];
$trailhead->lat = $row['lat'];
$trailhead->lng = $row['lng'];
$trailhead->is_free = $row['is_free'];
$trailhead->parking_spots = $row['parking_spots'];
$trailhead->cost_details = $row['cost_details'];
$trailheads[] = $trailhead;
}
If that's your full loop, then one problem is that you're not initializing $trailhead inside the loop. Do this:
while($row = mysql_fetch_assoc($trailhead_result))
{
$trailhead = new trailhead();
$trailhead->trailhead_name = $row['trailhead_name'];
$trailhead->park_id = $row['park_id'];
$trailhead->trailhead_id = $row['trailhead_id'];
$trailhead->trailhead_description = $row['trailhead_description'];
$trailhead->parking = $row['parking'];
$trailhead->lat = $row['lat'];
$trailhead->lng = $row['lng'];
$trailhead->is_free = $row['is_free'];
$trailhead->parking_spots = $row['parking_spots'];
$trailhead->cost_details = $row['cost_details'];
$trailheads[] = $trailhead;
}
I have to assume that the object $trailhead is a class called trailhead. If it's not, use whatever class is correct in place of new trailhead().

Need some help to determine the amount of recursive calls in PHP

I've got a, I think fairly easy question, but this is bugging me for a while now. So I figured, maybe I can get some help here.
Since recursive functions are always a bit tricky, and sometimes a bit unclear to me, I keep struggling to create a nice working solution to get my menudata.
In one of my classes I have this function, which gives me all menu-items recursively.
The thing I want is to determine at which recursion level a certain object was retrieved so I can create a nicely looking HTML output with indents for the levels of nesting.
public function GetObjectList($parentID = 0, $objectlist = null)
{
if(is_null($objectlist))
{
$objectlist = new ObjectList("Model_Navigation");
}
$query = MySQL::Query("SELECT * FROM `Navigation` WHERE `WebsiteID` = ".SITE_ID. " AND `LanguageID` = ".LANG_ID." AND `ParentID` = ".$parentID);
while($result = MySQL::FetchAssoc($query))
{
$object = new Model_Navigation();
$object->ID = $result["ID"];
$object->WebsiteID = $result["WebsiteID"];
$object->LanguageID = $result["LanguageID"];
$object->ParentID = $result["ParentID"];
$object->Name = $result["Name"];
$object->Page = Model_Page::GetObjectByID($result["PageID"]);
$object->ExternalURL = $result["ExternalURL"];
$object->Index = $result["Index"];
$object->Level = [here lies my problem];
$objectlist->Add($object);
self::GetObjectList($object->ID, $objectlist);
}
return $objectlist;
}
public function GetObjectList($parentID = 0, $objectlist = null, $level = 1)
{
if(is_null($objectlist))
{
$objectlist = new ObjectList("Model_Navigation");
}
$query = MySQL::Query("SELECT * FROM `Navigation` WHERE `WebsiteID` = ".SITE_ID. " AND `LanguageID` = ".LANG_ID." AND `ParentID` = ".$parentID);
while($result = MySQL::FetchAssoc($query))
{
$object = new Model_Navigation();
$object->ID = $result["ID"];
$object->WebsiteID = $result["WebsiteID"];
$object->LanguageID = $result["LanguageID"];
$object->ParentID = $result["ParentID"];
$object->Name = $result["Name"];
$object->Page = Model_Page::GetObjectByID($result["PageID"]);
$object->ExternalURL = $result["ExternalURL"];
$object->Index = $result["Index"];
$object->Level = $level;
$objectlist->Add($object);
self::GetObjectList($object->ID, $objectlist, $level+1);
}
return $objectlist;
}
Why don't you just add a parameter to the function call that stores the number of calls. At the first call just make that 0, increment the value inside the function and use it in the recursive call.

Categories