PHP класс генератор RSS ленты
Вариант реализации от AI ChatGPT + полезные дополнения.
В прошлой статье «RSS каналы – актуальность технологии сегодня» я описывал, что такое RSS лента, канал, фид и для чего это нужно. Сегодня разберём PHP класс, который будет генерировать структуру RSS канала на основе данных полученных из базы данных публикаций сайта.
У меня на ресурсе уже был организован RSS канал. Так как сайт самописный, то и код генератора был разработан вручную. Но захотелось обновить, улучшить и расширить функционал. Изначально в разработке кода мне помог AI ChatGPT. Сформировал вопрос, получил ответ, а после доработал под свои нужды. Вот оригинальный текст запроса:
Нужен php класс который формирует RSS ленту и записывает файл rss.xml (encoding=UTF-8). Записи публикаций находятся в базе mysql в таблице `publics` имеющей ряды `canonical` - канонический URL страницы без протокола https:// и http://, `nameRus`- имя страницы на кирилице, `titleStr` - строка для тега title, `flagRSS` - (varchar) имеет значения yes или no - включить/запретить запись в rss ленту соответственно, `textRSS` - текст през релиз статьи, `date` (формат Y-m-d H:i:s) - дата время публикации записи. Для обращения к базе использовать подготовленные выражения mysqli. Подробное описание работы.
Ответ: Вот пример класса, который формирует RSS ленту на основе данных из таблицы `publics` в базе данных MySQL и записывает ее в файл rss.xml. Для работы с базой данных используется подготовленный запрос mysqli:
class RSSGenerator { private $db; private $rss_items; public function __construct($db) { $this->db = $db; $this->rss_items = array(); } public function generateRSS() { // Получаем записи из базы данных $stmt = $this->db->prepare("SELECT canonical, nameRus, titleStr, textRSS, date FROM publics WHERE flag_RSS = 'yes' ORDER BY data_a DESC LIMIT 10"); $stmt->execute(); $result = $stmt->get_result(); // Формируем RSS ленту while ($row = $result->fetch_assoc()) { $item = array( 'title' => htmlspecialchars($row['titleStr']), 'link' => 'https://' . htmlspecialchars($row['canonical']), 'description' => htmlspecialchars($row['textRSS']), 'pubDate' => date('r', strtotime($row['date'])) ); array_push($this->rss_items, $item); } // Записываем RSS ленту в файл $rss_feed = $this->generateRSSFeed(); file_put_contents('rss.xml', $rss_feed); } private function generateRSSFeed() { $rss_feed = '<?xml version="1.0" encoding="UTF-8"?>/n'; $rss_feed .= '<rss version="2.0">/n'; $rss_feed .= '<channel>/n'; $rss_feed .= '<title>'.$this->rss_config['title'].'</title>/n'; $rss_feed .= '<link>'.$this->rss_config['link'].'/rss.xml</link>/n'; $rss_feed .= '<description>'.$this->rss_config['description'].'</description>/n'; foreach ($this->rss_items as $item) { $rss_feed .= '<item>/n'; $rss_feed .= '<title>/n'; $rss_feed .= '<link>' . $item['link'] . '</link>/n'; $rss_feed .= '<description>' . $item['description'] . '</description>/n'; $rss_feed .= '<pubDate>' . $item['pubDate'] . '</pubDate>/n'; $rss_feed .= '</item>/n'; } $rss_feed .= '</channel>/n'; $rss_feed .= '</rss>'; return $rss_feed; } }
Чтобы использовать этот класс, вам нужно создать объект и вызвать его метод generateRSS():
$db = new mysqli('hostname', 'username', 'password', 'database'); if ($db->connect_error) { die("Connection failed: " . $db->connect_error); } $rss_generator = new RSSGenerator($db); $rss_generator->generateRSS();
Это создаст файл rss.xml в текущей директории с содержимым в формате RSS.
Ответ вполне рабочий, но я дополнил класс RSSGenerator включением реальных значений тегов title, link, description шапки RSS фида. Значения берём в файле configRSS.ini. С помощью функции FileDir определяем путь к файлу с настройками, парсим файл в приватную переменную массива $rss_config для дальнейшего использования в классе. Более подробно о функции FileDir() я писал ранее.Там же берём и значения для подключении к базе данных. В файле настроек список названий и значений интуитивно понятен. Вот приблизительный макет файла configRSS.ini:
;Данные базы masql [connect] baza = "baza_name" user = "user_login" pass = "password" host = "localhost" ;RSS канал [rss] OnOffRss = "on" description = "RSS канал сайта MY-SITE" title = "RSS канал сайта MY-SITE" link = "https://my-site.ru/rss.xml" amtItem = "20"
Вот обновлённый код класса:
class RSSGenerator { private $db; private $rss_items; private $rss_config; public function __construct() { $dirhome=self::FileDir('configsite/configRSS.ini'); $inimass = parse_ini_file($dirhome['fullpath'], true); $this->db = new MySQLi($inimass['connect']['host'], $inimass['connect']['user'], $inimass['connect']['pass'], $inimass['connect']['baza']); if ($this->conn->connect_error) { die("Connection failed: " . $this->conn->connect_error); } $this->db->query("SET NAMES 'utf8'"); $this->rss_items = array(); $this->rss_config = $inimass['rss']; } public function FileDir($index = "rss.xml"){ //Парсим URL, путь от корня и обрезаем первый слеш $index = ltrim(parse_url($index, PHP_URL_PATH), '/'); $dirFile = __FILE__; $abs = ''; $infodir[]=""; $ns = substr_count($dirFile, '/'); while ($ns > 1){ $dirFile = trim(dirname($dirFile) . PHP_EOL); $filename = $dirFile."/".$index; if (file_exists($filename)){ $infodir['fulldir']=$dirFile; $infodir['fullpath']=$dirFile."/".$index; $infodir['relativepath']=$abs.$index; $infodir['pathbias']= $abs; return $infodir; }else{ $infodir['fulldir']=$dirFile; $infodir['fullpath']=0; $infodir['relativepath']= 0; $infodir['pathbias']= 0;//Путь смещения } $abs .= '../'; $ns--; } return $infodir; } public function generateRSS() { // Получаем записи из базы данных $stmt = $this->db->prepare("SELECT canonical, nameRus, titleStr, textRSS, date FROM public WHERE flag_RSS = 'yes' ORDER BY data_a DESC LIMIT ".$this->rss_config['amtItem']); $stmt->execute(); $result = $stmt->get_result(); // Формируем RSS ленту while ($row = $result->fetch_assoc()) { $item = array( 'title' => htmlspecialchars($row['titleStr']), 'link' => 'https://' . htmlspecialchars($row['canonical']), 'description' => htmlspecialchars($row['textRSS']), 'pubDate' => date('r', strtotime($row['date'])) ); array_push($this->rss_items, $item); } // Записываем RSS ленту в файл $rss_feed = $this->generateRSSFeed(); $path = self::FileDir(); file_put_contents($path['relativepath'], $rss_feed); return $rss_feed; } private function generateRSSFeed() { $rss_feed = '<?xml version="1.0" encoding="UTF-8"?>/n'; $rss_feed .= '<rss version="2.0">/n'; $rss_feed .= '<channel>/n'; $rss_feed .= '<title>'.$this->rss_config['title'].'</title>/n'; $rss_feed .= '<link>'.$this->rss_config['link'].'/rss.xml</link>/n'; $rss_feed .= '<description>'.$this->rss_config['description'].'</description>/n'; foreach ($this->rss_items as $item) { $rss_feed .= '<item>/n'; $rss_feed .= '<title>/n'; $rss_feed .= '<link>' . $item['link'] . '</link>/n'; $rss_feed .= '<description>' . $item['description'] . '</description>/n'; $rss_feed .= '<pubDate>' . $item['pubDate'] . '</pubDate>/n'; $rss_feed .= '</item>'/n; } $rss_feed .= '</channel>/n'; $rss_feed .= '</rss>'; return $rss_feed; } } //Запускаем генератор RSS $rss_generator = new RSSGenerator; $rss_generator->generateRSS();
Для отключения автоматической публикации RSS новостей можно использовать настройку OnOffRss в файле configRSS.ini секция [rss]. Но это Вы надеюсь сможете сделать сами. А о необходимости функции задержки публикаций в RSS я писал в статье RSS каналы – актуальность технологии сегодня.
Дата публикации: