我的想法是创建一个父类 Db_object 并添加一些我可以在子类中使用的方法。我首先让孩子类用户并测试了所有方法,它们都运行良好,但是当我尝试在其他类( Photo )类中使用相同的方法时,我无法使用create()
,update()
& delete()
。
我是编程新手,没有太多经验。这是我到目前为止所做的:
Db_object(家长):
<?php
class Db_object
{
public static function find_all()
{
return static::find_by_query("SELECT * FROM " . static::$db_table . " ");
}
public static function find_by_id($user_id)
{
global $database;
$test_array = array();
$the_result_array = static::find_by_query("SELECT * FROM " . static::$db_table . " WHERE id=$user_id LIMIT 1");
return !empty($the_result_array) ? array_shift($the_result_array) : $test_array;
}
public static function find_by_query($sql)
{
global $database;
$result_set = $database->query($sql);
//We created an empty array, so that we can store values in it
$the_object_array = array();
/*if($result_set === FALSE)
{
die("Error: " . mysqli_error());
}
if (!empty($result_set))
{*/
// We use while loop to fetch the database table
while($row = mysqli_fetch_array($result_set))
{
$the_object_array[] = static::instantiation($row);
}
/*}*/
return $the_object_array;
}
//instantiation method loops through the databse record & assign those to object properties.
public static function instantiation($the_record)
{
$calling_class = get_called_class();
$the_object = new $calling_class;
foreach ($the_record as $the_attribute => $value)
{
if($the_object->has_the_attribute($the_attribute))
{
$the_object->$the_attribute = $value;
}
}
return $the_object;
}
private function has_the_attribute($the_attribute)
{
$object_properties = get_object_vars($this);
return array_key_exists($the_attribute, $object_properties);
}
//Method to get all the properties.
protected function properties()
{
$properties = array();
foreach (static::$db_table_fields as $db_field)
{
if (property_exists($this, $db_field))
{
$properties[$db_field] = $this->$db_field;
}
}
return $properties;
}
//We are looping through protected static $db_table_fields.
protected function clean_properties()
{
global $database;
$clean_properties = array();
foreach($this->properties() as $key => $value)
{
$clean_properties[$key] = $database->escape_string($value);
}
return $clean_properties;
}
public function save()
{
return isset($this->id) ? $this->update() : $this->create();
}
public function create()
{
global $database;
$properties = $this->clean_properties();
$sql = "INSERT INTO " . static::$db_table . "(" . implode(",", array_keys($properties)) . ")";
$sql .= "VALUES ('" . implode("','", array_values($properties)) . "')";
if ($database->query($sql))
{
//This method is responsible for pulling up the last query, then assigmimg the id to the object.
$this->id = $database->the_insert_id();
return true;
}
else
{
return false;
}
}
public function update()
{
global $database;
$properties = $this->clean_properties();
$property_pairs = array();
foreach ($properties as $key => $value)
{
$property_pairs[] = "{$key}='{$value}'";
}
$sql = "UPDATE " . static::$db_table . " SET ";
$sql .= implode(", ", $property_pairs);
$sql .= " WHERE id= " . $database->escape_string($this->id);
$database->query($sql);
return (mysqli_affected_rows($database->connection) == 1) ? true : false;
}
public function delete()
{
global $database;
$sql = "DELETE FROM " . static::$db_table . " ";
$sql .= "WHERE id=" . $database->escape_string($this->id);
$sql .= " LIMIT 1";
$database->query($sql);
return (mysqli_affected_rows($database->connection) == 1) ? true : false;
}
}
?>
用户(一切似乎都运转良好):
<?php
include ("init.php");
class User extends Db_object
{
protected static $db_table = "users";
protected static $db_table_fields = array('username', 'password', 'first_name', 'last_name');
public $id;
public $username;
public $password;
public $first_name;
public $last_name;
public static function verify_user($username, $password)
{
global $database;
//To senatize Username & Password.
$username = $database->escape_string($username);
$password = $database->escape_string($password);
$sql = "SELECT * FROM " . self::$db_table . " WHERE ";
$sql .= "username = '{$username}' ";
$sql .= "AND password = '{$password}' ";
$sql .= "LIMIT 1";
$the_result_array = self::find_by_query($sql);
return !empty($the_result_array) ? array_shift($the_result_array) : false;
}
}
?>
照片(创建,更新和删除无效):
<?php
//include ("init.php");
class Photo extends Db_object
{
protected static $db_table = "photos";
protected static $db_table_fields = array('photo_id', 'title', 'description', 'file_name', 'type', 'size');
public $photo_id;
public $title;
public $description;
public $file_name;
public $type;
public $size;
}
?>
此外,这是来自数据库类的query()
方法:
public function query($sql)
{
$result = mysqli_query($this->connection, $sql);
return $result;
}
我没有得到任何错误。如果代码中有任何混淆,请询问,我会尝试解释。
答案 0 :(得分:0)
继续我的评论,看看这些修改是否适合您。我真的不明白为什么你在课堂上制作动态属性,我认为这不是完全必要的。它主要是在课堂上混乱并且使管理变得更加困难:
class DbObject
{
# Put the base properties in the parent class
private static $database;
protected $db_table_fields = array();
protected $db_table,
$properties;
public function __construct()
{
# Fetch any arguments into the construct
$args = func_get_args();
# If a database is passed, assign it
if(!empty($args[0]) && is_a($args[0],'mysqli'))
self::$database = $args[0];
}
# Create a db connection retrieval method
public function getDb()
{
# I use PDO, but I think the instanceof MySQLi is correct...
$con = (self::$database instanceof mysqli)? self::$database : false;
# If not assigned, throw error
if(!$con)
throw new Exception('Database is not set.');
return $con;
}
# I renamed your methods to camel case
public function findAll()
{
if(empty($this->db_table))
throw new Exception('Table name is not set yet.');
return (empty($this->db_table))? false : $this->findByQuery("SELECT * FROM " . $this->db_table . " ");
}
# Remove static
public function findById($user_id)
{
$test_array = array();
# If you don't bind, at least check it's numeric
if(!is_numeric($user_id))
return $test_array();
$the_result_array = $this->findByQuery("SELECT * FROM " . $this->db_table . " WHERE id={$user_id} LIMIT 1");
return !empty($the_result_array) ? array_shift($the_result_array) : $test_array;
}
# Remove static
public function findByQuery($sql)
{
$database = $this->getDb();
$result_set = $database->query($sql);
# We created an empty array, so that we can store values in it
$the_object_array = array();
// We use while loop to fetch the database table
while($row = mysqli_fetch_assoc($result_set)) {
$the_object_array[] = $row;
}
return $the_object_array;
}
//Method to get all the properties.
protected function properties()
{
$this->properties = array();
if(empty($this->db_table_fields) || !is_array($this->db_table_fields))
return $this->properties;
foreach($this->db_table_fields as $db_field) {
if (!isset($this->properties[$db_field])) {
$this->properties[$db_field] = $this->db_field;
}
}
return $this->properties;
}
protected function cleanProperties()
{
$database = $this->getDb();
$clean_properties = array();
foreach($this->properties() as $key => $value) {
$clean_properties[$key] = $database->escape_string($value);
}
return $clean_properties;
}
public function save()
{
return isset($this->id) ? $this->update() : $this->create();
}
public function create()
{
$database = $this->getDb();
$properties = $this->cleanProperties();
$sql = "INSERT INTO " . $this->db_table . "(" . implode(",", array_keys($properties)) . ")";
$sql .= "VALUES ('" . implode("','", array_values($properties)) . "')";
if ($database->query($sql)) {
$this->id = $database->the_insert_id();
return true;
}
else {
return false;
}
}
public function update()
{
$database = $this->getDb();
$properties = $this->cleanProperties();
$property_pairs = array();
foreach ($properties as $key => $value) {
$property_pairs[] = "{$key}='{$value}'";
}
$sql = "UPDATE " . $this->db_table . " SET ";
$sql .= implode(", ", $property_pairs);
$sql .= " WHERE id= " . $database->escape_string($this->id);
$database->query($sql);
return (mysqli_affected_rows($database->connection) == 1) ? true : false;
}
public function delete()
{
$database = $this->getDb();
$sql = "DELETE FROM " . $this->db_table . " ";
$sql .= "WHERE id=" . $database->escape_string($this->id);
$sql .= " LIMIT 1";
$database->query($sql);
return (mysqli_affected_rows($database->connection) == 1);
}
public function getTableFields()
{
return $this->db_table_fields;
}
public function describe()
{
return $this->findByQuery("describe ".$this->db_table);
}
}
class User extends DbObject
{
protected $db_table = "users";
protected $db_table_fields = array('username', 'password', 'first_name', 'last_name');
private $id,
$username,
$password,
$first_name,
$last_name;
public function verifyUser($username, $password)
{
try {
$database = $this->getDb();
//To senatize Username & Password.
$username = $database->escape_string($username);
$password = $database->escape_string($password);
$sql = "SELECT * FROM " . $this->db_table . " WHERE ";
$sql .= "username = '{$username}' ";
$sql .= "AND password = '{$password}' ";
$sql .= "LIMIT 1";
$the_result_array = $this->findByQuery($sql);
}
catch (Exception $e) {
trigger_error($e->getMessage(),E_USER_NOTICE);
}
return !empty($the_result_array) ? array_shift($the_result_array) : false;
}
}
class Photo extends DbObject
{
protected $db_table = "photos";
protected $db_table_fields = array('photo_id', 'title', 'description', 'file_name', 'type', 'size');
private $photo_id,
$title,
$description,
$file_name,
$type,
$size;
}
使用:
# Create the database connection
$MySql = new MySQLi('localhost','username','password','dbname');
# Create instance of User pass database
$User = new User($MySql);
# Create instance of Photo. Since db is static, you don't have pass database
# into subsequent extended classes
$Photo = new Photo();
# Describe user table
print_r($User->describe());
# Describe photos table
print_r($Photo->describe());