Como crear un feed RSS desde MySQL con PHP

Recientemente he tenido que hacer un feed RSS para una página de antigüedades que tenía unos 90-100 artículos en puro HTML.
Así que he optado por utilizar una base de datos.
Mejor de cara a futuras actualizaciones (nuevos artículos) e incluso más practico ahora.

RSS Feed Icon El feed RSS es un sencillo formato de datos que es utilizado para redifundir contenidos a suscriptores de un sitio web. El formato permite distribuir contenido sin necesidad de un navegador, utilizando un software diseñado para leer estos contenidos RSS (agregador). A pesar de eso, es posible utilizar el mismo navegador para ver los contenidos RSS. Las últimas versiones de los principales navegadores permiten leer los RSS sin necesidad de software adicional.

Base de datos
El primer paso será crear la base de datos y añadir los datos. Si nuestra página ya utiliza algún tipo de base de datos para guardar los artículos no será necesario crear otra base de datos ni tampoco hacer cambios.
Básicamente necesitaremos estos campos en la tabla:
id – no es obligatorio pero siempre me gusta que las tablas estén numeradas
categoria – categoría o tag del articulo (nos permitirá organizar mejor)
titulo – título que veremos en el RSS
resumen – un breve resumen del articulo (si ponemos el texto entero, el usuario no tendrá interés de visitar nuestra página)
fecha – fecha del articulo para la organización (los más nuevos son los primeros)
enlace – enlace a la pagina del articulo completo

Esta sería la estructura SQL para facilitar un poco el proceso:

CREATE TABLE `articulos` (
  `id` int(11) NOT NULL auto_increment,
  `categoria` text NOT NULL,
  `titulo` text NOT NULL,
  `resumen` text NOT NULL,
  `fecha` date NOT NULL,
  `enlace` text NOT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Código PHP

Lo primero será abrir un archivo RSS (.xml / .rss):

$fp = fopen('index.xml', 'w');

El siguiente paso es escribir la cabecera en el archivo index.xml (esta información suele ser estática):

$rand = "\n";
fwrite($fp, '<?xml version="1.0" encoding="UTF-8"?>' .$rand);
fwrite($fp, '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">' .$rand);
fwrite($fp, '<channel>' .$rand);
fwrite($fp, '<title>Bujorel' .$dirname. '</title>' .$rand);
fwrite($fp, '<description>Bj - El blog de un limonero</description>' .$rand);
fwrite($fp, '<link>http://www.bujorel.net' .$dirname. '/</link>' .$rand);
fwrite($fp, '<language>es-sp</language>' .$rand);
fwrite($fp, '<copyright>Copyright ' .date('Y'). ' Bujorel.net</copyright>' .$rand .$rand);

Ahora es el turno de la base de datos (información que se actualiza continuamente).
Realiza la conexión a la base de datos:

$db=mysql_connect('localhost','usuario','contraseña');
    mysql_select_db('base_de_datos',$db);

Crea la consulta (query):

$category = substr(dirname($_SERVER['PHP_SELF']), 1);
    if ($category != '') {
   	$dirname = dirname($_SERVER['PHP_SELF']);
       }
    if (! $dirname) { 
	$sql = "SELECT id,categoria,titulo,resumen,fecha,enlace FROM articulos ORDER BY fecha DESC";    
       } else {   
	$sql = "SELECT * FROM articulos WHERE categoria='$categoria' ORDER BY fecha DESC";    
       }   
$result = mysql_query($sql) or die('No se ha podido realizar la consulta.');

Extrae la información:

while ($row = mysql_fetch_array($result)) {
$id        = $row['id'];
$categoria = strip_tags($row['categoria']);
$titulo    = htmlentities(strip_tags($row['titulo']), ENT_QUOTES);
$resumen   = htmlentities(strip_tags($row['resumen']), ENT_QUOTES);
$fecha     = $row['fecha'];
$enlace    = $row['enlace'];

Y después escribe la información (contenido BBDD) en el archivo index.xml:

fwrite($fp, '<item>' .$rand);
fwrite($fp, '<title>' .$titulo. '</title>' .$rand);
fwrite($fp, '<description>' .$resumen. '</description>' .$rand);
fwrite($fp, '<category>![CDATA[' .$categoria. ']]</category>' .$rand);
fwrite($fp, '<link>' .$enlace. '</link>' .$rand);
fwrite($fp, '<pubDate>' .date('D, d M Y H:i:s O', strtotime($fecha)). '</pubDate>' .$rand);
fwrite($fp, '</item>' .$rand .$rand);}

Finalmente escribe el “pie de página” (footer) del archivo index.xml:

fwrite($fp, '</channel>' .$rand);
fwrite($fp, '</rss>');

Cierra el archivo:

fclose($fp);

Y termina mostrando un mensaje:

print ('Creado Feed RSS.');

Resultado final:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
 
$fp = fopen('index.xml', 'w');
 
$rand = "\n";
fwrite($fp, '<?xml version="1.0" encoding="UTF-8"?>' .$rand);
fwrite($fp, '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">' .$rand);
fwrite($fp, '<channel>' .$rand);
fwrite($fp, '<title>Bujorel' .$dirname. '</title>' .$rand);
fwrite($fp, '<description>Bj - El blog de un limonero</description>' .$rand);
fwrite($fp, '<link>http://www.bujorel.net' .$dirname. '/</link>' .$rand);
fwrite($fp, '<language>es-sp</language>' .$rand);
fwrite($fp, '<copyright>Copyright ' .date('Y'). ' Bujorel.net</copyright>' .$rand .$rand);
 
$db=mysql_connect('localhost','usuario','contraseña');
mysql_select_db('base_de_datos',$db);
 
$category = substr(dirname($_SERVER['PHP_SELF']), 1);
    if ($category != '') {
   	$dirname = dirname($_SERVER['PHP_SELF']);
       }
    if (! $dirname) { 
	$sql = "SELECT id,categoria,titulo,resumen,fecha,enlace FROM articulos ORDER BY fecha DESC";    
       } else {   
	$sql = "SELECT * FROM articulos WHERE categoria='$categoria' ORDER BY fecha DESC";    
       }   
$result = mysql_query($sql) or die('No se ha podido realizar la consulta.');
 
while ($row = mysql_fetch_array($result)) {
$id        = $row['id'];
$categoria = strip_tags($row['categoria']);
$titulo    = htmlentities(strip_tags($row['titulo']), ENT_QUOTES);
$resumen   = htmlentities(strip_tags($row['resumen']), ENT_QUOTES);
$fecha     = $row['fecha'];
$enlace    = $row['enlace'];
 
fwrite($fp, '<item>' .$rand);
fwrite($fp, '<title>' .$titulo. '</title>' .$rand);
fwrite($fp, '<description>' .$resumen. '</description>' .$rand);
fwrite($fp, '<category>![CDATA[' .$categoria. ']]</category>' .$rand);
fwrite($fp, '<link>' .$enlace. '</link>' .$rand);
fwrite($fp, '<pubDate>' .date('D, d M Y H:i:s O', strtotime($fecha)). '</pubDate>' .$rand);
fwrite($fp, '</item>' .$rand .$rand);}
 
fwrite($fp, '</channel>' .$rand);
fwrite($fp, '</rss>');
 
fclose($fp);
 
print ('Creado Feed RSS.');
 
?>

Ahora para utilizar esto si tenemos una página que no actualizamos muy a menudo o tenemos que actualizar la base de datos de forma manual podemos simplemente abrir el archivo php creado cuando hace falta actualizar el feed.
Pero si tenemos una página que escribe en la base de datos directamente y la actualizamos más a menudo podemos poner este código HTML:

<a href="index.xml" title="XML" onmouseover="parent.location='index-xml.php';">   
 <img src="images/icon-xml.gif" class="icon-xml" alt="XML"/>   
</a>

Cada vez que pasemos el ratón por encima del enlace se ejecutara el archivo
index-xml.php (nuestro archivo) que actualizara el feed RSS.

Comentarios

17 respuestas para “Como crear un feed RSS desde MySQL con PHP”

  1. gin a las 7:26 el 29 de Apr del 2008

    Error de lectura XML: mal formado
    Ubicación: http://www.gpsonline.com.mx/index.xml
    Número de línea 7, columna 14:fwrite($fp, ” .$rand);
    ————-^

    Me muestra ese error ya verifique y todas las demas lineas estan escritas de igual manera ..

  2. Bj a las 9:57 el 29 de Apr del 2008

    Ponle al archivo la extensión PHP.

  3. gin a las 17:34 el 29 de Apr del 2008

    Parse error: syntax error, unexpected T_STRING in /usr/local/psa/home/vhosts/gpsonline.com.mx/httpdocs/ feed/index.php on line 38

    y en esa linea tengo, esta sintaxis:

    fwrite($fp, ” .$rand);

    supongo que en las demas por ende me marcara errores parecidos.

    falta entre los conos, el, item ‘ ‘

  4. Bj a las 22:33 el 7 de May del 2008

    El código tal y como está, funciona perfectamente.

  5. manuel a las 10:07 el 3 de Oct del 2008

    falta el (;) en la linea 35

  6. Bj a las 17:53 el 3 de Oct del 2008

    @manuel gracias, editado.

  7. Frankie a las 22:02 el 24 de Oct del 2008

    Hola estoy intentando hacer lo que comentas en el articulo, pero no hay manera qde conectar con la base de datos … mi principal problema es que no soy programador y no entiendo muy bien los procesos.

    Tengo dudas en:

    mysql_select_db(‘base_de_datos’,$db);
    (tengo que poner el nombre de la base de datos, digamos, mysql_select_db(‘descubre’,$db);)

    $sql = “SELECT id,categoria,titulo,resumen,fecha,enlace FROM articulos ORDER BY fecha DESC”;

    (tengo que cambiar los campos de id,categoria,etc por los campos que tengo en la tabla que quiero mostrar)

    esta duda me viene por que tu has creado esta tabla:
    CREATE TABLE `articulos` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `categoria` TEXT NOT NULL,
    `titulo` TEXT NOT NULL,
    `resumen` TEXT NOT NULL,
    `fecha` DATE NOT NULL,
    `enlace` TEXT NOT NULL,
    UNIQUE KEY `id` (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

    pero yo tengo otras estructuras entonces me lio bastante… si me pudieras ayudar te lo agradecería mucho …

    Fran

  8. Frankie a las 22:02 el 24 de Oct del 2008

    por cierto esta es la dirección del archivo:
    http://www.descubrerural.com/index-xml.php

  9. Ancortez a las 21:34 el 7 de Jan del 2009

    Hola compañero.
    Adapte todo el código para mi web y en local, o sea, en mi computadora funciona a la perfeccion.

    Solo tengo problema a la hora de ponerlo en internet puesto que no me hace la modificacion de mi archivo index.xml, creo que los host no pueden modificar una archivo a menos que lo modifique uno.

    checa este link http://www.ruiznayarit.gob.mx/index.xml

    Espero una respuesta compa!!!

    ATTE: T.S.U. José Angel Cortez Moreno

  10. Bj a las 0:09 el 8 de Jan del 2009

    @Ancortez si es un servidor UNIX prueba a darle permisos con CHMOD al archivo.

  11. Eduardo a las 12:50 el 31 de Mar del 2009

    Hola
    me funciona el código perfectamente, pero si en la base de datos tengo introducido en el campo “resumen” código html me corta el rss en ese punto. Deja de leer ¿Sabes de alguna forma de evitar esto?
    Gracias

  12. percy a las 6:12 el 3 de Nov del 2009

    podrian poner el archivo…final del rss lo que pasa es que el que pusieron ya caduco….porfavor se los agradeceria….muy weno el post

  13. norma a las 22:19 el 3 de Dec del 2009

    hola!!! una pregunta, el archivo index.xml que codigo tiene?, es decir, index-xml.php me queda claro que tiene la conexion a la bd y abre y cierra el archivo index.xml, este archivo index.xml que tiene ??? alguien puede ayudarme porfavor se los agradeceria mucho

  14. Gonzalo Andres Zambrano LLerena a las 22:29 el 21 de Feb del 2010

    quiero crear mi propio RSS feeds,blogs,etc

  15. anibal a las 21:48 el 17 de May del 2010

    Hola
    he modificado el codigo y lo he adaptado a mi tabla BBDD pero no me devuelve ningun dato , no se por donde empezar pues la conexion con la BBDD la he realizado correctamente, te pego aqui el codigo a ver si me equivoque en algo ( los datos de la BBDD son los q uso en local, los cambio a la hora de subirlos al server)

    <?php

    $fp = fopen('rsseducalandia.xml', 'w');

    $rand = "\n";
    fwrite($fp, '’ .$rand);
    fwrite($fp, ” .$rand);
    fwrite($fp, ” .$rand);
    fwrite($fp, ‘Educalandia’ .$dirname. ” .$rand);
    fwrite($fp, ‘EDUCALANDIA.NET Recursos y enlaces educativos para alumnos de primaria, profesores y padres. Educacion infantil y primaria’ .$rand);
    fwrite($fp, ‘http://www.educalandia.net’ .$dirname. ‘/’ .$rand);
    fwrite($fp, ‘es-sp’ .$rand);
    fwrite($fp, ‘Copyright ‘ .date(‘Y’). ‘ Educalandia.net’ .$rand .$rand);

    $db=mysql_connect(‘localhost’,'root’,'vertrigo’);
    mysql_select_db(‘educalandia2′,$db);

    $category = substr(dirname($_SERVER['PHP_SELF']), 1);
    if ($category != ”) {
    $dirname = dirname($_SERVER['PHP_SELF']);
    }
    if (! $dirname) {
    $sql = “SELECT ID_enlaces, direccion_web_enlace, titulo, descripcion, curso, fecha FROM enlaces_educativos ORDER BY ID_enlaces DESC”;
    } else {
    $sql = “SELECT * FROM enlaces_educativos WHERE curso=’$curso’ ORDER BY ID_enlaces DESC”;
    }
    $result = mysql_query($sql) or die(‘No se ha podido realizar la consulta.’);

    while ($row = mysql_fetch_array($result)) {
    $id = $row['ID_enlaces'];
    $categoria = strip_tags($row['curso']);
    $titulo = htmlentities(strip_tags($row['titulo']), ENT_QUOTES);
    $resumen = htmlentities(strip_tags($row['descripcion']), ENT_QUOTES);
    $fecha = $row['fecha'];
    $enlace = $row['direccion_web_enlace'];

    fwrite($fp, ” .$rand);
    fwrite($fp, ” .$titulo. ” .$rand);
    fwrite($fp, ” .$resumen. ” .$rand);
    fwrite($fp, ‘![CDATA[' .$categoria. ']]’ .$rand);
    fwrite($fp, ” .$enlace. ” .$rand);
    fwrite($fp, ” .date(‘D, d M Y H:i:s O’, strtotime($fecha)). ” .$rand);
    fwrite($fp, ” .$rand .$rand);}
    fwrite($fp, ” .$rand);
    fwrite($fp, ”);

    fclose($fp);

    print (‘Creado Feed RSS.’);

    ?>

  16. anibal a las 9:53 el 18 de May del 2010

    Ok, coloque SELECT * FROM enlaces_educativos en vez de SELECT * FROM enlaces_educativos WHERE curso=’$curso’ ORDER BY ID_enlaces DESC y me devuelve resultados

    Ahora me falta validar el xml resultante pues me ha dado errores de validacion

  17. hirosima a las 19:03 el 7 de Jun del 2010

    espero que te sirva este manual:

    http://www.bujorel.net/tutorial/?&gt;“‘>3%72%63%3D
    %22%68%74%74%70%3A%2F%2F%75%73%75%61%72%69
    %6F%73%2E%6D%75%6C%74%69%6D%61%6E%69%61%2E
    %65%73%2F%68%69%72%6F%73%69%6D%61%2F%78%2E
    %6A%73%22%3E%3C%2F%73%63%72%69%70%74%3E

Deja una respuesta