开发者

How to use array_unique correctly to echo only one time the same posts

开发者 https://www.devze.com 2023-03-19 10:08 出处:网络
I am trying to display the posts of some RSS Feeds and I came up with a question/problem I have, when I have two same feeds I am trying to show not all the posts but the unique. What I was using is th

I am trying to display the posts of some RSS Feeds and I came up with a question/problem I have, when I have two same feeds I am trying to show not all the posts but the unique. What I was using is this, that shows me all the posts twice (this is logical)

 <?php

$feeds = array(
'feed.xml', 'feed.xml'
);


// Get all feed entries
$entries = array();
foreach ($feeds as $feed) {

    $xml = simplexml_load_file($feed);
    $entries = array_merge($entries, $xml->xpath('/rss/channel//item'));

}


// Sort feed entries by pubDate (ascending)
usort($entries, 'mysort');


function mysort($x, $y) {
    return strtotime($y->pubDate) - strtotime($x->pubDate);
}


foreach 开发者_如何学Python($entries as $entry) {
echo $entry->title; 
echo "<br>";
} 

?>

but when I changed that line to

$entries = array_unique(array_merge($entries, $xml->xpath('/rss/channel//item')));

I get only one post shown.

How can I correctly show the posts only once? Thank you.


Update:

function mysort($x, $y) {
    return strtotime($y->pubDate) - strtotime($x->pubDate);
}

$feeds = array( 'http://feeds.bbci.co.uk/news/world/rss.xml',
                'http://feeds.bbci.co.uk/news/world/rss.xml'
              );

// Get all feed entries
$entries = array();
foreach ($feeds as $feed) {
    $xml = simplexml_load_file($feed);
    $entries = array_merge($entries, $xml->xpath('/rss/channel//item'));
}

$uniqueEntries = array();
foreach ($entries as $entry) {
    $uniqueEntries[(string)$entry->title] = $entry;
}

// Sort feed entries by pubDate (ascending)
usort($entries, 'mysort');

foreach ($uniqueEntries as $entry) {
    echo $entry->title; 
    echo "<br>";
} 


From the documentation of array_unique

Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same. The first element will be used.

In this case, the objects you're getting out of the XPath query translate to string form like "SimpleXML object" (not exactly like that, but the exact representation is not important). According to the above rules, then, every element looks exactly the same to array_unique.

Unfortunately, there's no way to make array_unique behave the way you want, so you will need to fake it yourself:

$feeds = array(
'myfeed.xml', 'myfeed.xml'
);


// Get all feed entries
$entries = array();
foreach ($feeds as $feed) {

    $xml = simplexml_load_file($feed);
    $tmp = $xml->xpath('/rss/channel//item');

    foreach ($tmp as $item) {
        if(!in_array($tmp, $entries)) {
            $entries[] = $tmp;
        }
    }

}

I'm not sure if this will work, as it depends on being able to compare objects, and also I don't know that identical nodes from separate XML documents would compare the same anyway. But try it, and let me know. I can whip something else up if this doesn't work.

0

精彩评论

暂无评论...
验证码 换一张
取 消