PHP 将 MySql 查询与 类 分离
PHP decouple MySql queries from classes
我创建的所有 classes 似乎都充满了包含 MySql 查询的方法。我决定尝试一下脱钩。下面是我的基础 class Customer
和我的存储库 class CustomerRepository
,如果需要,它们会传递给构造函数。方法很基础,customer中的save
方法
例如在 CustomerRepository
中调用 create
方法。客户 class 现在可读性更强了,但代价是什么?我编写了一个完整的其他 class 只是为了执行 MySql 查询,我本可以在 Customer
class 中的 create
方法中开始查询。我正在努力寻找一个现实世界中的解耦示例,它适用于这种情况,因为它与工作项目有关。我在这里找到的示例 Proper Repository Pattern Design in PHP?(虽然很棒)似乎过于复杂。我的问题是:我是否正确解耦?当现实世界需要快速且有点脏的代码来尽快实现业务目标时,甚至有必要进行解耦吗?
<?php
/*
CRUD
create, read, update, delete
*/
class Customer {
public $CustomerRepository;
public $id;
public $first_name;
public $last_name
public $email;
public $phone;
public function __construct( CustomerRepository $CustomerRepository = null ) {
if( !is_null( $CustomerRepository ) {
$this->CustomerRepository = $CustomerRepository;
}
}
public function save() {
return $this->CustomerRepository->create(
$this->first_name,
$this->last_name,
$this->email,
$this->phone
);
}
public function find() {
return $this->CustomerRepository->read( $this->id );
}
public function edit() {
return $this->CustomerRepository->update(
$this->first_name,
$this->last_name,
$this->email,
$this->phone,
$this->id
);
}
public function remove() {
return $this->CustomerRepostitory->delete( $this->id );
}
public function populate( $id ) {
$customer = $this->find( $id );
$this->id = $customer['id'];
$this->first_name = $customer['first_name'];
$this->last_name = $customer['last_name'];
$this->email = $customer['email'];
$this->phone = $customer['phone'];
}
}
class CustomerRepository {
private $Database;
public function __construct() {
if( is_null( $this->Database ) {
$this->Database = new Database();
}
}
public function create( $first_name, $last_name, $email, $phone ) {
$this->Database->query( 'INSERT INTO customers( first_name, last_name, email, phone )
VALUES( :first_name, :last_name, :email, :phone )' );
$this->Database->bind( ':first_name', $first_name );
$this->Database->bind( ':last_name', $last_name );
$this->Database->bind( ':email', $email );
$this->Database->bind( ':phone', $phone );
return $this->Database->getLastID();
}
public function read( $id ) {
$this->Database->query( 'SELECT * FROM customers WHERE id = :id LIMIT 1' );
$this->Database->bind( ':id', $id ):
return $this->Database->single();
}
public function update( $first_name, $last_name, $email, $phone, $id ) {
$this->Database->query( 'UPDATE customer SET
first_name = :first_name,
last_name = :last_name,
email = :email,
phone = :phone WHERE id = :id' );
$this->Database->bind( ':first_name', $first_name );
$this->Database->bind( ':last_name', $last_name );
$this->Database->bind( ':email', $email );
$this->Database->bind( ':phone', $phone );
$this->Database->bind( ':id', $id );
return $this->Database->execute();
}
public function delete( $id ) {
$this->Database->query( 'DELETE FROM customers WHERE id = :id LIMIT 1' );
$this->Database->bind( ':id', $id ):
return $this->Database->execute();
}
}
正如大家已经在此处建议的那样,您需要实施 ORM。看这题选择:Good PHP ORM Library?
如果您仍然不想使用 ORM,您将需要自己实现同样的事情,这将比使用 ready-to-go ORM 花费更多的时间。您可以实施工作单元(http://martinfowler.com/eaaCatalog/unitOfWork.html
) 和 Repository (http://martinfowler.com/eaaCatalog/repository.html) 模式来构建您自己的 ORM。
我创建的所有 classes 似乎都充满了包含 MySql 查询的方法。我决定尝试一下脱钩。下面是我的基础 class Customer
和我的存储库 class CustomerRepository
,如果需要,它们会传递给构造函数。方法很基础,customer中的save
方法
例如在 CustomerRepository
中调用 create
方法。客户 class 现在可读性更强了,但代价是什么?我编写了一个完整的其他 class 只是为了执行 MySql 查询,我本可以在 Customer
class 中的 create
方法中开始查询。我正在努力寻找一个现实世界中的解耦示例,它适用于这种情况,因为它与工作项目有关。我在这里找到的示例 Proper Repository Pattern Design in PHP?(虽然很棒)似乎过于复杂。我的问题是:我是否正确解耦?当现实世界需要快速且有点脏的代码来尽快实现业务目标时,甚至有必要进行解耦吗?
<?php
/*
CRUD
create, read, update, delete
*/
class Customer {
public $CustomerRepository;
public $id;
public $first_name;
public $last_name
public $email;
public $phone;
public function __construct( CustomerRepository $CustomerRepository = null ) {
if( !is_null( $CustomerRepository ) {
$this->CustomerRepository = $CustomerRepository;
}
}
public function save() {
return $this->CustomerRepository->create(
$this->first_name,
$this->last_name,
$this->email,
$this->phone
);
}
public function find() {
return $this->CustomerRepository->read( $this->id );
}
public function edit() {
return $this->CustomerRepository->update(
$this->first_name,
$this->last_name,
$this->email,
$this->phone,
$this->id
);
}
public function remove() {
return $this->CustomerRepostitory->delete( $this->id );
}
public function populate( $id ) {
$customer = $this->find( $id );
$this->id = $customer['id'];
$this->first_name = $customer['first_name'];
$this->last_name = $customer['last_name'];
$this->email = $customer['email'];
$this->phone = $customer['phone'];
}
}
class CustomerRepository {
private $Database;
public function __construct() {
if( is_null( $this->Database ) {
$this->Database = new Database();
}
}
public function create( $first_name, $last_name, $email, $phone ) {
$this->Database->query( 'INSERT INTO customers( first_name, last_name, email, phone )
VALUES( :first_name, :last_name, :email, :phone )' );
$this->Database->bind( ':first_name', $first_name );
$this->Database->bind( ':last_name', $last_name );
$this->Database->bind( ':email', $email );
$this->Database->bind( ':phone', $phone );
return $this->Database->getLastID();
}
public function read( $id ) {
$this->Database->query( 'SELECT * FROM customers WHERE id = :id LIMIT 1' );
$this->Database->bind( ':id', $id ):
return $this->Database->single();
}
public function update( $first_name, $last_name, $email, $phone, $id ) {
$this->Database->query( 'UPDATE customer SET
first_name = :first_name,
last_name = :last_name,
email = :email,
phone = :phone WHERE id = :id' );
$this->Database->bind( ':first_name', $first_name );
$this->Database->bind( ':last_name', $last_name );
$this->Database->bind( ':email', $email );
$this->Database->bind( ':phone', $phone );
$this->Database->bind( ':id', $id );
return $this->Database->execute();
}
public function delete( $id ) {
$this->Database->query( 'DELETE FROM customers WHERE id = :id LIMIT 1' );
$this->Database->bind( ':id', $id ):
return $this->Database->execute();
}
}
正如大家已经在此处建议的那样,您需要实施 ORM。看这题选择:Good PHP ORM Library?
如果您仍然不想使用 ORM,您将需要自己实现同样的事情,这将比使用 ready-to-go ORM 花费更多的时间。您可以实施工作单元(http://martinfowler.com/eaaCatalog/unitOfWork.html ) 和 Repository (http://martinfowler.com/eaaCatalog/repository.html) 模式来构建您自己的 ORM。