2009-07-27 63 views
6

所以我試圖採用良好的面向對象編程技術與PHP。我的大部分(全部讀)項目涉及MySQL數據庫。我的直接問題涉及我需要開發的用戶模型。PHP的繼承和MySQL

我目前的項目有代理商和銷售線索。代理商和潛在客戶都是擁有大量相同信息的用戶。所以,顯然,我想要一個類代理和一個類導致擴展一個普通的類用戶。現在,我的問題如下:

SQL如何最好地處理加載這些對象?我不想在實例化代理或潛在客戶時執行多個SQL語句。但是,邏輯告訴我,當用戶構造函數被觸發時,它應該執行一條SQL語句來加載代理和潛在客戶之間的共同信息(用戶名,密碼,電子郵件,聯繫信息等)。 Logic還告訴我,當Agents或Leads構造函數被觸發時,我想執行SQL來加載對Agents或Leads類唯一的數據....但是,邏輯還告訴我,執行2每當我需要代理或主管時,SQL語句(因爲可能每個成千上萬)。

我試過尋找這個通常如何處理沒有成功的例子......也許我只是在尋找錯誤的東西?

回答

7

你基本上有三種方法解決這個問題(其中之一,我會立即消除):

每班
  1. 一個表(這是一個我會消除);
  2. 具有可選列的記錄類型;和
  3. 具有子表的記錄類型取決於您加入的類型。

爲了簡單起見,我一般推薦(2)。所以一旦你有你的桌子:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY, 
    type VARCHAR(10), 
    name VARCHAR(100) 
); 

其中類型可以是'代理'或'鉛'(例如)。或者,您可以使用一種字符類型代碼。然後,您可以使用對象模型開始填充空白:

  • 您有一個用戶父類;
  • 你有兩個孩子班:領導和代理;
  • 那些孩子有固定類型。

它應該很容易就位。

至於如何在一個語句中加載,我會使用某種工廠。假設這些準系統類:

class User { 
    private $name; 
    private $type; 
    protected __construct($query) { 
    $this->type = $query['type']; 
    $this->name = $query['name']; 
    } 
    ... 
} 

class Agent { 
    private $agency; 
    public __construct($query) { 
    parent::constructor($query); 
    $this->agency = $query['agency']; 
    } 
    ... 
} 

class Lead { 
    public __consruct($query) { 
    parent::constructor($query); 
    } 
    ... 
} 

工廠看起來是這樣的:

public function loadUserById($id) { 
    $id = mysql_real_escape_string($id); // just in case 
    $sql = "SELECT * FROM user WHERE id = $id"; 
    $query = mysql_query($sql); 
    if (!query) { 
    die("Error executing $sql - " . mysql_error()); 
    } 
    if ($query['type'] == 'AGENT') { 
    return new Agent($query); 
    } else if ($query['type'] == 'LEAD') { 
    return new Lead($query); 
    } else { 
    die("Unknown user type '$query[type]'"); 
    } 
} 

或者,你可以有工廠方法上,比如說一個靜態方法,用戶類和/或使用查找類爲類的查找表。

也許用這種查詢結果資源污染類是最嚴格的OO意義上的可疑設計,但它很簡單並且可行。

+0

我真的很喜歡這個想法。但是最讓我厭煩的是執行SQL來加載所有數據的地方......我不能把它放在User類中,因爲根據類型,我需要不同的SQL。我不想把它全部放在Agent和Lead類中,因爲大部分代碼都是相同的,我想避免複製和粘貼...理想情況下,我希望User類能夠加載共同的信息和Agent/Lead類來加載獨特的信息......但是,我每次執行2個SQL語句,每次我實例化一個Agent或Lead,這是不希望的..... – SpaDusA 2009-07-27 15:44:39

+0

你可以做到這一點在1個SQL語句中。告訴我,你用什麼來加載一個特定的用戶?你通過什麼?一個ID?還有別的嗎? – cletus 2009-07-27 15:52:45

0

你會有一個不是領導或代理的用戶嗎?該類真的需要從數據庫中提取數據嗎?

如果是這樣,爲什麼不把SQL查詢拉入可以在創建子類時重寫的函數中。

0

難道你不能繼承說一個SQL的骨架,然後使用每個子類中的函數來完成基於它的需求的查詢?

使用非常基本的例子:

<?php 
//our query which could be defined in superclass 
$query = "SELECT :field FROM :table WHERE :condition"; 

//in our subclass 
$field = "user, password, email"; 
$table = "agent"; 
$condition = "name = 'jim'"; 

$dbh->prepare($query); 
$sth->bindParam(':field', $field); 
$sth->bindParam....;//etc 

$sth->execute(); 
?> 

正如你可以看到我的例子並不驚人,但應該讓你明白我在獲得。如果你的查詢在子類之間非常相似,那麼我認爲我的建議可以起作用。

顯然它需要一些調整,但它可能是我會採取的方法。