tout d'abord je tiens à remercier stealth35 pour son coup de main, lui qui connait par cœur toutes les classes de la SPL
NewsFeedReader qui lit purement et simplement les fils de news RSS/ATOM, et vous envoi l'ensemble des news sous forme de tableau PHP et d'objet. Elle nécessite CURL et SimpleXml, donc à priori, PHP > 5
Fonctionnement global de la classe :
- Récupération du flux avec CURL,
- Lecture avec SimpleXML,
- Détermination automatique de la nature du flux ( RSS ou ATOM )
- On renvoi l'ensemble des news sous forme de tableau et d'objet ( grâce à ArrayObject )
Fonctions disponible pour toi, ami développeur :
- Constructeur : possibilité de lui passé un unique argument : l'url du flux.
- méthode parse() : Retourne les news.
- getType() : qui retourne le type de flux
- getUrl & setUrl($url) : getter et setter pour l'url du flux
Le fichier de la classe :
MAJ 06/10/2010 14h00: remplacement du regex de test d'url par un filter_var
MAJ 06/10/2010 14h30: mise en place du de la constante qui permet de checker le http://
MAJ 06/10/2010 15h20: retourne les résultats sous la forme de tableau ET d'objet ( au lieu de ou )
MAJ 06/10/2010 15h30: suppression de cUrl; tout le chargement se fait avec SimpleXMLIterator + define() remplacé par des const
MAJ 06/10/2010 16h15: centralisation des fonction de parsing RSS et ATOM, elles étaient identique à un détail près
MAJ 06/10/2010 17h15: ajout d'un getter pour qui retourne le type de flux
MAJ 07/10/2010 13h15: Remplacement du tableau de retour par un ArrayIterator
class NewsFeedReader
{
protected $url=null;
protected $xml_doc=null;
const FEED_TYPE_NO = 0;
const FEED_TYPE_RSS = 1;
const FEED_TYPE_ATOM = 2;
protected $feed_type=self::FEED_TYPE_NO;
function __construct($url=null)
{
if($url!=null)
$this->setUrl($url);
}
private function fetchFeed()
{
if($this->getUrl() == null)
throw new Exception('Aucune URL.');
$this->xml_doc = new SimpleXMLIterator($this->url, LIBXML_NOCDATA, true);
if(isset($this->xml_doc->channel))
$this->feed_type=self::FEED_TYPE_RSS;
elseif(isset($this->xml_doc->entry))
$this->feed_type=self::FEED_TYPE_ATOM;
else
$this->feed_type=self::FEED_TYPE_NO;
}
public function parse()
{
if($this->xml_doc==null)
$this->fetchFeed();
switch($this->feed_type)
{
case self::FEED_TYPE_RSS:
case self::FEED_TYPE_ATOM:
return $this->parseRSSATOM();
break;
default:
throw new Exception('Rien à parser');
}
}
/* PARSERS */
protected function parseRSSATOM()
{
$retour = new ArrayIterator();
$newsList=null;
if($this->feed_type==self::FEED_TYPE_RSS)
$newsList=$this->xml_doc->channel->item;
elseif($this->feed_type==self::FEED_TYPE_ATOM)
$newsList=$this->xml_doc->entry;
foreach($newsList as $item)
{
$retour->append(new ArrayObject((array) $item, ArrayObject::ARRAY_AS_PROPS));
}
return $retour;
}
/* GETTER / SETTER */
public function setUrl($url)
{
if(filter_var($url, FILTER_VALIDATE_URL,FILTER_FLAG_SCHEME_REQUIRED)===$url)
{
$this->url=$url;
return true;
}
throw new Exception('URL invalide');
}
public function getUrl()
{
return ((strlen($this->url)>0)?$this->url:null);
}
public function getType()
{
return $this->feed_type;
}
}
?>
Exemple d'utilisation<?php
require("NewsFeedReader.class.php");
if(!isset($_GET['atom']))
$rss = new NewsFeedReader("http://feeds.feedburner.com/Ao6-labs?format=xml");
else
$rss = new NewsFeedReader("http://www.atomenabled.org/atom.xml");
$news = $rss->parse();
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Exemple</title>
</head>
<body>
<div>
<?php
foreach($news as $actu)
{
//print_r($actu);
echo '<h1><a href='.$actu->link.'>'.$actu->title.'</a></h1>';
if( $rss->getType() == NewsFeedReader::FEED_TYPE_RSS)
echo '<p>'.$actu->description.'</p>';
elseif($rss->getType() == NewsFeedReader::FEED_TYPE_ATOM)
echo '<p>'.$actu->content.'</p>';
}
?>
</div>
</body>
</html>
J'ai très peu souvent à développer des classes génériques à utilisation multiple, je bosse surtout sur des points spécifique en général, alors n'hésitez pas à me donner votre avis et à me conseiller !Bisous