使用这种方法有什么根本缺陷吗?
你必须明白的第一件事是$pdo
是一部分storage逻辑。这意味着,它应该只在执行以下操作的类中使用抽象数据访问,无论是 SQL 表还是集合。
让我们看看你的代码,
function somefunction(){
global $pdo;
$statement = $pdo->prepare("some query");
$statement->execute();
}
如果将来你想从 MySQL 切换到 Mongodb/MYSQL/PostgreSQL 怎么办?
那么你将不得不重写很多代码。
对于每个数据库供应商,您必须创建一个具有不同变量的单独文件。像这样
function somefunction(){
global $mongo;
return $mongo->fetch(...);
}
By using a global state, you end up with mass code duplication, because you cannot pass parameters and thus cannot change function's behavior at runtime.
现在让我们看看这个,
function somefunction($pdo){
$statement = $pdo->prepare("some query");
$statement->execute();
}
Here, $pdo
作为参数传递,因此不存在全局状态。但问题仍然存在,你最终违反了单一责任原则
如果你真的想要一些可维护、干净且易读的东西,你最好坚持使用数据映射器 http://en.wikipedia.org/wiki/Data_mapper_pattern。这是一个例子,
$pdo = new PDO(...);
$mapper = new MySQL_DataMapper($pdo);
$stuff = $mapper->fetchUserById($_SESSION['id'])
var_dump($stuff); // Array(...)
// The class itself, it should look like this
class MySQL_DataMapper
{
private $table = 'some_table';
private $pdo;
public function __construct($pdo)
{
$this->pdo = $pdo;
}
public function fetchUserById($id)
{
$query = "SELECT * FROM `{$this->table}` WHERE `id` =:id";
$stmt = $this->pdo->prepare($query);
$stmt->execute(array(
':id' => $id
));
return $stmt->fetch();
}
}
结论
无论您的项目是小还是大,您都应该始终避免所有形式的全局状态(全局变量、静态类、单例) -为了代码的可维护性
你必须记住,那$pdo
不是您业务逻辑的一部分。它是存储逻辑的一部分。这意味着,在开始使用业务逻辑执行某些操作(例如繁重计算)之前,您应该真正抽象表访问(包括 CRUD 操作)
这座桥梁将您聚集在一起data access abstraction
and computation logic
通常被称为Service
您应该始终将功能需要的事物作为参数传递
您最好停止担心您的代码并开始考虑抽象层。
最后,在开始做任何事情之前,您首先要初始化所有服务bootstrap.php
然后根据用户的输入开始查询存储($_POST
or $_GET
).
就像,
public function indexAction()
{
$id = $_POST['id']; // That could be $this->request->getPost('id')
$result = $this->dataMapper->fetchById($id);
return print_r($result, true);
}