[英]Unable to use Parent Class method in second Child Class
我的想法是制作一個父類Db_object並放置一些可以在子類中使用的方法。 我首先使子類User成為用戶並測試了所有方法,並且它們都可以正常工作,但是當我嘗試在另一個類( 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;
}
我沒有任何錯誤。 如果代碼中有任何混淆,請詢問,我將嘗試解釋。
除了我的評論,請查看這些修改是否對您有用。 我不太了解為什么要在類中創建動態屬性,我認為這不是完全必要的。 它主要使班級混亂,並使管理變得更加困難:
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());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.