I've been reading an OOP book recently and it gives some nice Adaptor / Template patttern code to wrap around the php Mysql functions. I thought that I'd try and create a Simple Address book using similar methods, but I'm having some trouble with using the class functions (I'm new to OOP in PHP 5).
So far I've written a Contact Book class and a Contact class. The Contact Book class has add, edit, delete and display functions for manipulating and displaying data in a database. My intention is to use the DB_Mysql, DB_MysqlStatement and DB_Mysql_Prod classes which I lifted from the book for the database interactions.
The following are my ContactBook and Contact classes (contacts.inc.php):
[php]
<?php
/*
* A simple contact book class
* @package
* @author chromis
*/
class ContactBook {
protected $dbh;
protected $dbtable;
protected $name;
public function __construct($dbh, $dbtable, $name) {
$this->dbh = $dbh;
$this->dbtable = $dbtable;
$this->name = $name;
$this->display();
}
public function add($contact) {
if(!is_resource($this->dbh)) {
throw new Exception("ContactBook: Database resource invalid.");
}
$query = "INSERT INTO " . $this->dbtable . " (name,email,address)
VALUES (
'" . mysql_escape_string($contact->getName()) . "',
'" . mysql_escape_string($contact->getEmail()) . "',
'" . mysql_escape_string($contact->getAddress()) . "'
);";
$stmt = $this->dbh->execute($query);
}
public function edit($contact) {
}
public function delete($contact) {
}
public function display() {
print("<h1>" . $this->name . " Contact Book</h1>\n");
print("<h2>Contacts:</h2>\n");
$query = "SELECT name,email,address FROM " . $this->dbtable;
// Fetch row results from query
$stmt = $this->dbh->execute($query);
//$ret = $this->dbh->fetch_row();
}
public function show_entry($entry_id) {
$query = "SELECT * FROM $dbtable WHERE entry_id = :1";
$stmt = $this->dbh->prepare($query)->execute($entry_id);
}
}
class Contact {
protected $name;
protected $email;
protected $address;
public function __construct() {
$this->name = $name;
$this->email = $email;
$this->address = $address;
}
public function getName() {
return $this->name;
}
public function getEmail() {
return $this->email;
}
public function getAddress() {
return $this->address;
}
}
?>[/php]
The classes lifted from the book (db.inc.php):
[php]
<?php
/*
* MySQL Database Handling Classes
*
* @package DB_Mysql
* @author chromis
*/
class DB_Mysql {
protected $user;
protected $pass;
protected $dbhost;
protected $dbname;
protected $dbh; // Database connection handle
public function __construct($user, $pass, $dbhost, $dbname) {
$this->user = $user;
$this->pass = $pass;
$this->dbhost = $dbhost;
$this->dbname = $dbname;
$this->connect();
}
public function connect() {
$this->dbh = mysql_connect($this->$dbhost, $this->$user, $this->$pass);
if(!is_resource($this->dbh)) {
throw new Exception("Cannot connect to database.");
}
if(!mysql_select_db($this->dbname, $this->dbh)) {
throw new Exception("Cannot select database.");;
}
}
public function execute($query) {
if(!$this->dbh) {
$this->connect();
}
$ret = mysql_query($query, $this->dbh);
if(!$ret) {
throw new Exception;
}
else if(!is_resource($ret)) {
return TRUE;
}
else {
$stmt = new DB_MysqlStatement($this->dbh, $query);
$stmt->result = $ret;
return $stmt;
}
}
public function prepare($query) {
if(!$this->dbh) {
$this->connect();
}
return new DB_MysqlStatement($this->dbh,$query);
}
}
class DB_MysqlStatement {
protected $result;
protected $dbh;
public $query;
public $binds;
public function __construct($dbh, $query) {
$this->query = $query;
$this->dbh = $dbh;
if(!is_resource($dbh)) {
throw new Exception("Not a valid database connection");
}
}
public function fetch_row() {
if(!$this->result) {
throw new Exception("Query not executed");
}
return mysql_fetch_row($this-result);
}
public function fetch_assoc() {
return mysql_fetch_assoc($this-result);
}
public function fetchall_assoc() {
$retval = array();
while($row = $this->fetch_assoc()) {
$retval[] = $row;
}
return $retval;
}
public function execute() {
$binds = func_get_args();
foreach($binds as $index => $name) {
$this->binds[$index + 1] = $name;
}
$cnt = count($binds);
$query = $this->query;
foreach($this->binds as $ph => $pv) {
$query = str_replace(":$ph", "'".mysql_escape_string($pv)."'",$query);
}
$this->result = mysql_query($query, $this->dbh);
if(!$this->result) {
throw new MysqlException;
}
return $this;
}
}
/*
* Test class - an example of the Template pattern.
* Hides the database specific connection parameters in the previous classes.
*
*/
class DB_Mysql_Prod extends DB_Mysql {
protected $user = "***";
protected $pass = "***";
protected $dbhost = "***";
protected $dbname = "***";
public function __construct() {}
}
?>
[/php]
And the code to initialise them (index.php):
[php]
include("inc/db.inc.php");
include("inc/contacts.inc.php");
// Create new mysql db connection
$dbh = new DB_Mysql_Prod();
// Create contact book passing in db connection, db table and name of contact book
$myContactBook = new ContactBook($dbh, "simple_address_book", "E-Simple");
[/php]
The function that I'm working on at the moment is the display function in the ContactBook class, what I'm trying to do is write a function correctly which retrieves the contacts from the database using the db classes and then displays them, first of all though i need to get the query statement to work:
[php]
public function display() {
print("<h1>" . $this->name . " Contact Book</h1>\n");
print("<h2>Contacts:</h2>\n");
$query = "SELECT name,email,address FROM " . $this->dbtable;
// Fetch row results from query
$stmt = $this->dbh->execute($query); (query statement)
//$ret = $this->dbh->fetch_row();
}
[/php]
I'm getting the following error though:
Expand|Select|Wrap|Line Numbers
- Notice: Undefined variable: dbhost in D:\sites\eddy\php\simple-address-book\inc\db.inc.php on line 23
- Fatal error: Cannot access empty property in D:\sites\eddy\php\simple-address-book\inc\db.inc.php on line 23
Thanks,
chromis