您正試圖實現Active record pattern。
對象持久化的一種方法是提供一個共同的祖先類[例如,BasicEntity
]每個子類中延伸,它建立基於給定數據模式的查詢:
class BasicEntity
{
protected $tablename;
protected $schema;
public function update()
{
$fields = "";
$placeholders = "";
foreach($this -> schema as $field => $type)
{
// you join the fields here to get something like ('username', 'email', 'enabled', 'createdAt', 'password')
// then you write your PDO statement providing placeholders like (:?, :?, :?, :?, :?)
// you'll have to bind parameters based on their $type [int, string, date]
}
$query = sprintf(
"UPDATE %s SET VALUES(%s) = %s",
$this -> tablename,
$fields,
$placeholders
);
// execute statement here, handle exceptions, and so...
}
}
所以你User
類將是這樣的:
class User extends BasicEntity
{
protected $id;
protected $username;
protected $email;
protected $password;
protected $enabled;
protected $createdAt;
public function __construct()
{
$this -> tablename = '_user';
$this -> schema = array(
'id' => 'int',
'username' => 'string',
'email' => 'string',
'password' => 'string',
'enabled' => 'int',
'createdAt' => 'datetime'
);
}
}
而且你Admin
類:
class Admin extends User
{
protected $additionalProperty;
public function __construct()
{
parent::__construct();
$this -> schema['additionalProperty'] = 'string';
}
}
調用update()
將根據類架構構建正確的查詢。這種方法與工作在低複雜度,因爲你會發現:[!在同一個表]
- 如果你擴展你的實體,您需要甚至不提供行空表的字段有這樣的班級[在這種情況下,
additionalProperty
];
- 如果您的模式更改[例如你改變了一個變量名稱],你必須將它硬編碼到類的構造函數中,這使得它更難以維護;如果你想要處理實體之間的關係,那麼在每個SELECT語句中編寫正確的連接將是一個很大的痛苦,除非你只寫了很多單獨的查詢,從而導致性能下降。
要解決的首先,你需要的對象組成,所以你不要讓你的主表增長多少[它只是獲取一個外部AdditionalPropertyList
實體引用,例如。
要解決第二個問題,必須將架構保留在外部文件中或使用inline annotations。
要解決第三個問題,您必須編寫自己的ORM [Object Relational Mapping],或者更好地切換到an existing one。
無論出於什麼學習的好處,我都會站在巨人的肩膀上,如果你打算構建一個可擴展的和可維護的應用程序,我會選擇一個框架。
即使您重寫Admin類中的save方法,仍然可以通過執行parent :: save()來調用父類(即User)中的方法。 –
爲什麼不採取現成的ORM?例如,我最喜歡的:[RedBean](http://redbeanphp.com/#/Tutorial)它使用起來非常簡單,並提供了快速開發。 –