I'm trying to push data to an array inside a foreach loop. Empty values get pushed into the array.
I tried logging out the values to see if they were empty but they were there, they only go missing when pushing to the array. I also tried to just assign the value to another variable and that worked fine.
$winners = \App\Winner::where('gameid', 577)->pluck('prizes_web_1');
$xml = simplexml_load_string(stripslashes($winners));
$winners_1 = [];
foreach($xml->Winner as $v) {
$out->writeln($v); //when logging here every value gets logged correctly
array_push($winners_1, $v);
}
$out->writeln($winners_1); //here an array with 4 empty values gets logged
I tried declaring the array as array()
, the issue stayed. Tried assigning the value like so winners_1[] = $v
still everything remained the same. Also tried using strval($v)
but that didn't help either
I can't figure out what is causing the problem, never have I come across something like that when pushing to arrays.
EDIT Here's an example of xml:
<?xml version='1.0' encoding='UTF-8'?>
<Winners>
<Winner><name>Robb Stark</name></Winner>
<Winner><name>Jon Snow</name></Winner>
<Winner><name>Aria Stark</name></Winner>
<Winner><name>Theon Greyjoy</name></Winner>
</Winners>
Also the $log->writeln()
line are logging things to the console, when loging the $v
I can see the values Robb Stark
, Jon Snow
etc logged, they dissapear when pushing to the array.
EDIT 2 Added more context to the sample code above.
EDIT 3 SOLUTION
Thank you @misorude
I just needed to cast my xml name
element and it worked.
$winners_1[] = (string)$v->name;
The issue here wasn’t really adding the elements into the array, but what was actually added - and how it got processed / interpreted later on.
SimpleXML is what you’d traditionally call a “fickle mistress”. Often SimpleXMLElement instances behave like strings in certain contexts - but then don’t in a slightly different one.
I didn’t go look up the inner workings of Symfony’s ConsoleOutput, but how exactly that creates output from the input objects has probably played a role here.
Casper’s advice to cast them into strings was a good idea - if you don’t need any properties / methods a SimpleXMLElement object offers later on any more, and you just need their contained “data” - then casting them as soon as possible is a good way to avoid further troubles.
You can not directly cast $v into a string here though - because the Winner
element did not contain the text directly, but it was wrapped in an additional name
element. Casting a SimpleXMLElement that in turn contains other elements into a string would just result in an empty string again.
So the name
element itself needs to be accessed and cast into a string here - (string) $v->name