I am getting data from XML files that I need to make into an array in PHP. Can any one tell me how to fill PHP array when count is unknown?
function getFeed($feed_url)
{
$content = file_get_contents($feed_url);
$x = new SimpleXmlElement($content);
echo "<ul>";
foreach($x->channel->item as $entry)
{
echo "
<li>
<a href='$entry->link' title='$entry->title' target='_new'> " . $entry->title . "</a>
</li>";
}
echo "</ul>";
}
Question: can any one tell me how to fill php array when count is unknown
Declare the array and add items to it like so or use array_push
$something = array();
$something[] = 'first item';
$something[] = 'second item';
Hope this works for you:
$c = 0;
$entries = Array();
foreach($x->channel->item as $entry) {
echo "
<li>
<a href='$entry->link' title='$entry->title' target='_new'> " . $entry->title . " </a>
</li>";
$entries[$c] = $entry->title;
$c++;
}
function getFeed($feed_url) {
$content = file_get_contents($feed_url);
$x = new SimpleXmlElement($content);
$count = 0;
$data = array();
foreach($x->channel->item as $entry) {
$data[$count]['link'] = $entry->link;
$data[$count]['title'] = $entry->title;
$count++;
}
return $data;
}
might be a better solution. You can then manipulate the data in a more flexible way; keeping the data from presentation separate. Simply loop through $data and output it as you require.
You can always use array_push() or basic array method.
http://php.net/manual/en/function.array-push.php
Array Push
$list = array();
array_push($list,$element);
or
$list[] = $element;
Full Code
<?php
function getFeed($feed_url) {
$content = file_get_contents($feed_url);
$x = new SimpleXmlElement($content);
$list = array();
foreach($x->channel->item as $entry) {
array_push($list,$entry);
}
return $list;
}
$list = getFeed("url");
echo "<ul>";
foreach($list as $entry) {
echo "
<li>
<a href='$entry->link' title='$entry->title' target='_new'> " . $entry->title . "</a>
</li>";
}
echo "</ul>";
?>
I can see you print an HTML list while navigating through XML nodes. So if I got your question, you also need to fill an array (in the meanwhile) with the data taken from the XML, actually converting your XML into an array... is that what you want?
Then, you just need to declare an empty array before the foreach statement:
$arr = array();
and then, inside your foreach, add new fields to the array this way:
$arr[] = $entry;
If you need to specify more fields, you can do something like that:
$arr[] = array(
'field' => $entry->fieldvalue
);`
Hope this helps!
Related
Basically I'm trying to group my arrays like this:
Shopping
Amazon
Social
Amoeblo
American express
By using below PHP code:
<?php
echo '<ul id="list"><h2 class="searchresults"></h2>';
foreach($records as $catval) {
$sitechar = $catval->site_category;
echo '<h3 id="disappear">'. strtoupper($sitechar) .'</h3>';
echo '<li class="siteli"><a href="#" class="add">';
echo '<p id="text-site">'.$catval->site_name. '</p></a>';
echo '</li>';
}
echo '</ul>';
?>
But I'm getting values only like below.
Shopping
Amazon
Social
Amoeblo
Social
American express
I'm not getting the exact PHP sorting to use for this.
I would create a new array with categories as keys for arrays with the sites.
<?php
$arr = array();
// First create multidimensional array with categories as keys for site arrays
foreach($records as $catval) {
$sitechar = $catval->site_category;
if (!array_key_exists($sitechar, $arr)) {
// Set new array for a category if it does not exist
$arr[$sitechar] = array();
}
// Add site to category
$arr[$sitechar][] = array(
"name"=>$catval->site_name,
"image"=>$catval->site_img
);
}
// Then iterate the new array of categories
echo ("<ul>");
foreach($arr as $category => $sites) {
echo("<h3>" . $site_category "</h3>");
// Iterate array of sites
foreach($sites as $site) {
echo("<li>" . $site["name"] . "-" , $site["image"] . "</li>");
}
}
echo("</ul>");
?>
You can do it using a foreach and ksort
Let $your_array be the array you mentioned above
$res_array = array();
foreach($your_array as $val){
$res_array[$val->site_category][] = $val->site_name;
}
ksort($res_array);
print_r($res_array);
OR search for multisort in php which will solve your problem :)
$tmp = null;
echo '<ul id="list"><h2 class="searchresults"></h2>';
foreach($records as $catval) {
$myHtml = makeHtml($catval,$tmp);
echo $myHtml;
$tmp = $catval->site_category;
}
echo '</ul>';
function makeHtml($catval,$tmp){
if($tmp != $catval->site_category){ $html .= '<h3 id="disappear">'. strtoupper($catval->site_category) .'</h3>';}
$html .='<li class="siteli"><p id="text-site">'.$catval->site_name. '</p></li>';
return $html;
}
I´ve got the a php that returns a JSON string:
$recipes = json_encode($arr);
That is my php-code how I output the recipe-title:
<?php
include('php/getAllRecipes.php');
$jsonstring = $recipes;
$recip = json_decode($recipes, true);
$i = 1;
var data = include('php/getAllRecipes.php')Data.Recipes;
foreach ($recip['Data']['Recipes'] as $key => $recipe) {
echo "$i.)   ";
echo $recipe['TITLE'];
$i = $i + 1;
echo "<br>";
}
?>
Now, I need to add a href to each title. The href should contain a link to recipe_search.php and I have to give it the id of each recipe.
How can I add this href?
<?php
include('php/getAllRecipes.php');
$jsonstring = $recipes;
$recip = json_decode($recipes, true);
?>
<ol>
<?php
foreach ($recip['Data']['Recipes'] as $key => $recipe) {
echo '<li>
<a href="/recipe_search.php?id=' . $recipe['ID'] . '">
' . $recipe['TITLE'] . '
</a>
</li>';
}
?>
</ol>
Use an ordered list (<ol>) instead of trying to create one yourself using a counter.
var data = include('php/getAllRecipes.php')Data.Recipes; is not valid PHP.
I assume that the id of the recipe is in $recipe['ID'].
Here you are...
foreach ($recip['Data']['Recipes'] as $key => $recipe)
{
// I guess $key is ID of your recipe...
echo sprintf('%d.) %s<br />', $i++, 'recipe_search.php?id=' . $key, $recipe['TITLE']);
}
Thats worked for me, just to test the above:
<?php
$i = 1;
foreach (array_fill(0, 40, 'recipe') as $key => $recipe)
{
// I guess $key is ID of your recipe...
echo sprintf('%d.) %s<br />', $i++, 'recipe_search.php?id=' . $key, $recipe);
}
?>
here is my working php explode code for NON links:
<?php
$textarea = get_custom_field('my_custom_output');
$array = explode(',',$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
$item = trim($item); // clear off white-space
$output .= '<li>' . $item . '</li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
..and the code which defines "my_custom_output", which I input into my textarea field:
text1,text2,text3,etc
..and the finished product:
text1
text2
text3
etc
So that works.
Now what I want to do is make text1 be a link to mywebsite.com/text1-page-url/
I was able to get this far:
<?php
$textarea = get_custom_field('my_custom_output');
$array = explode(',',$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
$item = trim($item); // clear off white-space
$output .= '<li class="link-class"><a title="' . $item . '" href="http://mywebsite.com/' . $item_links . '">' . $item . '</a></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
Now, I would like $item_links to define just the rest of the url. For example:
I want to put input this into my textarea:
text1:text1-page-url,text2:new-text2-page,text3:different-page-text3
and have the output be this:
text1
text2
..etc (stackoverflow forced me to only have two links in this post because I only have 0 reputation)
another thing I want to do is change commas to new lines. I know the code for a new line is \n but I do not know how to swap it out. That way I can put this:
text1:text1-page-url
text2:new-text2-page
text3:different-page-text3
I hope I made this easy for you to understand. I am almost there, I am just stuck. Please help. Thank you!
Just split the $item inside your loop with explode():
<?php
$separator1 = "\n";
$separator2 = ":";
$textarea = get_custom_field('my_custom_output');
$array = explode($separator1,$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
list($item_text, $item_links) = explode($separator2, trim($item));
$output .= '<li class="link-class"><a title="' . $item_text . '" href="http://mywebsite.com/' . $item_links . '">' . $item_text . '</a></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
And choose your string separators so $item_text, $item_links wouldn't contain them.
After you explode the string you could loop through again and separate the text and link into key/values. Something like...
$array_final = new array();
$array_temp = explode(',', $textarea);
foreach($array_temp as $item) {
list($text, $link) = explode(':', $item);
$array_final[$text] = $link;
}
foreach($array_final as $key => $value) {
echo '<li>'.$key.'</li>';
}
to change comma into new line you can use str_replace like
str_replace(",", "\r\n", $output)
I have inherited some PHP code (but I've little PHP experience) and can't find how to count some elements in the object returned by simplexml_load_file()
The code is something like this
$xml = simplexml_load_file($feed);
for ($x=0; $x<6; $x++) {
$title = $xml->channel[0]->item[$x]->title[0];
echo "<li>" . $title . "</li>\n";
}
It assumes there will be at least 6 <item> elements but sometimes there are fewer so I get warning messages in the output on my development system (though not on live).
How do I extract a count of <item> elements in $xml->channel[0]?
Here are several options, from my most to least favourite (of the ones provided).
One option is to make use of the SimpleXMLIterator in conjunction with LimitIterator.
$xml = simplexml_load_file($feed, 'SimpleXMLIterator');
$items = new LimitIterator($xml->channel->item, 0, 6);
foreach ($items as $item) {
echo "<li>{$item->title}</li>\n";
}
If that looks too scary, or not scary enough, then another is to throw XPath into the mix.
$xml = simplexml_load_file($feed);
$items = $xml->xpath('/rss/channel/item[position() <= 6]');
foreach ($items as $item) {
echo "<li>{$item->title}</li>\n";
}
Finally, with little change to your existing code, there is also.
$xml = simplexml_load_file($feed);
for ($x=0; $x<6; $x++) {
// Break out of loop if no more items
if (!isset($xml->channel[0]->item[$x])) {
break;
}
$title = $xml->channel[0]->item[$x]->title[0];
echo "<li>" . $title . "</li>\n";
}
The easiest way is to use SimpleXMLElement::count() as:
$xml = simplexml_load_file($feed);
$num = $xml->channel[0]->count();
for ($x=0; $x<$num; $x++) {
$title = $xml->channel[0]->item[$x]->title[0];
echo "<li>" . $title . "</li>\n";
}
Also note that the return of $xml->channel[0] is a SimpleXMLElement object. This class implements the Traversable interface so we can use it directly in a foreach loop:
$xml = simplexml_load_file($feed);
foreach($xml->channel[0] as $item {
$title = $item->title[0];
echo "<li>" . $title . "</li>\n";
}
You get count by count($xml).
I always do it like this:
$xml = simplexml_load_file($feed);
foreach($xml as $key => $one_row) {
echo $one_row->some_xml_chield;
}
I only want the first and the second last Area nodes - how would I do that here?
$url = "http://developer.multimap.com/API/geocode/1.2/OA10081917657704697?qs=Byker&countryCode=GB";
$results = simplexml_load_file($url);
foreach($results->Location as $location) {
echo "<hr />";
foreach($location->Address as $address) {
foreach($address->Areas as $areas) {
foreach($areas->Area as $area) {
echo $area;
echo "<br />";
}
}
}
}
Update: If you have those foreach-loops anyway you can simply use:
$url = "http://developer.multimap.com/API/geocode/1.2/OA10081917657704697?qs=Byker&countryCode=GB";
$results = simplexml_load_file($url);
foreach($results->Location as $location) {
foreach($location->Address as $address) {
foreach( $address->Areas as $areas) {
// <-- todo: add test if those two elements exist -->
echo $areas->Area[0], ' - ', $areas->Area[count($areas->Area)-1], "\n";
}
}
}
You can use XPath for this.
<?php
$doc = new SimpleXMLElement('<foo>
<bar>a</bar>
<bar>b</bar>
<bar>c</bar>
<bar>x</bar>
<bar>y</bar>
<bar>z</bar>
</foo>');
$nodes = $doc->xpath('bar[position()=1 or position()=last()-1]');
foreach( $nodes as $n ) {
echo $n, "\n";
}
prints
a
y
see also:
PHP Manual: SimpleXMLElement::xpath()
XPath: predicates
XPath: position()
XPath: last()
Here it is:
<?php
$url = 'http://developer.multimap.com/API/geocode/1.2/OA10081917657704697?qs=Byker&countryCode=GB';
$results = simplexml_load_file($url);
$areas = array();
foreach ($results->Location->Address->Areas->Area as $area)
{
$areas[] = (string) $area;
}
$first = $areas[0];
$second_last = $areas[count($areas)-2];
?>