2009-08-17 56 views
2

我可以使用PHP解析RSS - 我在尋找的是隻能獲取更新的內容,如果沒有新的RSS更新,什麼都不做。例如,我有這RSS File,如果沒有新的內容,沒有任何反應,但如果有新內容,我想給我的用戶發送最新的RSS更新,而不是重新發送他們已有的內容。我只解析併發送標題和鏈接。XML數據更新時只能讀取

我使用cronjob檢查每小時更新。我的問題是,我怎麼能告訴飼料現在已經更新,而不是最後一次?這裏是我用來閱讀RSS的PHP file。我是否將最後的內容寫入文件並進行比較,或者是否有其他方式來確定內容現在與上次不同?

更新:我不得不復活這篇文章,因爲我仍然試圖讓它工作。雖然我接受了一些答案,但它們很難實現,例如哈希選項最初看起來是個好主意,但是由於會檢查數以千計的RSS,所以幾乎不可能將它們全部哈希。

再次,有人建議HTTP緩存 - 我找不到一個簡單的演示,所以我實際上卡住了。

任何進一步的建議將不勝感激。

+0

您是否正在從Feed中獲取信息並將其發送給用戶或只是轉發Feed本身?如果是後者,讓用戶決定何時重新閱讀Feed。否則就沒有意義了。 – mcandre 2009-08-17 17:14:20

+0

我只將標題和鏈接發送給用戶。所以,我不想再次發送相同的標題。我想要的是如果沒有新的內容,什麼都不做,但是如果有新的更新,解析它併發送更新。 – 2009-08-17 17:20:23

回答

5

您可以使用哈希爲此,有兩種方式:

  1. 爲了緩解更新 - 當請求更新,你湊整飼料和結果與上一次的哈希比較 - 如果他們相同,您知道該Feed沒有改變,甚至可以在解析之前停止。
  2. 識別更改 - 在解析時,您散列每個項目並將其與先前運行存儲的散列進行比較。如果它匹配,你知道你以前見過它。

如果有問題的訂閱源爲其項目提供指導,則可以通過存儲指導<>散列對來優化此過程。這會使比較更快,因爲您只會將項目與已知的先前版本進行比較,而不是與以前的所有項目進行比較。

你仍然需要一些到期/清除機制來保持存儲的散列數量在界限內,但是鑑於你只存儲相對短的字符串(取決於所選擇的散列算法),你應該能夠保持相當在獲得性能問題之前積壓。

+0

它實際上不會使用散列,但比較字節數據包......(對於哈希,您正在讀取整個兩個文件,不管是什麼,並且激活散列算法 - 讀取整個文件肯定會花費更多閱讀儘可能多,並且has算法肯定不僅僅是比較字節)。 – Letterman 2009-10-19 12:35:55

+0

@ Itay:當然,哈希會對其產生影響,但這裏的重點是存儲以前的條目並與之相比較。要進行字節比較,您必須將整個訂閱源和整個訂閱源項目存儲在數據庫中,這取決於訂閱源,可能是相當數量的數據。編寫和閱讀這些內容也需要時間,但是特別要減少一個人可以保留的給定數量的存儲空間的過去條目的數量。 – 2009-10-19 12:49:01

+0

@Itay - 你可以散列舊內容一次,所以你只需要散列新內容。如果內容很多,您不必重新閱讀舊內容,只能閱讀舊雜誌。 – orip 2009-10-19 18:04:38

0

您的客戶將一直在詢問您的供稿數據,因此您在時不能控制。我不認爲大多數提要讀者服從HTTP緩存控制/過期頭,所以你不能依靠使用HTTP規範和利用HTTP緩存。

我認爲你最好的選擇就是緩存你的最後一個響應,併發送所有後續的緩存請求 - 在進行更改時適當地更新緩存。實際上,這意味着如果您只是將其從memcache或文件系統中提取出來,那麼對每個客戶端及其陳舊數據做出響應的成本幾乎接近0。

+0

感謝科迪的評論 - 但我們的系統是爲了在有更新時向客戶端發送信息。事實上,這是一個短信系統,應該只發送最新信息,而不是重複最後的信息 – 2009-08-17 17:43:49

+0

@Cody支持HTTP條件GET始終是一個好主意。你是否有任何參考來支持你的說法,它不受客戶的尊重? – 2009-10-19 09:19:14

1

由於rss的多樣性,您提出的問題並沒有簡單的解決方案。 主要問題是如何確定rss項目的唯一性。它可以是guid,發佈時間或內容本身,但是自動檢測它可能會很棘手。

一旦你知道唯一性標準,你可以堅持所有'舊'項目,並將它們與您收到的最新項目進行比較。

HTTP緩存控制和過期頭可以用作支持該網站的優化,但不幸的是有些不支持。

+0

感謝Genndy,你的迴應給了我一個主意。我現在將標題寫在一個文件中,並在cronjob運行時將它們與新內容進行比較。如果他們沒有出現在舊名單中,我會發送它。 這意味着我將不得不每週清除整個列表以阻止它在服務器上失去控制。至少,這是我現在唯一的選擇。 – 2009-08-17 18:10:52

+0

只有當您確定商品標題是唯一的時,此功能纔有效。一般來說,如果情況並非如此,您可以輕鬆找到供稿。 – 2009-08-18 11:54:31

+0

GUID/UUID將是比較好的候選對象,它意味着全球性(概率上)是獨一無二的。 – 2009-10-19 09:21:55

1

@ Henrik的解決方案是正確的,但它可能是最容易與散列數據的例子爲您提供:

// hash the three channel variables 
$hash = sha1($channel_title . $channel_link . $channel_desc); 

// here you should check the currently stored database hashed 
// value against current hash value to see if any channel variables 
// have recently changed 
if ($database_hash != $hash) { 
    // you need to update the channel data in your database 
    // including the new hash value 
} 

for ($i = 0; $i < 3; $i++) { 

    // hash the item values 
    $hash = $item_title . $item_link . $item_description 

    // here you should check the currently stored database hashed 
    // value against all item hash values to see if any item variables 
    // have recently changed 
    if ($database_hash != $hash) { 
     // you need to update the item data in your database 
     // including the new hash value 
    } 

} 

另外,如果你想要做一個快速檢查,以確定是否在任何數據XML文件發生了任何變化,您可以將XML作爲字符串散列。您應該存儲此值,並在每次運行cronjob時檢查它是否已更改(指示XML文件中的某些數據已更改)。

$overall_hash = sha1($xmlDoc->saveXML());