问题
Im trying to display the latest 5 images from:
http://api.flickr.com/services/feeds/photos_public.gne
with the tag "cars" and then output the latest 5 thumbnails into a blank html document as a type of gallery.
This is as far as i have gotten:
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('http://api.flickr.com/services/feeds/photos_public.gne');
$request->setMethod(HTTP_Request2::METHOD_GET);
$url = $request->getUrl();
$url->setQueryVariable('tags', 'cars');
$url->setQueryVariable('tagmode', 'any');
$url->setQueryVariable('format', 'atom_1');
try {
$response = $request->send();
if (200 == $response->getStatus()) {
$body = $response->getBody();
} else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
} catch (HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
$DOM = new SimpleXMLElement($body);
?>
I don't know if this is correct and i'm not sure how to go about displaying it in html.
回答1:
After looking into the feed of your question, it shows that each item does not have an image element. Therefore accessing it will give you NULL
which is echoed as an empty string (invisible):
foreach ($DOM->entry as $entry) {
echo '<a href="">', htmlspecialchars($entry->title), '</a>', "\n",
'<img src="', $entry->image, '" alt="', htmlspecialchars($entry->title), '" ',
'width="304" height="228">', "\n";
;
}
The exemplary output shows that the title is available, but the image src is empty:
<a href="">Picadas, Marco Juarez 01-05-13</a>
<img src="" alt="Picadas, Marco Juarez 01-05-13" width="304" height="228">
Looking closer into the feed itself it turns out that there is not even any other element containing the thumbnail but the HTML text inside the conent element. And only inside that HTML there are the dimensions of the thumbnail image:
<entry>
<title>Picadas, Marco Juarez 01-05-13</title>
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/osvaldorainero/8709806523/"/>
<id>tag:flickr.com,2005:/photo/8709806523</id>
<published>2013-05-05T15:25:15Z</published>
<updated>2013-05-05T15:25:15Z</updated>
<flickr:date_taken>2013-05-01T15:42:01-08:00</flickr:date_taken>
<dc:date.Taken>2013-05-01T15:42:01-08:00</dc:date.Taken>
<content type="html"> <p><a href="http://www.flickr.com/people/osvaldorainero/">Osvaldo Rainero</a> posted a photo:</p>
<p><a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez 01-05-13"><img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13" /></a></p>
</content>
<author>
<name>Osvaldo Rainero</name>
<uri>http://www.flickr.com/people/osvaldorainero/</uri>
<flickr:nsid>91267729@N05</flickr:nsid>
<flickr:buddyicon>http://farm9.staticflickr.com/8107/buddyicons/91267729@N05.jpg?1363607055#91267729@N05</flickr:buddyicon>
</author>
<link rel="enclosure" type="image/jpeg" href="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_b.jpg"/>
<category term="cars" scheme="http://www.flickr.com/photos/tags/"/>
...
<category term="arrancadas" scheme="http://www.flickr.com/photos/tags/"/>
</entry>
Zoom:
<content type="html"> <p><a href="http://www.flickr.com/people/osvaldorainero/">Osvaldo Rainero</a> posted a photo:</p>
<p><a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez 01-05-13"><img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13" /></a></p>
</content>
This is HTML encoded in XML. And this is kind of a show-stopper for simplexml you use, because it can only return the HTML verbatim out of the box:
echo $entry->content, "\n";
Output (plain text):
<p><a href="http://www.flickr.com/people/osvaldorainero/">Osvaldo Rainero</a> posted a photo:</p>
<p><a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez 01-05-13"><img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13" /></a></p>
This is the important part to understand: You do not only want to parse the XML from the feed, but you additionally want to parse HTML inside the node-value of an XML element.
So you need to extend the SimplexmlElement you use with a HTML parser. That is easy to do because if your PHP version ships with simplexml, it also ships with DOMDocument which has an HTML parser and it can return the parsed result as simplexml so this is pretty compatible.
So the following extends simplexml with a HTML parser:
class HtmledSimpleXML extends SimpleXMLElement
{
/**
* Parses element content as HTML and returns the
* body element of it.
*
* @param string $xpath (optional) specify a different element to return
*
* @return SimpleXMLElement
*/
public function html($xpath = '//body') {
$doc = new DOMDocument();
$doc->loadHTML($this);
$xml = simplexml_import_dom($doc->documentElement);
list($body) = $xml->xpath($xpath);
return $body;
}
}
It already allows to pass an xpath query to specify the concrete element you want to retrieve, normally that is the body
tag from inside the HTML this is why it is set as default. Even if your HTML does not have that tag in there, it actually exists in the DOM, therefore this default is never wrong. But anyway in your case you're interested in the img tag. Thanks to simpelxml we can even output it directly as XML and can spare to even create the HTML by hand.
Usage example:
$DOM = new HtmledSimpleXML($body);
foreach ($DOM->entry as $entry) {
echo '<a href="">', $entry->title, '</a>', "\n",
$entry->content->html('//img')->asXML(), "\n";
;
}
The exemplary output for a single entry then is:
<a href="">Picadas, Marco Juarez 01-05-13</a>
<img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez 01-05-13"/>
Which should come pretty close to what you're looking for. Naturally you can as well just aquire the image-element and access it's attributes like with any other Simplexmlelement:
$thumb = $entry->content->html('//img');
echo 'Title: ', $entry->title, "\n",
'Thumb: ', $thumb['src'], "\n",
'Size : ', $thumb['width'], ' x ', $thumb['height'], "\n";
Output (plain text):
Title: Picadas, Marco Juarez 01-05-13
Thumb: http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg
Size : 240 x 161
I hope this is helpful so far.
Last time I extended SimpleXMLElement on Stackoverflow was to show how to parse CSV data inside the underlying XML structure in PHP simplexml xpath search for value in an ELEMENT containing tab delimited text?.
来源:https://stackoverflow.com/questions/16385026/displaying-5-latest-thumbnails-from-public-flickr-api-using-atom-1-and-php