views:

409

answers:

1

I want to use the PHP Simple HTML DOM Parser to display all my Left4Dead Steam achievements on my website. The achievements list on the steam community website looks something like this:

<img src="…" /><br />
<div class="achieveImgHolder"><img src="…" /></div>
<div class="achieveTxtHolder">
 <img src="…" />
 <div class="achieveTxt">
  <h3>Stand Tall</h3>
  <h5>Survive a campaign without being incapacitated.</h5>
 </div>
</div>
<br clear="left" />

Active achievements are separated from inactive achievements by

<br /><br /><br />

So I wrote the this code to display my achievements:

<?php
include("simple-html-dom-parser.php");
$achievementPage = file_get_html("http://steamcommunity.com/id/snorpey/stats/L4D?tab=achievements");
$activeInactiveSplit = split("<br /><br /><br />", $achievementPage);
$actives = str_get_html($activeInactiveSplit[0]);
$inactives = str_get_html($activeInactiveSplit[1]);

foreach($actives->find(".achieveTxtHolder") as $achievement)
{
 echo $achievement->find(".achieveTxt h3", 0)->innertext;
}
?>

I always get the following error and have no idea where comes from.

Fatal error: Call to a member function find() on a non-object in testing.php on line 8

I tested the parser with another part of the page and it worked properly. It seems to have problems with splitting the page.

echo $actives // works w/out errors

What exactly went wrong here?

+3  A: 

Change...

$actives->find(".achieveTxtHolder", 0)

to...

$actives->find(".achieveTxtHolder")

Specifying 0 returns only the first occurrence instead of an iterable list of occurrences; since you're using a foreach you want all of the occurrences. Otherwise the foreach tries to iterate over something that's not a list, and thus your $achievement variable is actually NULL, hence why you get an error when you try to invoke ->find() on it.

Amber
Thanks for your quick answer. I changed the script as you proposed, but it keeps running into the same error.
snorpey
Have you tried dumping out the contents of `$activeInactiveSplit[0]` and `$activeInactiveSplit[1]` (via something like `print_r($activeInactiveSplit)` and seeing if they match your expectations? Likewise, try dumping out what you get back from your first `find()` call and see if it's what you expect.
Amber
@Snorpey and please click the check to accept Dav's answer, thx.
Don
Patience Don, it doesn't seem like the issue is fully resolved yet. :)
Amber
@snorpey: What happens if you `print_r($actives->find(".achieveTxtHolder"))`?
Amber
print_r($activeInactiveSplit) returns an array. [0] contains the source code if the page before "<br /><br /><br />", [1] contains the rest. I still have no idea why $actives->find(".achieveTxtHolder") doesn't work as expected.
snorpey
and print_r($actives->find(".achieveTxtHolder")) produces "Fatal error: Call to a member function find() on a non-object ..."
snorpey
Sounds like your find() call isn't actually finding anything. Are you sure you spelled the class name correctly, etc?
Amber
Just found the typo; the script works now. THANKS A LOT!
snorpey