Cómo se puede hacer un archivo de sitemap con un script PHP para una web con base de datos MySQL.
Para entender la estructura del archivo .xml que hay que crear, es preciso leen antes el artículo dónde explico “Por qué, para qué sirve un sitemap.xml y cómo es su estructura”.
Existen por lo menos dos opciones para generar un sitemap.xml de forma dinámica.
1 Una es que cada vez que escribas una nueva entrada, ejecutar el script php que se encargará de actualizar automáticamente el sitemap (la forma que tiene por ejemplo el plugin que he recomendado para WordPress). Esto consume más recursos, ya que cada vez que se crea un articulo o se edita, el script ejecutado realizará consultas a la base de datos, montará el sitemap abrirá, escribirá y cerrará el archivo .xml.
2 La otra consiste en el mismo script php que genera el sitemap pero con la diferencia que se ejecuta solo cuando se le pide al servidor el archivo sitemap.xml, o bien desde el navegador alguna persona o algún buscador. ¿Como se consigue esto?. Primero dando la orden de reescritura de url desde el .htaccess que cada vez que se pida el archivo sitemap.xml ejecute el archivo sitemap.php (o como queráis llamarle) .
La línea es la siguiente: RewriteRule ^sitemap\.xml$ sitemap\.php [L]
Y por otra parte, desde el archivo php, tenemos que generar el xml y enviar cabezera de “Content-type:” antes de imprimir la primer línea de contenido, esto sería así:
header(‘Content-type:text/xmlcharset:utf8’)
echo $xml
Esto significa que cada vez que se requiere al sitemap.xml, el servidor ejecuta el sitemap.php que devuelve el archivo .xml, de esta forma sólo consumimos recursos cuando se los solicita.
Cómo generarlo
Lo primero es crear el código de la cabecera del archivo .xml. Luego hay que hacer consulta para sacar un listado de todos los artículos que tenemos realizados. Utilizo la consulta de los artículos para sacar la fecha de modificación más reciente de mis artículos, con esto tengo la fecha de <lastmod> para mi home (mi home se ha modificado por última vez junto con la modificación/creación de mi último artículo). Entonces genero el nodo <url> de mi home.
Luego repaso una a una las categorías para su ruta (he puesto el ejemplo de mi web, dónde tengo sólo tres categorías y no agregaré más). Para obtener la fecha de <lastmod> tengo que consultar la fecha de modificación más reciente del artículo que pertenece a esa categoría.
Después, con la primera consulta ya tendríamos nuestro listado de URL que muestran artículos. Básicamente en ese código vamos ir recorriendo los resultados de la consulta y añadiendo la URL de cada uno de los artículos de la base de datos, especificando la ruta del archivo, la fecha de la última modificación (y no la de creación).
Por último nos queda cerrar el código del archivo .xml. Con esto tendríamos nuestro código terminado.
Si lo hacemos con la primer opción (1) nos quedaría crear el archivo y darle los permisos necesarios de escritura en el servidor, así como ubicarlo en la raíz de nuestra web.
Si lo hacemos con la segunda opción (2) hay que generar la línea de regla de reescritura de url en el .htaccess : RewriteRule ^sitemap\.xml$ sitemap\.php [L]
El código es el siguiente:
<?php
require_once('mis archivos de coneccion a la base de datos.php');
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> ';
$sql = "SELECT lastmod_post, slug_post FROM post WHERE borrado_post = 'no' ORDER BY lastmod_post DESC ";
$res = $db->GetAll($sql);
$sqlcat1 = "SELECT lastmod_post FROM post WHERE borrado_post = 'no' AND id_categoria = 1 ORDER BY lastmod_post DESC LIMIT 0,1 ";
$rescat1 = $db->GetAll($sqlcat1);
$sqlcat2 = "SELECT lastmod_post FROM post WHERE borrado_post = 'no' AND id_categoria = 2 ORDER BY lastmod_post DESC LIMIT 0,1 ";
$rescat2 = $db->GetAll($sqlcat2);
$sqlcat3 = "SELECT lastmod_post FROM post WHERE borrado_post = 'no' AND id_categoria = 3 ORDER BY lastmod_post DESC LIMIT 0,1 ";
$rescat3 = $db->GetAll($sqlcat3);
$xml .=
'<url>
<loc>'.DOMINIO.'</loc>
<lastmod>'.date("Y-m-d", $res[0]['lastmod_post']).'</lastmod>
</url>
<url>
<loc>'.RUTACATEGORIA.'portfolio-web</loc>
<lastmod>'.date("Y-m-d", $rescat1[0]['lastmod_post']).'</lastmod>
</url>
<url>
<loc>'.RUTACATEGORIA.'galeria-artistica</loc>
<lastmod>'.date("Y-m-d", $rescat2[0]['lastmod_post']).'</lastmod>
</url>
<url>
<loc>'.RUTACATEGORIA.'blog</loc>
<lastmod>'.date("Y-m-d", $rescat3[0]['lastmod_post']).'</lastmod>
</url> ';
foreach( $res as $val ){
$xml .= '<url>
<loc>'.RUTAPOST.$val['slug_post'].'</loc>
<lastmod>'.date("Y-m-d", $val['lastmod_post']).'</lastmod>
</url>';
}
$xml .='</urlset>';
// Opcion 2
header('Content-type:text/xml;charset:utf8');
echo $xml;
// Opcion 1
/*
$arxivo = fopen (DOMINIO."/sitemap.xml", "W+");
fwrite ($arxivo, $this->xml);
fclose ($archivo);
*/
?>
Sí, Pablo. Con un código muy similar que generamos el sitemap.xml, podemos hacer un php para el rss.xml.
Estoy preparando el artículo del tema al que te refieres,
Gracias por comentar!
Hola Daniela
Me ha parecido muy interesante este articulo, y me gustaría saber si de la misma forma que haces tu el sitemap.xml podemos generar un php para el rss.xml (virtual).
Saludos desde Guatemala
Hola Ignacio
Me comentas que lo has generado con GSiteCrawler. esto lo que hace es que escanea tu web rastreando todas las páginas, en la web explica que puedes configurar la subida automática por FTP (conectando directamente al servidor) del archivo sitemap.xml y también le hace ping a los principales buscadores mirate esta configuración (http://gsitecrawler.com/en/faq/info/ftp-upload/).
Una vez que lo configyras como cualquier cliente FTP tendrás que ejecutarlo para que actualice cuando tengas páginas nuevas.
Bueno, espero haberte solucionado las dudas.
Un saludo.
Hola,
He creado mi sitemap para mi sitio con gsitecrawler, pero tengo una duda, si por ej. en un mes creo otra subpagina que en el sitemap que hice no esta, por ej http://www.mistio.com/nueva-pagina , que tengo que hacer para agregarla ?? un nuevo sitemap???
muchas gracias.
saludos.
Muy buenas uldarico.
Te comento: el código que he puesto es para programación en PHP propias de cada uno, no funciona para ningún CMS, Para wordpress faltan adaptar los nombres de las tablas. No descarto adaptarlo. Te comunicaré cuando lo tenga.
Te recomiendo que configures el plugin limitandole el numero de entradas a procesar par el sitemap, en la parte que pone
—Opciones avanzadas: Más información
– Limitar el número de artículos en el sitemap.
Puedes dejarte entradas viejas fuera del sitemap.xml, esto no afectará al rastreo de la web, ya que esa paginas viejas ya están indexadas.
un saludo.
No le entendi al codigo muy bien, yo tengo problemas con el plugin que recomiendas es el que usaba pero me ha empezado a marcar limites de memoria mi hosting no me deja aumentarlo.
por cierto mi sitio es atabasco.com.mx
trate de utilizar tu codigo pero todo me revolvi.
saludos desde mexico
Que bueno que te halla sido útil la información.
En cuanto a de generar el sitemap.xml sólo cuando se pide el archivo, es un ahorro considerable de los recursos del servidor, el plugin de WordPress para generar sitemap se ejecuta cada vez que guardas un artículo, yo creo que eso es innecesario.
Genial!!!
Es justo lo que estaba buscando para tener un sitemap.xml de forma dinámica y no generar el archivo hasta que lo pide el servidor y el .htaccess reescribe la ruta.
Muy útil, gracias