問題描述
我擁有的每個數據庫表都有一個類,例如 events
表的行存儲在 Event
類中.對于我編寫的每個類,有幾個方法完全相同,只是變量或列名不同.例如:
I have a class for each database table I have, for example events
table's rows are stored in Event
classes. For each class I write, there are several methods that are exactly the same just with different variables or column names. For example:
播放器類 update()
public function update() {
$conn = new PDO( db_host, db_user, db_pw );
$sql = "UPDATE players SET name=:name, picture=:picture, position=:position, num=:num, team=:team, description=:description WHERE id = :id";
$st = $conn->prepare ( $sql );
$st->bindValue( ":name", $this->name, PDO::PARAM_STR );
$st->bindValue( ":picture", $this->picture, PDO::PARAM_STR );
$st->bindValue( ":position", $this->position, PDO::PARAM_STR );
$st->bindValue( ":num", $this->num, PDO::PARAM_INT );
$st->bindValue( ":team", $this->team, PDO::PARAM_INT );
$st->bindValue( ":description", $this->description, PDO::PARAM_STR);
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
團隊班級update()
public function update() {
$conn = new PDO( db_host, db_user, db_pw );
$sql = "UPDATE teams SET name=:name, sname=:sname, logo=:logo, sport=:sport WHERE id = :id";
$st = $conn->prepare ( $sql );
$st->bindValue( ":name", $this->name, PDO::PARAM_STR );
$st->bindValue( ":sname", $this->sname, PDO::PARAM_STR );
$st->bindValue( ":logo", $this->logo, PDO::PARAM_STR );
$st->bindValue( ":sport", $this->sport, PDO::PARAM_STR );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
正如您所見,方法的重點是相同的,只是將不同的變量綁定到語句(更多方法就是這種情況).有沒有一種簡單的方法可以讓每個類都有相同的基本 update()
、insert()
、delete()
... 方法但有其各自的變量?我曾想過從超類繼承基本行為,但從 OO 的角度來看并沒有多大意義(我不相信有任何方式可以說對于此類中聲明的每個公共變量"),但我不是確定是否有辦法使用合成來做到這一點(或者根本沒有).
As you can see the point of the methods are the same it's just different variables being bound to the statement (this is the case with more methods). Is there an easy way to do it so that each class has the same basic update()
, insert()
, delete()
... methods but with its respective variables? I have thought of inheriting basic behaviour from a super class but from OO point of view doesn't make much sense (and im not convinced there is any way of saying "for each public variable declared in this class") but I'm not sure if there is a way to do this using compositions (or at all, really).
推薦答案
是的,這是你所說的一個嬰兒 ORM,它很容易實現.
Yes, this a baby ORM you are talking about and it is quite easy to implement.
首先,創建一個原型類,包含所有常用方法(create()、update()、find() 等).
First of all, create a prototype class, with all the common methods (create(), update(), find() etc).
abstract class BaseActiveRecord
{
protected $_db;
protected $_table;
protected $_primary = 'id';
protected $_fields = [];
public function __construct($db)
{
$this->_db = $db;
}
public function read($id)
{
$sql = "SELECT * FROM `$this->_table` WHERE `$this->_primary` = ?";
$stmt = $this->_db->prepare($sql);
$stmt->execute([$id]);
$stmt->setFetchMode(PDO::FETCH_INTO, $this);
$stmt->fetch();
}
public function update()
{
$data = [];
$set = "";
foreach($this->_fields as $key)
{
$set .= "`$key` = :$key,";
$data[$key] = $this->{$key};
}
$set = rtrim($set, ",");
$data[$this->_primary] = $this->{$this->_primary};
$where = "$this->_primary = :$this->_primary";
$sql = "UPDATE {$this->_table} SET $set WHERE $where";
$this->_db->prepare($sql)->execute($data);
}
}
如您所見,有一些新變量:
As you can see, there are some new variables:
$_table
保存特定類中使用的表名.$_primary
保存將在find()
和update()
方法中使用的主鍵的名稱,以及id
的默認值.$_fields
是一個非常重要的屬性,它應該包含該類所有真實"屬性的列表.它將用于create()
和update()
方法
$_table
holds the table name used in the particular class.$_primary
holds the name of the primary key that will be used in thefind()
andupdate()
methods, with the default value ofid
.$_fields
is a very important property, it should contain the list of all "real" properties of this class. It will be used forcreate()
andupdate()
methods
然后只需創建實際的類,擴展您的原型類,例如 Team
Then just create actual classes, extending your prototype class, such as Team
class Team extends BaseActiveRecord
{
protected $_table = "teams";
protected $_fields = ['name', 'sname', 'logo', 'sport'];
}
如您所見,定義相當簡單 - 在這里您必須定義表和字段名稱,以便我們的自動化工作.現在!您所要做的就是簡單地調用 update()
方法!
As you can see, the definition is fairly simple - here you have to define the table and field names in order to make our automation work. And now! All you have to do is to simply call update()
method!
include 'pdo.php';
$team = new Team($pdo);
$team->read(1); // get the record from the database
$user->name = "Boston Celtics";
$user->sname = "Celtics";
$user->update(); // save the updated record.
請注意,永遠不要在每個方法內部創建新的數據庫連接.創建一次并傳遞給類的構造函數.這是如何正確連接PDO.
Note that you should never create a new database connection inside of each method. Create it once and pass into constructor of your classes. Here is how to connect with PDO properly.
這篇關于類之間共享的 PDO 交互的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!