I am following a YouTube video for making a listing website using PHP. However, when I try and create a new listing, this happens in my browser:
Fatal error: Uncaught Error: Call to a member function prepare() on null in D:\Dev\Dependencies\XAMPP\htdocs\addonlister\lib\Database.php:31 Stack trace: #0 D:\Dev\Dependencies\XAMPP\htdocs\addonlister\lib\Addon.php(61): Database->query('SELECT * FROM a...') #1 D:\Dev\Dependencies\XAMPP\htdocs\addonlister\addon.php(10): Addon->getAddon('2') #2 {main} thrown in D:\Dev\Dependencies\XAMPP\htdocs\addonlister\lib\Database.php on line 31
Here is my code on the referenced pages:
database.php
<?php
class Database{
private $host = DB_HOST;
private $user = DB_USER;
private $pass = DB_PASS;
private $dbname = DB_NAME;
private $dbh;
private $error;
private $stmt;
public function __construct(){
// Set DSN
$dsn = 'mysql:host=localhost'. $this->host .';dbname=addonlister' . $this->dbname;
// Set Options
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
// PDO Instance
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
} catch(PDOException $e) {
$this->error = $e->getMessage();
}
}
public function query($query){
$this->stmt = $this->dbh->prepare($query);
}
public function bind($param, $value, $type = null){
if(is_null($type)){
switch(true){
case is_int ( $value ) :
$type = PDO::PARAM_INT;
break;
case is_bool ( $value ) :
$type = PDO::PARAM_BOOL;
break;
case is_null ( $value ) :
$type = PDO::PARAM_NULL;
break;
default :
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}
public function execute(){
return $this->stmt->execute();
}
public function resultSet(){
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_OBJ);
}
public function single(){
$this->execute();
return $this->stmt->fetch(PDO::FETCH_OBJ);
}}
Addon.php
<?php
class Addon{
private $db;
public function __construct(){
$this->db = new Database;
}
// Get All Addons
public function getAllAddons(){
$this->db->query("SELECT addons.*, categories.name AS cname
FROM addons
INNER JOIN categories
ON addons.category_id = categories.id
ORDER BY post_date DESC
");
// Assign Result Set
$results = $this->db->resultSet();
return $results;
}
//Get Categories
public function getCategories(){
$this->db->query("SELECT * FROM categories");
// Assign Result Set
$results = $this->db->resultSet();
return $results;
}
// Get Addons By Category
public function getByCategory($category){
$this->db->query("SELECT addons.*, categories.name AS cname
FROM addons
INNER JOIN categories
ON addons.category_id = categories.id
WHERE addons.category_id = $category
ORDER BY post_date DESC
");
// Assign Result Set
$results = $this->db->resultSet();
return $results;
}
// Get category
public function getCategory($category_id){
$this->db->query("SELECT * FROM categories WHERE id = :category_id"
);
$this->db->bind(':category_id' , $category_id);
// Assign Row
$row = $this->db->single();
return $row;
}
// Get Addon
public function getAddon($id){
$this->db->query("SELECT * FROM addons WHERE id = :id");
$this->db->bind(':id' , $id);
// Assign Row
$row = $this->db->single();
return $row;
}
// Addon Job
public function create($data){
//Insert Query
$this->db->query("INSERT INTO addons (category_id, addon_title, description, developer, file_size)
VALUES (:category_id, :addon_title, :description, :developer, :file_size)");
//Bind Data
$this->db->bind(':category_id', $data['category_id']);
$this->db->bind(':addon_title', $data['addon_title']);
$this->db->bind(':description', $data['description']);
$this->db->bind(':developer', $data['developer']);
$this->db->bind(':file_size', $data['file_size']);
//Execute
if($this->db->execute()){
return true;
} else {
return false;
}
}
}
Addon.php
<?php include_once 'config/init.php'; ?>
<?php
$addon = new Addon;
$template = new Template('templates/addon-single.php');
$addon_id = isset($_GET['id']) ? $_GET['id'] : null;
$template->addon = $addon->getAddon($addon_id);
echo $template;