douzhu7507 2015-11-30 13:43
浏览 41
已采纳

旧程序程序员的OOP结构

I come from the world of procedural programming with assembler being my first language and PL/1 and Cobol being the languages I learnt most of my (bad) habits from.

This is my first post here, so please accept my apologies if I am not doing it 100% correct.

I am rewriting our frontend and backend systems from procedural php to OOP and I don't really understand what structure to use.

In the old system, we have a number of scripts that include xxx.inc.php with the functions used and those xxx.inc.php in turn includes other xxx.inc.php such as db.inc.php, api_pj.inc.php etc

Trying to do this OOP, I create one file for each class and autoloads them, but I can't understand how to handle the common classes (database, connection to external api's, etc). When testing, I used inheritance and it works fine, but it feels very odd. I can't really see customer class being a child of database class. Also I do not understand what needs to be defined and not. Should all variables in the classes be defined?

The example below do not work, since the database connection is not available for the Customer class. When having "class Customer extends DB" instead it all works fine, but I suppose there is a more correct way of doing this?

Edited code below after reply from Alex Andrei

the_example_page.php

// autoloader
spl_autoload_register(function ($class) {
    require_once 'classes/' . $class . '.class.php';
});

// data for testing
$customer_id = '12090';
$order_id = '31480';

// db
$db = new DB();
$db_conn = $db->db_connect();

// get customer name data and print it:
$customer = new Customer($db_conn);
$customer_data = $customer->get_customer_info($customer_id);
print $customer_data['name'];

// get order date and print it:
$order = new Order($db_conn);
$order_data = $order->get_order_info($order_id);
print $order_data['date'];

DB.class.php

class DB
{
    public function __construct() {}

    public function db_connect()
    {
        static $db_conn;

        if( !$db_conn )
        {
            $db_conn = pg_connect("dbname=database user=user password=PaSsWoRd");
        }
        return $db_conn;
    }

    public function db_exec($sql)
    {
        if( !$sql ) return;
        $db_conn = $this->db_connect();
        $result = @pg_exec($db_conn,$sql);
        if( !$result )
        {
            return;   
        }
        $ret[result] = $result;
        return $ret;
    }

    public function db_getrow(&$a)
    {
    # a bunch of stuff in real function, but here only a plain fetch_array as example       
        $ret = pg_fetch_array($a);
        return $ret;
    }
}

Customer.class.php

class Customer
private $conn;
{
public function __construct($db)
{
    $this->conn=$db;
}

    public function get_customer_info($customer_id) 
    {
        return $this->conn->db_getrow($this->conn->db_exec("SELECT * FROM customer WHERE customerid = $customer_id;"));
    }

    public function get_all_customers($status) 
    {
        return $this->conn->db_exec("SELECT * FROM customer WHERE status = $status;");
    }
}

Order.class.php

class Order
{
private $conn;
{
public function __construct($db)
{
    $this->conn=$db;
}

    public function get_order_info($order_id) 
    {
        return $this->conn->db_getrow($this->conn->db_exec("SELECT * FROM order WHERE orderid = $order_id;"));
    }

    public function get_all_orders($status) 
    {
        return $this->conn->db_exec("SELECT * FROM order WHERE status = $status;");
    }
}
  • 写回答

2条回答 默认 最新

  • duanpei4455 2015-11-30 13:50
    关注

    UPDATE
    Extended example on how to modify the DB connection class and the Order class

    database class

    class DB
    {
        private $conn;
        private $user;
        private $password;
        private $database;
    
        public function __construct($database,$username,$password){
    
            $this->user = $user;
            $this->password = $password;
            $this->database = $database;
    
        }
    
        public function connect(){
            if( !$this->conn ){
                $this->conn = pg_connect("dbname=$this->database user=$this->user password=$this->password");
            }
            return $this->conn;
        }
    
        public function db_exec($sql){
            if( !$sql ) return; // add some relevant error message
    
            if (!$this->conn){
                $this->connect();
            }
    
            $result = pg_exec($this->conn,$sql);
    
            if( !$result ){
                return;   
            }
            $ret[result] = $result;
    
            return $ret;
        }
    
        public function db_getrow(&$a){
        # a bunch of stuff in real function, but here only a plain fetch_array as example       
            $ret = pg_fetch_array($a);
            return $ret;
        }
    }
    

    Order class

    class Order
    {
        private $dbObj;
    
        public function __construct($db)
        {
            $this->dbObj=$db;
        }
    
        public function get_order_info($order_id) 
        {
            $result = $this->dbObj->db_exec("SELECT * FROM order WHERE orderid = $order_id;");
            return $this->dbObj->db_getrow($result);
        }
    
        public function get_all_orders($status) 
        {
            return $this->conn->db_exec("SELECT * FROM order WHERE status = $status;");
        }
    }
    

    Usage

    $db = new DB("myDatabase","user","password");
    $db->connect();
    
    $order = new Order($db);
    

    You don't have to extend everything, only what makes sense.

    Just pass the db connection as a parameter to the other objects, so the queries can be executed.

    Ex.

    $customer = new Customer($db);
    $order = new Order($db);
    

    You should add a private variable for each class to hold the database connection, ex

    class Customer{
        private $conn;
    
        // ...
    }
    

    and the constructor would look like this

    public function __construct($db) {
        $this->conn = $db;
    }
    

    using it in the methods like so

    public function get_order_info($order_id){
        return $this->conn->db_getrow($this->db_exec("SELECT * FROM order WHERE orderid = $order_id;"));
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改