ika ika - 7 months ago 9
PHP Question

How to save multiple images using 'file_get_contents' at once using xml tag - [SOLVED]

I would appreciate some help. I am trying to save images from an xml feed using 'file_get_contents'. But the problem is, that it only takes 1 image at time right now and that too when entered URL. I am looking for a code where it automatically saves images from feed, every time the feed is refreshed, but only save new images, not the ones already stored. Also, the problem is, that link is inside the 'ContentItem' tag, which isn't easy to extract

This is my XML feed code:

<xml>
<channel><title></title>
<link>http://www.yournewssite.com</link>
<description>gossip</description>
<item>
<title>title of article</title>
<link>http://yourwebsite.com/</link>
<description><![CDATA[<img src=http://yourwebsite.com/i.php?k=d88d4e2b336966b5389837832 width=100 height=100>
<BR>article content<BR>]]></description>
<ContentItem Href="http://yourwebiste.com/i.php?k=d88d4e2b336966b538983783230051c7">
<MediaType FormalName="Picture" />
<MimeType FormalName="image/jpg" />
<Property FormalName="caption" value="Nick Carter" />
</ContentItem>
</xml>


PHP Code:

<?php
$doc = new DOMDocument();
$doc->load('http://yourwebsite.com/clients/d51b83e5/index.xml');

$xpath = new DOMXpath($doc);
$nodeLists = $xpath->query ('//ContentItem[@Href]');

$arrFeeds = array();
foreach ($doc->getElementsByTagName('item') as $node) {
$itemRSS = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'ContentItem'=>$nodeLists->item(0)->getAttribute('Href'),
);
array_push($arrFeeds, $itemRSS);
}


echo file_get_contents("http://yourwebsite.com/clients/d51b83e5/index.xml");
$url = '';
$img = 'C:\xampp\htdocs\trial\images\image.jpg';
file_put_contents($img, file_get_contents($url));
?>


I would really appreciate your help with this. Thanks in advance.

Answer

Your code to retrieve <ContentItem Href> is a bit twisted, but it seems to work, for me.

You can simplify it in this way:

$nodeLists = $xpath->query ('//ContentItem[@Href]');
foreach( $nodeLists as $node )
{
    $itemRSS = array (
        'title'       => $node->parentNode->getElementsByTagName('title')->item(0)->nodeValue,
        'ContentItem' => $node->getAttribute('Href'),
    );
    /* Following syntax is equivalent to array_push() when you add only one item to array: */
    $arrFeeds[] = $itemRSS;
}

To retrieve only new images, we can help you only guessing. If image name in URL is unique, you can use it to save pictures and check for already saved files.

In your example, the link is:

http://yourwebiste.com/i.php?k=d88d4e2b336966b538983783230051c7

So, with this code:

$url = parse_url( 'http://yourwebiste.com/i.php?k=d88d4e2b336966b538983783230051c7' );
parse_str( $url['query'], $query );

In $query['k'] you have:

d88d4e2b336966b538983783230051c7

If you want use it as unique file name, you can write the code to save images in this way:

$localPath = '/Your/Path/To/Image/Directory';
foreach( $arrFeeds as $feed )
{
    $url = parse_url( $feed['ContentItem'] );
    parse_str( $url['query'], $query );
    $localName = "$localPath/{$query['k']}.jpg";
    if( file_exists( $localName ) )
    {
        echo "Already downloaded: '$localName'".PHP_EOL;
    }
    else
    {
        $data = file_get_contents( $feed['ContentItem'] );
        if( ! $data )
        {
            echo "Error downloading '{$feed['ContentItem']}'".PHP_EOL;
        }
        else
        {
            if( ! file_put_contents( $localName, $data ) )
            {
                echo "Error saving '$localName'".PHP_EOL;
            }
            else
            {
                echo "'$localName' successful saved".PHP_EOL;
            }
        }
    }
}
Comments