Mostrando 5 miniaturas más recientes de la API pública de Flickr usando atom_1 y php

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.

preguntado el 05 de mayo de 13 a las 14:05

Sorry if I can only ask back quickly: ¿Por qué don't you know if this is correct or not? Do you have got some error with it? Or do you expect something differently? And with your display problem: Are you aware that HTML has an image element? -

I have this in the body: foreach ($DOM->entry as $item ) { $image = (string) $item->image; $title = (string) $item->title; echo "<a href=''>$title</a>"; echo '<img src="$image" alt="$title" width="304" height="228">'; } but it only displays the title of the image it does not display the atual thumbnail itself -

There is a bit more work to do and it's probably not that straight forward to understand, I left you an answer. -

1 Respuestas

After looking into the feed of your question, it shows that each item does no tener un imagen 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 uña del pulgar but the HTML text dentro el contenido 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>

Enfocar:

<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 dentro 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 y 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.

Ejemplo de uso:

$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.

Ultima vez I extended SimpleXMLElement on Stackoverflow was to show how to parse CSV data inside the underlying XML structure in PHP simplexml xpath busca valor en un ELEMENTO que contiene texto delimitado por tabulaciones?.

contestado el 23 de mayo de 17 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.