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条)

报告相同问题?

悬赏问题

  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本