Displaying 5 latest thumbnails from public flickr api using atom_1 and php

余生长醉 提交于 2019-12-11 19:19:28

问题


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">           &lt;p&gt;&lt;a href="http://www.flickr.com/people/osvaldorainero/"&gt;Osvaldo Rainero&lt;/a&gt; posted a photo:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez  01-05-13"&gt;&lt;img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez  01-05-13" /&gt;&lt;/a&gt;&lt;/p&gt;

</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">           &lt;p&gt;&lt;a href="http://www.flickr.com/people/osvaldorainero/"&gt;Osvaldo Rainero&lt;/a&gt; posted a photo:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/osvaldorainero/8709806523/" title="Picadas, Marco Juarez  01-05-13"&gt;&lt;img src="http://farm9.staticflickr.com/8114/8709806523_3b8d7c0418_m.jpg" width="240" height="161" alt="Picadas, Marco Juarez  01-05-13" /&gt;&lt;/a&gt;&lt;/p&gt;

</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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!