PHP foreach Loop Element Index - php

I have an XPath query that gets Genres of a movie.
$genreXpath = $xml_data->xpath("//category");
I get the attributes from $genreXpath like this
$genreName=array();
$genresID=array();
$i=0;
foreach($genreXpath as $node) {
$genre = $node->attributes();
$genreName[$i] = $node["name"];
$genresID[$i] = $node["id"];
$i++;
}
I'm going to be writing these values to a Db hence the two different arrays.
This code works but I know there has to be a better way of doing this be it with a 2 d array, not using a $i counter or something more obvious that I haven't figured out....any pointers???

foreach($genreXpath as $i=>$node) { //note $i is your index of the current $node
$genre = $node->attributes();
$genreName[$i] = $node["name"];
$genresID[$i] = $node["id"];
}
It auto increments and you do not need to declare it above.

Use foreach($genreXpath as $key => $node) {

If you looking to a multidimensional you could do:
$genres = array();
foreach($genreXpath as $node) {
$genre = $node->attributes();
$genres[] = array($node["name"], $node["id"]);
}

Related

Database information into separate arrays

here is what I'm trying to do. I'm retrieving information from a database via array. What is happening is the information from the previous array is going into the next array.
Here is the code:
$i = 0;
foreach ($array_name as $key => test_name) {
$id = $test_name['id']
foreach ($test_name['id] as $key => $test_id {
$data = ModelClass::Information($test_id);
$array_name[$i]['new_infroamtion'] = $data'
}
}
So right now based on the code data from the table is correctly going into the first array, however, information based from the first array is going into the second array..
Let me know if you need anymore information.
Thank you
You are using $array_name while you are iterating through $array_name. This is valid code if you want to do this, but I don't think you do. You need to change the second $array_name to something else.
$i = 0;
foreach (**$array_name** as $key => test_name) {
$id = $test_name['id']
foreach ($test_name['id'] as $key => $test_id {
$data = ModelClass::Information($test_id);
**$array_name**[$i]['new_infroamtion'] = $data
}
}
I did find a solution. What I had to do was add the following
$s = array()
Then in the for loop, I added the following code:
foreach ($test_name['id] as $key => $test_id {
$data = ModelClass::Information($test_id);
$s[] = $data
$array_name[$i]['new_infroamtion'] = $s'
}

Parse DOM document to array php

*
What I want is, for the DOM to instead of printing the results line by line in a "foreach" loop, rather store it in an array.... So it should look like a list i.e.
"[0] 16GB USB Stick" "[1] Computer monitor" "[2] wireless keyboard"
etc etc
So far I have this, but it only stores the last value from the for each loop.. Please help!
*
$html = new DOMDocument();
#$html->loadHtmlFile('some online shop');
$xpath = new DOMXPath($html);
$nodelist = $xpath->query( "//div[#class='productname']/p" );
foreach ($nodelist as $n)
{
$value = $n->nodeValue;
$list = array($value);
}
echo $list[0];
That's because you're overriding it in each loop. Create an array, and add to that array:
$list = array();
foreach ($nodelist as $n)
{
$value = $n->nodeValue;
$list[] = $value;
}
// Check there's at least one item in the array before accessing it
if (count($list) > 0)
{
echo $list[0];
}
You need to look into how arrays work in PHP. What you're doing wrong is you are re-declaring the array on each iteration, instead of adding more information to it.
$list = array();
foreach ($nodelist as $n) {
$list[] = $n->nodeValue;
}
var_dump($list);
Explanation:
[] basically means - add an item in this array, and auto generate the key.
The foreach I wrote is equivalent to this one:
$i = 0;
foreach ($nodelist as $n) {
$list[$i] = $n->nodeValue;
$i ++;
}

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?

failed to add item into an array in the foreach loop

I am new to zend framework and i am having a problem while i was trying to add items into an array.
first i created a db table object:
$questionTable = new xxx();
$db = $questionTable->getAdapter();
$sql = "select * from questions where value='v'";
$res = $db->query($sql)->fetchAll();
the $res is an array which looks like this in JSON [{'a':1},{'a':2},{'a':3}]
then i used a foreach :
foreach($res as $element)
{
$value = $element['a'];
if($value == 2)
{
$element['extra'] = 10;
}
}
then when i print out the result using:
echo Zend_Json_Encoder::encode($res);
it remains [{'a':1},{'a':2},{'a':3}].
does anyone know how to fix it?
thx in advance:)
Just add a magical ampersand to your $element
foreach($res as &$element)
----------------^

How to use array_unique correctly to echo only one time the same posts

I am trying to display the posts of some RSS Feeds and I came up with a question/problem I have, when I have two same feeds I am trying to show not all the posts but the unique. What I was using is this, that shows me all the posts twice (this is logical)
<?php
$feeds = array(
'feed.xml', 'feed.xml'
);
// Get all feed entries
$entries = array();
foreach ($feeds as $feed) {
$xml = simplexml_load_file($feed);
$entries = array_merge($entries, $xml->xpath('/rss/channel//item'));
}
// Sort feed entries by pubDate (ascending)
usort($entries, 'mysort');
function mysort($x, $y) {
return strtotime($y->pubDate) - strtotime($x->pubDate);
}
foreach ($entries as $entry) {
echo $entry->title;
echo "<br>";
}
?>
but when I changed that line to
$entries = array_unique(array_merge($entries, $xml->xpath('/rss/channel//item')));
I get only one post shown.
How can I correctly show the posts only once? Thank you.
Update:
function mysort($x, $y) {
return strtotime($y->pubDate) - strtotime($x->pubDate);
}
$feeds = array( 'http://feeds.bbci.co.uk/news/world/rss.xml',
'http://feeds.bbci.co.uk/news/world/rss.xml'
);
// Get all feed entries
$entries = array();
foreach ($feeds as $feed) {
$xml = simplexml_load_file($feed);
$entries = array_merge($entries, $xml->xpath('/rss/channel//item'));
}
$uniqueEntries = array();
foreach ($entries as $entry) {
$uniqueEntries[(string)$entry->title] = $entry;
}
// Sort feed entries by pubDate (ascending)
usort($entries, 'mysort');
foreach ($uniqueEntries as $entry) {
echo $entry->title;
echo "<br>";
}
From the documentation of array_unique
Note: Two elements are considered equal if and only if (string) $elem1
=== (string) $elem2. In words: when the string representation is the same. The first element will be used.
In this case, the objects you're getting out of the XPath query translate to string form like "SimpleXML object" (not exactly like that, but the exact representation is not important). According to the above rules, then, every element looks exactly the same to array_unique.
Unfortunately, there's no way to make array_unique behave the way you want, so you will need to fake it yourself:
$feeds = array(
'myfeed.xml', 'myfeed.xml'
);
// Get all feed entries
$entries = array();
foreach ($feeds as $feed) {
$xml = simplexml_load_file($feed);
$tmp = $xml->xpath('/rss/channel//item');
foreach ($tmp as $item) {
if(!in_array($tmp, $entries)) {
$entries[] = $tmp;
}
}
}
I'm not sure if this will work, as it depends on being able to compare objects, and also I don't know that identical nodes from separate XML documents would compare the same anyway. But try it, and let me know. I can whip something else up if this doesn't work.

Categories