PHP/Tutorials/Einen RSS-Feed auslesen

Aus SELFHTML-Wiki
< PHP‎ | Tutorials
Wechseln zu: Navigation, Suche

RSS- und Atom-Feeds sind eine weit verbreitete Möglichkeit, Neuigkeiten wie Nachrichten oder neue Blogeinträge oder Podcast-Folgen in einem wohldefinierten Format bereitzustellen. Damit lassen sich Webseiten über sogenannte Feedreader abonnieren, Nutzer über neue Einträge benachrichtigen oder andere kreative Verwendungszwecken zuführen.

In diesem Tutorial geht es darum, zu zeigen, wie die Daten aus einem RSS-Feed mit PHP ausgelesen und für den Anwendungszweck passend aufbereitet werden können. Als Anwendungsbeispiel könnte man beispielsweise seine Webseite mit seinem Blog verbinden wollen, um auf dieser auf die 5 neuesten Blogposts zu verweisen. Des Weiteren könnte man auch Nachrichten von Nachrichtenseiten anzeigen, die für einen Besucher relevant sind. Hier gilt es allerdings, sicherzustellen, dass die betreffenden Anbieter dies auch erlauben.

Vorbereitung: Feed-URL herausfinden

Viele Websites benutzen vorgefertigte Standard-Software, die meist bereits einen Feed enthält, ohne dass der Betreiber diese Funktion explizit aktivieren oder gar in die Software einbauen müsste. Bei auf WordPress aufbauenden Blogs lautet diese meist https://blog.example.org/feed/. Außerdem verlinken Websites den Link häufig in Seitenleisten oder im Footer. Außerdem gibt es die häufig genutzte Möglichkeit, die Feed-URL im Head-Bereich eines HTML-Dokuments anzugeben:

Beispiel
<link rel="alternate" type="application/rss+xml" title="SELFHTML-Blog &raquo; Feed" href="https://blog.selfhtml.org/feed/" />

Im Folgenden wird https://blog.selfhtml.org/feed/ als Beispiel-Feed benutzt. Hinter dieser URL verbirgt sich folgendes XML-Dokument (gekürzt):

Beispiel
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SELFHTML-Blog</title>
	<atom:link href="https://blog.selfhtml.org/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.selfhtml.org</link>
	<description></description>
	<lastBuildDate>Sun, 01 Mar 2020 12:05:34 +0000</lastBuildDate>
	<language>de-DE</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.2.5</generator>
	<item>
		<title>SVG 2 (2020)</title>
		<link>https://blog.selfhtml.org/2020/02/27/svg-2-2020/</link>
				<comments>https://blog.selfhtml.org/2020/02/27/svg-2-2020/#respond</comments>
				<pubDate>Thu, 27 Feb 2020 11:57:13 +0000</pubDate>
		<dc:creator><![CDATA[Matthias Scharwies]]></dc:creator>
				<category><![CDATA[SVG]]></category>

		<guid isPermaLink="false">https://blog.selfhtml.org/?p=1871</guid>
				<description><![CDATA[Denn das SVG-Format ist vermutlich die spannendste Entwicklung im Bereich Grafik, die derzeit überhaupt stattfindet, und es eignet sich wie kaum ein anderes für etliche statische und dynamische Grafiksorten im Web. Stefan Münz 27.10.2001 Seit über 20 Jahren wurde SVG &#8230; <a href="https://blog.selfhtml.org/2020/02/27/svg-2-2020/">Weiterlesen &#8594;</a>]]></description>
								<content:encoded><![CDATA[<blockquote><p>Denn das SVG-Format ist vermutlich die spannendste Entwicklung im Bereich Grafik, die derzeit überhaupt stattfindet, und es eignet sich wie kaum ein anderes für etliche statische und dynamische Grafiksorten im Web. <cite><a href="https://web.archive.org/web/20020313170247/http://de.selfhtml.org/grafik/formate.htm#svg">Stefan Münz 27.10.2001</a></cite></p></blockquote>
<p><!-- […] --></p>
]]></content:encoded>
		<wfw:commentRss>https://blog.selfhtml.org/2020/02/27/svg-2-2020/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	</item>
	<item>
		<title>Surfen mit dem neuen Edge Chromium</title>
		<link>https://blog.selfhtml.org/2020/01/15/surfen-mit-dem-neuen-edge-chromium/</link>
		<!-- […] -->
	</item>
	</channel>
</rss>

Am Root-Element rss lässt sich erkennen, dass es sich um einen RSS-Feed der Version 2.0 handelt. Anschließend folgen innerhalb des channel-Elements Meta-Angaben zum Feed und der bereitstellenden Website und zuletzt jeweils in einem item-Element verpackt die Daten zu den einzelnen Beiträgen.

Das Skript

Beispiel
<?php
// Feed-URL des RSS-Feeds
$feed_url = 'https://blog.selfhtml.org/feed/';

// In welcher Datei soll der Cache abgelegt werden?
$feedcache_path = __DIR__.'/feed_cache.html';

// Wie alt in Sekunden darf der Cache sein? (1800 s entsprechen einer halben Stunde)
$feedcache_max_age = 1800;

// Wie viele Einträge sollen angezeigt werden?
$max_entries = 5;

if(!file_exists($feedcache_path) or filemtime($feedcache_path) < (time() - $feedcache_max_age)) {
  $xml = simplexml_load_string(file_get_contents($feed_url));
  $output = '<p>Die '.(int)$max_entries.' neusten Einträge aus dem <a href="'.htmlspecialchars($xml->channel->link).'">'.htmlspecialchars($xml->channel->title).'</a></p>'.PHP_EOL;
  $entries = $xml->channel->item;
  $counter = 0;
  $output .= '<ul>';
  
  foreach($entries as $root) {
    $counter++;
    // Ausgabe nach x Einträgen beenden:
    if($counter > $max_entries) {
      break;
    }
    $date = date('d.m.Y', strtotime($root->pubDate));
    // Anreißertext:
    //$description = strip_tags($root->description);
    $output .= '<li><a href="'.htmlspecialchars($root->link).'" title="'.htmlspecialchars($date).'">'.htmlspecialchars($root->title).'</a></li>'.PHP_EOL;
  }
  $output .= '</ul>';
  echo $output;
  file_put_contents($feedcache_path, $output);
} else {
  echo file_get_contents($feedcache_path);
}
?>

Das Skript beginnt mit einem Konfigurationsteil, in dem die Feed-URL, der Speicherort des Caches und einer Angabe, wie viele Einträge maximal angezeigt werden sollen, festgelegt werden. Anschließend wird abgefragt, ob die Cache-Datei fehlt oder ob sie bereits älter ist. Ist dies nicht der Fall, wird im else-Zweig aus dem Cache gelesen. Im anderen Fall wird der Feed abgerufen und SimpleXML, einer Bibliothek zur Verarbeitung von XML-Dokumenten, übergeben. Anschließend werden allgemeine Informationen aus dem Feed zur betreffenden Seite ausgelesen und für die spätere Ausgabe in der Variable $output abgelegt. Anschließend werden so lange die einzelnen Einträge im Feed zu einer HTML-Liste hinzugefügt, bis entweder alle Einträge erfasst wurden oder die definierte maximale Anzahl an Einträgen erreicht ist. Dann wird der Inhalt von $output ausgegeben und im Cache abgelegt.

Die Cache-Datei dient dazu, um nicht bei jedem Aufruf der Seite den Feed erneut abrufen zu müssen, dies spart Datenverkehr und verringert die durchschnittliche Laufzeit des Skripts, da nicht bei jedem Aufruf der Feed abgerufen werden muss.

Fehlerbehebung

  • Sie haben das Skript geändert, aber die Ausgabe ändert sich nicht? Löschen Sie die Cache-Datei, dann wird die Ausgabe neu generiert ;-)
  • Es kann sein, dass Sie auf Atom- statt RSS-Feeds treffen. Diese basieren auch auf XML, haben aber eine andere Struktur als RSS-Feeds, in diesem Fall müssten Sie das obige Skript anpassen.

Weblinks

  • php.net: SimpleXML
  • SimplePie Feed-Parser-Bibliothek, vereinfacht bei verschiedenen Feedquellen ggf. die Handhabung.