2015-11-30 27 views
0

我來自程序化編程的世界,彙編程序是我的第一語言,PL/1和Cobol是我學習我大部分(壞)習慣的語言。舊的程序員程序員的OOP結構

這是我第一篇文章,所以請接受我的道歉,如果我沒有做到100%正確。

我正在改寫我們的前端和後端系統,從程序化的PHP到OOP,我真的不知道要使用什麼結構。

在舊系統中,我們有許多腳本,其中包括使用函數的xxx.inc.php,而xxx.inc.php又包含其他xxx.inc.php,如db.inc.php, api_pj.inc.php等

試圖做到這一點,我爲每個類創建一個文件並自動加載它們,但我無法理解如何處理常見類(數據庫,連接到外部api的等)。測試時,我使用繼承,它工作正常,但感覺很奇怪。我無法真正看到客戶類是數據庫類的孩子。 另外我不明白什麼需要定義而不是。是否應該定義類中的所有變量?

下面的示例不起作用,因爲數據庫連接不適用於Customer類。當「類客戶擴展數據庫」,而不是一切正常,但我想有一個更正確的方式做到這一點?

編輯亞歷安德烈

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

的確是一個CUS tomer *不是*數據庫,所以它不應該繼承它。研究***依賴注入***。從看起來像'$ db = new Database('foo','bar')的消費者一方; $ cust = new Customer($ db);'。更好的是:'$ manager = new CustomerManager($ db); $ cust = $ manager-> get(42);'。看看*庫模式* – deceze

回答

1

UPDATE
關於如何修改數據庫連接類和Order類擴展的例子方法

數據庫類別

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 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一切,只是情理之中的事情。

只需將db連接作爲參數傳遞給其他對象,以便可以執行查詢。

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

謝謝你的答覆。因此,如果我理解正確,我會通過$ db = new DB()在the_example_page.php中激發數據庫(如果是這樣的話)。並將其發送給其他課程?但那是一個客體而不是聯繫?要麼?在DB.class.php中,連接是$ db_conn,所以我認爲這應該傳遞給其他類。 (可能我誤解了這一切,但是當我回到一個小時後我會更多地閱讀它) –

+0

是的。非常好。 DB對象有一個返回'connection'的方法。您可以將此作爲參數傳遞給其他類。它是「實例化」:) –

+0

我更新了代碼,但得到錯誤:PHP致命錯誤:在類/ Customer.class中的非對象上調用成員函數db_getrow()。php 12行 第12行是:return $ this-> conn-> db_getrow($ this-> conn-> db_exec(「SELECT * FROM customer WHERE customerid = $ customer_id;」)); –

-1

如果他們使用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(); 
    } 
} 
+0

感謝downvote所以該死的很快...意外地提交了一半完成的帖子和... – RamRaider

+0

這不是關於半完成的答案,這是關於糟糕的面向對象操作。客戶*不是數據庫,所以不應該繼承它。在這個問題下看到我的評論。 – deceze

+0

其次,如果您的客戶除了調用父構造函數之外沒有在其構造函數中執行任何操作,只需將其完全保留,完全不需要編寫它。 – deceze