I'm currently developing a music website using OOP PHP and I'm trying to correctly implement the Model View Controller pattern.
I am creating this website from scratch so I would like to avoid answers suggesting I use frameworks such CakePHP etc please.
Here are simplified snippets of the files I'm using to generate a page on my site that displays an album release.
albumView.php (VIEW)
<?php
include_once($_SERVER['DOCUMENT_ROOT'].'/../app/config.php');
include('commonHead.php'); //shared site head
include('htmlHeader.php'); //shared website header
$album = new AlbumController(); //instantiate controller
?>
<div id="main">
<article>
<header>
<h1><?php $album->echoArtist(); ?></h1>
</header>
<?php if($album->isTracklisting()) : ?>
<section id="tracklisting">
<header>
<h1>TRACK LISTING</h1>
</header>
<ol>
<?php $album->echoTracklisting() ?>
</ol>
</section>
<?php endif ?>
...etc...
<?php
include('htmlFooter.php');
include('commonFoot.php');
?>
AlbumController.php (CONTROLLER)
//Inherits shared page display fields and functions
class AlbumController extends PageController
{
private $albumModel;
public function __construct()
{
parent::__construct();
//Instantiate new album model
$this->albumModel = new AlbumModel($this->getDate, $this->getRelease);
}
public function echoArtist()
{
echo $albumModel->artist;
}
public function isTracklisting()
{
if(!$this->strEmpty($albumModel->tracklisting)) return true;
}
public function echoTracklisting()
{
$songArray = explode(',', $albumModel->tracklisting);
foreach($songArray as $song) {
...various logic...
$html = '<li class="'.$class.'" '.$mp3Data.'>'.$song.'</li>';
echo $html;
}
}
...etc...
PageController.php (CONTROLLER SUPER CLASS)
abstract class PageController
{
protected $getDate;
protected $getRelease;
function __construct()
{
if(isset($_GET['date'])) $this->getDate = $_GET['date'];
if(isset($_GET['release'])) $this->getRelease = $_GET['release'];
}
...etc...
AlbumModel.php (MODEL)
class AlbumModel
{
//Album data variables
public $artist;
public $album;
public $genre;
public $releaseDate;
public $tracklisting;
private $db;
private $getDate;
private $getRelease;
public function __construct($getDate, $getRelease)
{
$this->getDate = $getDate;
$this->getRelease = $getRelease;
//Create new db object
$this->db = new Database();
//Get album array from db
$albumArray = $this->getAlbumArrayFromDB();
//Assign variables
$this->artist = $albumArray['artist'];
$this->album = $albumArray['album'];
$this->genre = $albumArray['genre'];
$this->releaseDate = $albumArray['date'];
$this->tracklisting = $albumArray['tracklisting'];
}
private function getAlbumArrayFromDB()
{
//Query DB
$sql = 'SELECT * FROM releases WHERE date = '.$this->getDate.' AND release_number = '.$this->getRelease;
$qId = $this->db->query($sql);
$albumArray = $this->db->fetch_array_assoc($qId);
return $albumArray;
}
...etc...
And my config.php defines constants and imports all my classes
config.php
//Paths
define('ABS_PATH', dirname(__FILE__));
//Database
define('DB_NAME', 'myname');
define('DB_USER', 'myuser');
define('DB_PASSWORD', 'mypass');
define('DB_HOST', 'myhost');
...etc...
//Import all classes
foreach(glob(dirname(__FILE__).'/classes/*.php') as $classPath) {
require_once($classPath);
}
Am I understanding and implementing the MVC design pattern correctly?
I know strictly speaking it's not best practice to access instance variables directly (e.g. $albumModel->artist) but with dozens of additional variables it seems overkill/unnecessary to create getter functions for each one and then redefine them all again in the controller. I put these here because as I understand it the model defines the data, but I could just return an array to the controller and define these variables there?
Anything I'm missing or best practices I'm not adhering to?
Any advice greatly appreciated.
Many thanks