Проблема со вставкой нескольких элементов RSS в БД

Ситуация:

У меня есть PHP-скрипт, который пытается объединить 26 различных RSS-каналов и вставить до 1000 элементов из этих каналов в БД MySQL.

Хостинг: Блюхост

Версия MySQL: 5.7.23-23

Версия PHP через phpversion(): 8.0.17

Версия PHP через My Admin info:

  • PHP: 7.4.30
  • Версия клиента базы данных: libmysql
  • mysqlnd 7.4.30
  • Расширение PHP: mysqliDocumentation curlDocumentation mbstringDocumentation

Проблема:

Скрипт вставляет только 26 элементов RSS-канала, по 1 элементу из каждого RSS-канала в БД, т.е. он не вставляет ВСЕ элементы RSS из 26-ти каналов (до 1000). Я использовал этот же скрипт для создания RSS-канала и файла JSON, который включает все элементы из 26 элементов RSS.

Вопрос:

Может ли кто-нибудь помочь определить, почему этот скрипт не вставляет все элементы RSS из всех RSS-каналов, как ожидалось? Спасибо вам за помощь.

Код PHP-скрипта:

<?php
$json = new DOMDocument();

$data = array();

$resources = array(
    array( 'type' => 'Article', 'source' => 'Source 1', 'feedurl' => 'http://www.example1.com/feed/', 'id' => '1' ),
    array( 'type' => 'Article', 'source' => 'Source 2', 'feedurl' => 'https://example2.com/feed', 'id' => '2' ),
    array( 'type' => 'Article', 'source' => 'Source 3', 'feedurl' => 'https://example3.com/feed', 'id' => '3' )
);

foreach ( $resources as $resource ) {
  $json->load( $resource['feedurl'] );

  foreach ( $json->getElementsByTagName( 'item' ) as $node ) {
  $item = array(
    'source'  => $resource['source'],
    'type'  => $resource['type'],
    'title' => $node->getElementsByTagName( 'title' )->item( 0 )->nodeValue,
    'link'  => $node->getElementsByTagName( 'link' )->item( 0 )->nodeValue,
    'date'  => $node->getElementsByTagName( 'pubDate' )->item( 0 )->nodeValue,
    'id'  => $resource['id']
  );

  array_push( $data, $item );
  }
}

usort( $data, function( $a, $b ) {
  return strtotime( $b['date'] ) - strtotime( $a['date'] );
});

$servername = '???';
$username = '???';
$password = '???';
$dbname = '???';

// Create connection
$DBconnection = new mysqli($servername, $username, $password, $dbname);
/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

//sql query
$sql = "INSERT INTO articles(source, type, title, url, date, id) VALUES(?, ?, ?, ?, ?, ?)";

//insert into mysql table
$stmt = $DBconnection->prepare($sql);

$limit = 1000;

for ( $x = 0; $x < $limit; $x++ ) {
    $source = $data[ $x ]['source'];
    $type = $data[ $x ]['type'];
    $title = htmlspecialchars(str_replace( ' & ', ' & ', $data[ $x ]['title'] ));
    $link = htmlspecialchars($data[ $x ]['link']);
    $date = date( 'Y-m-d H:i:s', strtotime( $data[ $x ]['date'] ) );
    $id = $data[ $x ]['id'];

    $stmt->bind_param("sssssi", $source, $type, $title, $link, $date, $id);

    $stmt->execute();
}

$stmt->close();
$DBconnection->close();

?>

Попробуйте поместить $stmt = внутрь цикла for

Jacob Mulquin 09.10.2022 02:51

@JacobMulquin спасибо. Я попытался добавить '$stmt =' внутри цикла for, но, к сожалению, он по-прежнему вставляет одинаковое количество элементов. он не вставляет все из них.

Damage 09.10.2022 03:05
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
2
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я переписал код и протестировал локально, похоже, он работает:

$resources = [
  ['type' => 'Article', 'source' => 'Hackaday', 'feedurl' => 'https://hackaday.com/blog/feed/', 'id' => '1'],
  ['type' => 'Article', 'source' => 'The Daily WTF', 'feedurl' => 'http://syndication.thedailywtf.com/TheDailyWtf', 'id' => '2']
];

$dom = new DOMDocument();

$articles = [];

foreach ($resources as $resource) {
  $dom->load($resource['feedurl']);

  foreach ($dom->getElementsByTagName('item') as $node) {
    $articles[] = [
      'id' => $resource['id'],
      'source' => $resource['source'],
      'type' => $resource['type'],
      'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
      'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
      'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue,
    ];
  }
}

usort($articles, function ($a, $b) {
  return strtotime($b['date']) - strtotime($a['date']);
});

$server = '???';
$user = '???';
$pass = '???';
$db = 'so';

$mysql = new mysqli($server, $user, $pass, $db);
$mysql->query('CREATE TABLE IF NOT EXISTS articles (source TEXT, type TEXT, title TEXT, url TEXT, date DATETIME, id INT);');

if (mysqli_connect_errno()) {
  printf("Connect failed: %s\n", mysqli_connect_error());
  exit;
}

$sql = "INSERT INTO articles (source, type, title, url, date, id) VALUES (?, ?, ?, ?, ?, ?);";

$stmt = $mysql->prepare($sql);

foreach ($articles as $article) {
  $source = $article['source'];
  $type = $article['type'];
  $title = htmlspecialchars($article['title']);
  $link = htmlspecialchars($article['link']);
  $date = date('Y-m-d H:i:s', strtotime($article['date']));
  $id = $article['id'];

  $stmt->bind_param("sssssi", $source, $type, $title, $link, $date, $id);
  $stmt->execute();
}

$stmt->close();
$mysql->close();

Это добавляет все записи:

MariaDB [so]> SELECT COUNT(*) FROM articles;
+----------+
| COUNT(*) |
+----------+
|       22 |
+----------+
1 row in set (0.000 sec)

Спасибо за вашу помощь в этом Джейкобе, очень признателен. Это самая странная вещь, я все еще не вижу все элементы RSS в БД. Я вижу 1 элемент RSS на канал RSS - всего 2. Я размещаю свой сайт на Bluehost. Возможно ли, что причиной этого могут быть какие-то настройки сервера, PHP и/или MySQL?

Damage 09.10.2022 05:30

Хм, это действительно очень интересно! Вы используете код, который я разместил точно так же, как есть? Интересно, имеет ли это какое-то отношение к самим фидам, если вы сделаете count($articles) после того, как все они будут извлечены и добавлены, каков будет результат? Также какую версию PHP/MySQL вы используете? Есть вероятность, что где-то может быть ошибка. Я использую PHP 8.1.7 на Debian с MySQL 10.5.15-MariaDB.

Jacob Mulquin 09.10.2022 07:26

Я использую тот же скрипт для объединения всех элементов RSS-каналов в файл JSON и RSS-канал, поэтому я так озадачен, почему он не работает для вставки в БД. Я использовал сценарий как есть, за двумя исключениями: 1. Удалено «СОЗДАТЬ ТАБЛИЦУ, ЕСЛИ НЕ СУЩЕСТВУЕТ» 2. Добавлена ​​информация о БД. Я сделал эхо 'count($articles)'; после последнего цикла foreach и получил: 22. Информация: MySQL: 5.7.23-23 PHP через phpversion(): 8.0.17 PHP через My Admin информация: - PHP: 7.4.30 - Версия клиента базы данных: libmysql - mysqlnd 7.4. 30 — Расширение PHP: mysqliDocumentation curlDocumentation mbstringDocumentation

Damage 09.10.2022 22:15

Другие вопросы по теме