一个老程序程序员的OOP结构


OOP structure for an old procedural programmer

我来自过程编程的世界,汇编程序是我的第一语言,PL/1和Cobol是我学习大多数(坏)习惯的语言。

这是我在这里的第一篇帖子,所以如果我没有100%正确,请接受我的道歉。

我正在将我们的前端和后端系统从过程php重写为OOP,我真的不知道该使用什么结构。

在旧系统中,我们有许多脚本,其中包括xxx.inc.php和所使用的函数,而这些xxx.inc.php又包括其他xxx.inc..php,如db.inc.php、api_pj.inc.php等

为了实现这个OOP,我为每个类创建一个文件并自动加载它们,但我不知道如何处理公共类(数据库、与外部api的连接等)。在测试时,我使用了继承,它运行得很好,但感觉很奇怪。我真的不认为客户类是数据库类的子类。我也不明白什么是需要定义的,什么是不需要定义的。是否应该定义类中的所有变量?

下面的示例不起作用,因为数据库连接对于Customer类不可用。当使用"类客户扩展数据库"时,一切都很好,但我想还有更正确的方法吗?

Alex Andrei回复后编辑的代码

_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;
    }
}

客户.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;");
    }
}

更新
关于如何修改DB连接类和订单类的扩展示例

数据库类

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;
    }
}

订单类别

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;");
    }
}

使用

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

你不需要extend所有的东西,只需要有意义的东西。

只需将数据库连接作为参数传递给其他对象,就可以执行查询。

Ex。

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

您应该为每个类添加一个私有变量来保持数据库连接,例如

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

构造函数看起来像这个

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

在类似的方法中使用它

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

如果其他类使用database类,则可以extend其他类,然后在子构造函数中调用它们。如果选择此方法,请注意方法中存在冲突的变量。

如果Customer类扩展了Database类,那么它将可以访问Database等的方法

class Database{
    public function __construct(){
    }
    /* other methods*/
}
class Customer extends Database{
    public function __construct(){
        parent::__construct();
    }
}
class Order extends Database{
    public function __construct(){
        parent::__construct();
    }
}