无法在第二个子类

时间:2017-09-01 16:12:18

标签: php

我的想法是创建一个父类 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;
    }

我没有得到任何错误。如果代码中有任何混淆,请询问,我会尝试解释。

1 个答案:

答案 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());