Вопрос или проблема
Я пытаюсь создать веб-страницу, которая случайным образом выбирает песню из моей базы данных для воспроизведения с условием, что песня еще не воспроизводилась. В моей базе данных есть поле с названием played, значение по умолчанию – false. Я хочу извлечь информацию из базы данных и затем установить поле played для этой песни в true. Я обдумывал идею сделать обновление функцией, но когда я пытался выполнить это на странице, это не сработало. Я добавил обновление после моего оригинального запроса Select, который выбирает песню. Это не вызывает ошибок и сообщает, что было успешно, но когда я проверяю свою базу данных на обновление, ничего не изменилось. Я не уверен, какой будет лучший способ. Я хочу, чтобы песни воспроизводились непрерывно (что является другой проблемой, которую нужно решить в другом вопросе).
<?php
// Подключение к базе данных
$servername = "localhost";
$username="xxx";
$password = 'xxx';
$dbname="bingo";
// Создание подключения
$conn = new mysqli($servername, $username, $password, $dbname);
// Проверка подключения
if ($conn->connect_error) {
die("Ошибка подключения: " . $conn->connect_error);
}
//echo "Подключение успешно";
// Создание класса для музыки
class Music {
// Свойства
public $played;
public $cover;
public $title;
public $artist;
public $song;
public $result;
// Метод для выбора песни
function chooseSong($conn) {
$sql = "SELECT music.Song, music.Image, music.Title, artist.Name, music.played
FROM music
INNER JOIN artist ON music.Artist_ID = artist.Artist_ID
WHERE music.played = false
ORDER BY RAND() LIMIT 1";
$this->result = $conn->query($sql);
// обновление поля played с false на true, чтобы песня воспроизводилась только один раз
$sql2 = "UPDATE music SET music.played = 'true'";
if (mysqli_query($conn, $sql2)) {
echo "Запись была обновлена";
}
else {
echo "ОШИБКА: Не удалось выполнить $sql2. " . mysqli_error($conn);
}
if ($this->result->num_rows > 0) {
// Получение результата в ассоциативный массив
$row = $this->result->fetch_assoc();
$this->song = $row['Song'];
$this->cover = $row['Image'];
$this->title = $row['Title'];
$this->artist = $row['Name'];
$this->played = $row['played'];
} else {
echo "Песен не найдено.";
}
}
// Методы для получения информации о песне
function getSong() {
return $this->song;
}
function getCover() {
return $this->cover;
}
function getTitle() {
}
function getArtist() {
return $this->artist;
}
function getplayed() {
return $this->played;
}
}
// Пример использования
$music = new Music();
$music->chooseSong($conn);
//echo "Песня: " . $music->getSong() . "<br>";
//echo "Обложка: " . $music->getCover() . "<br>";
//echo "Название: " . $music->getTitle() . "<br>";
//echo "Исполнитель: " . $music->getArtist() . "<br>";
//echo "Воспроизводилось: " . $music->getplayed() . "<br>";
$cover = $music->getCover();//
$title = $music->getTitle() ;
$artist = $music->getArtist();
$song = $music->getSong();
// Закрытие подключения
//$conn->close();
?>
<!DOCTYPE html>
<html>
<title>Музыкальное бинго</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="Bingo.css">
<body>
<head>
<img src="Title.jpg" alt="Музыкальное бинго" style="width:100px;height:75px;" id="Title">
</head>
<section id = "playnow" >
<!--Этот раздел предназначен для отображения текущей воспроизводимой песни -->
<h2>Сейчас играет</h2>
<img src="https://stackoverflow.com/questions/79102822/<?php echo $cover; ?>" style="width:200px;height:200px;" id="Cover" > <br>
<h3><?php echo $title . "<br>"; ?></h3>
<h4><?php echo $artist . "<br>";?></h4>
<audio controls autoplay>
<source src="<?php echo $song; ?>" type="audio/mp3">
</audio>
</section>
<h2>Воспроизведенные песни</h2>
<section id="played" ><!-- Этот раздел предназначен для отображения песен, которые уже были воспроизведены
-- >
<!-- <h2>Воспроизведенные песни</h2> -->
<ul>
<li><?php echo $title; ?> / <?php echo $artist; ?> <br></li>
</ul>
</section>
}
</body>
</html>
Ответ или решение
Для решения задачи обновления поля в базе данных MySQL из PHP при выборе случайной песни, которая должна воспроизводиться только один раз, необходимо внести несколько изменений в предоставленный код. Основная проблема заключается в том, что ваш обновленный запрос SQL не уточняет, какая именно запись должна быть обновлена. Давайте разберем эту проблему более подробно и предложим улучшения.
Пошаговая инструкция по обновлению поля в цикле с использованием PHP и MySQL
-
Подключение к базе данных:
Первым делом вы уже правильно настроили подключение к базе данных. Убедитесь, что ваши учетные данные верны, и база данных доступна. -
Выбор случайной песни:
В вашем методеchooseSong
вы выбрали случайную песню, но необходимо сохранитьID
или другое уникальное поле для этой песни, чтобы правильно обновить запись. -
Обновление поля ‘played’:
После того как вы выбрали песню, вам нужно выполнить обновление поляplayed
для конкретной записи, а не для всех записей.
Обновленный код
Вот предлагемый обновленный код с комментариями:
<?php
// Подключение к базе данных
$servername = "localhost";
$username = "xxx"; // Ваше имя пользователя
$password = 'xxx'; // Ваш пароль
$dbname = "bingo"; // Название базы данных
// Создание соединения
$conn = new mysqli($servername, $username, $password, $dbname);
// Проверка соединения
if ($conn->connect_error) {
die("Ошибка соединения: " . $conn->connect_error);
}
// Класс для музыки
class Music {
public $played;
public $cover;
public $title;
public $artist;
public $song;
public $result;
public $songId; // Добавление переменной для ID песни
// Метод для выбора песни
function chooseSong($conn) {
// Запрос на выбор случайной песни, которая не играла
$sql = "SELECT music.Song, music.Image, music.Title, artist.Name, music.played, music.Music_ID
FROM music
INNER JOIN artist ON music.Artist_ID = artist.Artist_ID
WHERE music.played = false
ORDER BY RAND() LIMIT 1";
$this->result = $conn->query($sql);
if ($this->result->num_rows > 0) {
$row = $this->result->fetch_assoc();
$this->song = $row['Song'];
$this->cover = $row['Image'];
$this->title = $row['Title'];
$this->artist = $row['Name'];
$this->played = $row['played'];
$this->songId = $row['Music_ID']; // Сохранение уникального идентификатора песни
// Обновление поля played для выбранной песни
$this->updatePlayed($conn, $this->songId);
} else {
echo "Нет доступных песен.";
}
}
// Метод для обновления поля played
function updatePlayed($conn, $songId) {
$sql2 = "UPDATE music SET played = true WHERE Music_ID = ?";
$stmt = $conn->prepare($sql2);
$stmt->bind_param("i", $songId); // связываем параметр
if ($stmt->execute()) {
echo "Запись была обновлена";
} else {
echo "Ошибка: не удалось выполнить " . $stmt->error;
}
$stmt->close(); // Закрытие подготовленного выражения
}
// Остальные методы...
}
// Пример использования
$music = new Music();
$music->chooseSong($conn);
// Закрытие соединения
$conn->close();
?>
Краткие пояснения:
-
Добавление уникального идентификатора:
В запросеSELECT
добавлено полеMusic_ID
, которое представляет уникальный идентификатор каждой песни. Это будет использоваться позже для обновления. -
Подготовленные выражения:
Использование подготовленных выражений сbind_param
защищает ваш код от SQL-инъекций и является хорошей практикой при работе с пользовательским вводом. -
Закрытие соединений:
Не забудьте закрыть соединение с базой данных после завершения операций, чтобы предотвратить утечки ресурсов.
Заключение
Теперь, после выбора случайной песни, поле played
для данной песни будет обновляться правильно. Это обеспечит, что песня будет воспроизводиться только один раз, а все другие песни останутся доступными для воспроизведения. Переходите к следующей части вашей задачи, если необходимо реализовать воспроизведение песен в непрерывном цикле или другие улучшения.
Если у вас есть дополнительные вопросы, смело задавайте!