public function getAllSongs(){ $sql = "SELECT id, artist, track, link FROM song"; $query = $this->db->prepare($sql); $query->execute(); return $query->fetchAll();}
application/controller/songs.php
public function index(){ // Get all songs from model $songs = $this->model->getAllSongs(); $amount_of_songs = $this->model->getAmountOfSongs(); // Load views require APP . 'view/_templates/header.php'; require APP . 'view/songs/index.php'; require APP . 'view/_templates/footer.php';}
public function getSong($song_id){ $sql = "SELECT id, artist, track, link FROM song WHERE id = :song_id LIMIT 1"; $query = $this->db->prepare($sql); $parameters = array(':song_id' => $song_id); $query->execute($parameters); return $query->fetch();}
application/controller/songs.php
public function editSong($song_id){ if (isset($song_id)) { // Get song from model $song = $this->model->getSong($song_id); // Load views require APP . 'view/_templates/header.php'; require APP . 'view/songs/edit.php'; require APP . 'view/_templates/footer.php'; } else { // No ID provided - redirect header('location: ' . URL . 'songs/index'); }}
public function addSong(){ // Check if form was submitted if (isset($_POST["submit_add_song"])) { // Call model method $this->model->addSong( $_POST["artist"], $_POST["track"], $_POST["link"] ); } // Redirect back to index header('location: ' . URL . 'songs/index');}
3
Execute INSERT query in model
application/model/model.php
public function addSong($artist, $track, $link){ $sql = "INSERT INTO song (artist, track, link) VALUES (:artist, :track, :link)"; $query = $this->db->prepare($sql); $parameters = array( ':artist' => $artist, ':track' => $track, ':link' => $link ); $query->execute($parameters);}
The controller action (e.g., addSong()) is not a regular page - it’s an ACTION endpoint. It processes POST data and redirects. Never render views directly from action methods.
public function updateSong(){ if (isset($_POST["submit_update_song"])) { // Call model update method $this->model->updateSong( $_POST["artist"], $_POST["track"], $_POST["link"], $_POST['song_id'] ); } // Redirect back to index header('location: ' . URL . 'songs/index');}
3
Execute UPDATE query in model
application/model/model.php
public function updateSong($artist, $track, $link, $song_id){ $sql = "UPDATE song SET artist = :artist, track = :track, link = :link WHERE id = :song_id"; $query = $this->db->prepare($sql); $parameters = array( ':artist' => $artist, ':track' => $track, ':link' => $link, ':song_id' => $song_id ); $query->execute($parameters);}
The hidden song_id field is crucial - it tells the update method which record to modify.
public function deleteSong($song_id){ if (isset($song_id)) { // Call model delete method $this->model->deleteSong($song_id); } // Redirect back to index header('location: ' . URL . 'songs/index');}
application/model/model.php
public function deleteSong($song_id){ $sql = "DELETE FROM song WHERE id = :song_id"; $query = $this->db->prepare($sql); $parameters = array(':song_id' => $song_id); $query->execute($parameters);}
Delete operations via GET requests (URL links) are not production-ready. In real applications, use POST requests with CSRF tokens and confirmation dialogs.
public function getAmountOfSongs(){ $sql = "SELECT COUNT(id) AS amount_of_songs FROM song"; $query = $this->db->prepare($sql); $query->execute(); return $query->fetch()->amount_of_songs;}
public function searchSongs($search_term){ $sql = "SELECT id, artist, track FROM song WHERE artist LIKE :search OR track LIKE :search"; $query = $this->db->prepare($sql); $parameters = array(':search' => '%' . $search_term . '%'); $query->execute($parameters); return $query->fetchAll();}