Ситуация:
У меня есть PHP-скрипт, который пытается объединить 26 различных RSS-каналов и вставить до 1000 элементов из этих каналов в БД MySQL.
Хостинг: Блюхост
Версия MySQL: 5.7.23-23
Версия PHP через phpversion(): 8.0.17
Версия PHP через My Admin info:
Проблема:
Скрипт вставляет только 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();
?>
@JacobMulquin спасибо. Я попытался добавить '$stmt =' внутри цикла for, но, к сожалению, он по-прежнему вставляет одинаковое количество элементов. он не вставляет все из них.






Я переписал код и протестировал локально, похоже, он работает:
$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?
Хм, это действительно очень интересно! Вы используете код, который я разместил точно так же, как есть? Интересно, имеет ли это какое-то отношение к самим фидам, если вы сделаете count($articles) после того, как все они будут извлечены и добавлены, каков будет результат? Также какую версию PHP/MySQL вы используете? Есть вероятность, что где-то может быть ошибка. Я использую PHP 8.1.7 на Debian с MySQL 10.5.15-MariaDB.
Я использую тот же скрипт для объединения всех элементов 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
Попробуйте поместить
$stmt =внутрь цикла for