使用这种方法有什么根本缺陷吗?
您必须了解的第一件事是,这$pdo
是存储逻辑的一部分。这意味着,它只能在执行抽象数据访问的类中使用,无论是 SQL 表还是集合。
让我们看看你的代码,
function somefunction(){
global $pdo;
$statement = $pdo->prepare("some query");
$statement->execute();
}
如果你将来想从 MySQL 切换到 Mongo/MSSQL/PgSQL 怎么办?然后你将不得不重写很多代码。
对于每个数据库供应商,您必须创建一个具有不同变量的单独文件。像这样
function somefunction(){
global $mongo;
return $mongo->fetch(...);
}
通过使用全局状态,您最终会出现大量代码重复,因为您无法传递参数,因此无法在运行时更改函数的行为。
现在让我们看看这个,
function somefunction($pdo){
$statement = $pdo->prepare("some query");
$statement->execute();
}
在这里,$pdo
作为参数传递,因此没有全局状态。但是问题仍然存在,你最终违反了单一责任原则
如果你真的想要一些可维护、干净且可读性强的东西,你最好坚持使用DataMappers。这是一个例子,
$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
和computation logic
通常称为服务的桥梁
您应该始终将 things 函数的需要作为参数传递
你最好停止担心你的代码,开始考虑抽象层。
最后,在你开始做任何事情之前,你首先要初始化你的所有服务,bootstrap.php
然后根据用户的输入($_POST
或$_GET
)开始查询存储。
就像,
public function indexAction()
{
$id = $_POST['id']; // That could be $this->request->getPost('id')
$result = $this->dataMapper->fetchById($id);
return print_r($result, true);
}