New to PHP, Cannot retrieve info from Array correctly

Hello there all. I’m just learning PHP and I wanted to start by making a script which would read an RSS feed, strip out what I do not want to display, and output only one number (or an average of them all). In my case, I am reading the RSS from a government website which tracks fuel prices.

I’m able to pull the RSS feed, display the data and so forth. My problem is, the array contains everything in one element (?). So not only are price being displayed, but other information which (for me) is unnecessary. I only need one price, or an average of them all.

I have tried limiting the amount of data displayed, and various methods of stripping out the things like state names, etc. However, the method I am using displays every number and (since I need the decimal points), displays EVERY decimal point in the text, not just those in the fuel prices.

Now please don’t be too harsh. I’ve been trying for a while with codeviper and then my local xampp install to do this. My var_dump displays close to what I want, but you’ll see the problem occurs with my filter. And also I cannot select an individual gasoline price because of the way the RSS feed is formatted. That data is under one block (description), so I have to pull it all (I think).

Here is what I have so far (the commented out code was an earlier attempt to limit the amount of data displayed from the stream to perhaps make it easier to filter or search for and match a pattern).

[php]<?php
$rss = new DOMDocument();
$rss->load(‘http://www.eia.gov/petroleum/gasdiesel/includes/gas_diesel_rss.xml’);
$feed = array();
foreach ($rss->getElementsByTagName(‘item’) as $node) {
$item = array (
‘desc’ => $node->getElementsByTagName(‘description’)->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 1;
for($x=0;$x<$limit;$x++) {

	$description = $feed[$x]['desc'];
	// only to limit the number of items displayed $description = substr($description, 0, 160);
	echo '<p>'.$description.'</p>';
}

$arr = $item;

foreach($arr as &$item) {
$item = preg_replace(’/[^0-9.]*/’, ‘’, $item);
}

var_dump($arr);

?>[/php]

Any pointers would be appreciated. I’ve been searching the PHP manual and trying various filters. Ideally, I want to be able to display only one number (the US average would be fine… or simply to be able to find all the numbers, average them, set it as a variable and display that). I’m a bit stuck ???

I will try to review this tomorrow when I can test your code. Have you tried to experiment with SimpleXML instead? It’s quite a bit easier than working with DOMDocument

http://php.net/manual/en/book.simplexml.php

I appreciate that. I tried using cURL and SimpleXML, but I’m still left with this problem: how do I isolate the data I want? Currently, the xml document is formatted with everything in the description area and there are no tags within that to target.

The only thing I can think of is using some sort of pattern matching search to target integers like n.nnn where n=0-9. I search for and pick up the first one and use that. I have no idea how to do that in PHP though. And stripping out characters isn’t working because I’m getting left with a bunch of extra decimal points from that data set.

This is what I tried:

[php]<?php
$fuel_rss = curl_init();
curl_setopt($fuel_rss, CURLOPT_URL, ‘http://www.eia.gov/petroleum/gasdiesel/includes/gas_diesel_rss.xml’);
curl_setopt($fuel_rss, CURLOPT_HEADER, 0);
curl_setopt($fuel_rss, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($fuel_rss);
curl_close($fuel_rss);

$xml = new SimpleXMLElement($data);
foreach($xml->channel->item as $post) {

echo $post->description; //description causes the problem... everything is located here

}

?>[/php]

I see what you mean… perhaps preg_replace is the wrong function to use. What if you did something like this with preg_match

[php]
$str = “3.580 … Central Atlantic”;
preg_match(’/([0-9]+.{1}[0-9]+)/’, $str, $parts);
print_r($parts);
[/php]

This code outputs:


Array
(
    [0] => 3.580
    [1] => 3.580
)

I want to add that you could also use typecasting or floatval() to achieve this:

Typecasting:
[php]
$str = “3.580 … Central Atlantic”;
echo (float) $str;
[/php]

floatval()
[php]
$str = “3.580 … Central Atlantic”;
echo floatval($str);
[/php]

I was just looking up preg_match. I was looking at $item = preg_match(’[0-9].[0-9][0-9][0-9]’,$item); (syntax is wrong, I’ll be trying yours).

I found http://www.regexpal.com/ … what an amazing tool.

I like your idea, I’m just worried about using the … Central Atlantic"; in the pattern. I have no idea if this changes or not, so I’m hoping i’ll be able to do something with n.nnn where n = [0-9] according to regex. Don’t know how to insert that decimal though, so I’m still reading on that!

I think it might be like [\d+][^\n][0-9][0-9][0-9] according to http://www.bio.ic.ac.uk/Evolve/docs/regex.html

Thanks so much. I’ll post my code if I get this to work. Once I have this down, I’m going to add some logic in the event the RSS returns as NULL so I don’t get anything nasty.

If the description always begins with a float value then nothing else matters.

[0-9].[0-9][0-9][0-9] this isn’t even a valid regex. It may work, to an extent, but the additional [0-9] do not match by character

Gotcha.

I was also feeding in the wrong variable into preg_match at this point :-[ lol

this is what I’ve got

[php]<?php
$rss = new DOMDocument();
$rss->load(‘http://www.eia.gov/petroleum/gasdiesel/includes/gas_diesel_rss.xml’);
$feed = array();
foreach ($rss->getElementsByTagName(‘item’) as $node) {
$item = array (
‘desc’ => $node->getElementsByTagName(‘description’)->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 1;
for($x=0;$x<$limit;$x++) {

	$description = $feed[$x]['desc'];
	//only to limit the number of items displayed 
	$description = substr($description, 0, 160);
	echo '<p>'.$description.'</p>';
}

echo “
”;
$str = $description;
preg_match(’/([0-9]+.{1}[0-9]+)/’, $str, $item);
print_r($item);

?>[/php]

Hate replying to my own post, but I can’t seem to modify my old one. It shouldn’t be necessary to limit the characters to 160, so I’ve removed that line.

I could see it causing problems if, for whatever reason, the format changed.

I just want to add one more. This can be done with preg_replace:

[php]
$str = preg_replace(array(’/[^0-9.]/’, ‘/[.]{2,}/’), array(’’, ‘’), $str);
[/php]

The first removes anything that is not 0-9, the second removes 2 or more decimals

One final question… now that I’ve isolate that through preg_match, how to I print it as a non array? I was trying to use

[php]$string = var_export($item, true);
print $string[/php]

but I get

array ( 0 => '3.542', 1 => '3.542', )

for my
[php]$string = var_export($item, true);
print $string[/php]

full code is:

[php]<?php
$rss = new DOMDocument();
$rss->load(‘http://www.eia.gov/petroleum/gasdiesel/includes/gas_diesel_rss.xml’);
$feed = array();
foreach ($rss->getElementsByTagName(‘item’) as $node) {
$item = array (
‘desc’ => $node->getElementsByTagName(‘description’)->item(0)->nodeValue,
);
array_push($feed, $item);
}
$limit = 1;
for($x=0;$x<$limit;$x++) {

	$description = $feed[$x]['desc'];

	echo '<p>'.$description.'</p>';
}

echo “
”;
$str = $description;
preg_match(’/([0-9]+.{1}[0-9]+)/’, $str, $item);
print_r($item);
echo “
”;
var_dump($item);
echo “
”;

$string = var_export($item, true);
print $string

?>
[/php]

I thought var_export was the thing to use… I also tried array_shift … but I don’t know enough about arrays to pull this out as an output like “3.452”

If you specify the 3rd param in preg_match it will always be an array of “matches”

The matches are what are contained in the parentheses ()

So if your regex contains one set of parentheses then you would use $item[1] to access the first match

That makes perfect sense. I was trying to use implode next haha.

I did:

[php]echo “
”;
$str = $description;
preg_match(’/([0-9]+.{1}[0-9]+)/’, $str, $item);
print_r($item[1]);[/php]

And it works perfectly. I think I’m going to love PHP. Thank you very much for your help. I’m going to be reading some more tutorials and hopefully not have to need so much help with arrays now :slight_smile:

I am still unable to retrieve the array using the code you shared.

My RSS filtering code or the code supplied by m@tt? They are both working for me.

Btw m@tt when I get the ability to give karma, I will give you some!

Sponsor our Newsletter | Privacy Policy | Terms of Service