PHP Class Database interaction (using PDO)
Hey guys, so I'm completely new to Object Oriented PHP -- I've read some tutorials, but I can't find anything that really goes into working with a database with PHP classes.
I'm trying to make something simple -- a quick news post class. You get the post from the database, etc. However, I'm getting an error whenever I try to interact with the database.
I read that PDO is the way to go with OO PHP; to that end, I've developed a database class, as detailed in this post: Use of PDO in classes
class Database
{
public $db; // handle of the db connexion
private static $dsn = "mysql:host=localhost;dbname=test";
private static $user = "admin";
private static $pass = "root";
private static $instance;
public function __construct ()
{
$this->db = new PDO(self::$dsn,self::$user,self::开发者_开发技巧$pass);
}
public static function getInstance()
{
if(!isset(self::$instance))
{
$object= __CLASS__;
self::$instance=new $object;
}
return self::$instance;
}
// others global functions
}
I then attempt to use it in my PHP class, in order to retrieve data on a news post:
<?php
require_once "database.php";
class news extends Database
{
private $title;
private $author;
private $date;
private $content;
private $category;
function __construct($id)
{
$db = Database::getInstance();
$query = $this->db->prepare("SELECT title, author, date, content, category FROM news WHERE id = :id LIMIT 1");
$query->bindParam(":id", $this->id, PDO::PARAM_INT);
if ($query->execute())
{
$result = $query->fetch(PDO::FETCH_OBJ);
$this->set_title($result->title);
$this->set_author($result->author);
$this->set_date($result->date);
$this->set_content($result->content);
$this->set_category($result->category);
}
}
<...>
?>
Every time I try to run this script though, I get the following error:
Fatal error: Call to a member function prepare() on a non-object in /news.class.php on line 16
Any ideas?
$db = Database::getInstance();
$query = $this->db->prepare();
You'll have to use either $db
or $this->db
both times. $db
is a variable in the local function. $this->db
is an instance variable of the class. They're not the same. In this case, $this->db
does not exist and as such has no member function prepare
, as the error states.
You're trying to create $this->db
in your parent's constructor, but since you're overriding the constructor in the child class, that code is not run. You would need to call parent::__constructor
for that code to run.
Your design is flawed. Why does news extend Database? Database represents your global database connection. One single row of the news table is not a database connection. So it should not inherit from it. What you should do is follow the "favor composition over inheritance" principle.
Extending a singleton is not a good idea. As a matter of fact, singletons are a bad idea in general, because they make your code monolithic.
What you are doing is basically object-relational mapping. You should take a look at some existing PHP ORMs, I suggest Doctrine.
$db = Database::getInstance(); need to be: $db = new Database();
And this line $query = $this->db->prepare(); need to be $query = $db->prepare();
Then this $query->bindParam(":id", $this->id, PDO::PARAM_INT); need to be $query->bindParam(":id", $id, PDO::PARAM_INT);
I'm not sure why you need the getInstance() function in the Database class? The
new Database()
will give you a new instance.
精彩评论