在询问有关PDO查询的其他问题时,我被告知将我的PDO连接对象保存为全局,以便在我调用数据库查询的各种函数中使用它通常是不好的做法。
以下是我通常使用PDO对象的方法:
function somefunction(){
global $pdo;
$statement = $pdo->prepare("some query");
$statement->execute();
}
我读过的论点更多的是代码维护和调试,很难跟踪修改PDO对象的人以及代码的位置。其他人只是拒绝使用全局变量来存储PDO对象,但无法真正解释为什么全局变量是一种糟糕的方法。
但是,对于只有一个数据库的中小型项目,使用全局变量真的有缺点吗?我通常单独使用连接脚本和函数脚本,其中函数脚本require_once()连接脚本,我的PDO对象创建在那里。通过这种方式,我的连接始终建立,并且对PDO对象的所有修改都在我的连接脚本中完成。
使用这种方法有任何根本缺陷吗?
答案 0 :(得分:10)
使用这种方法有任何根本缺陷吗?
您必须首先了解的是,$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
的桥梁通常称为服务
您应该始终将函数的需要作为参数传递
您最好不要担心代码并开始考虑抽象层。
最后,在你开始做任何事情之前,你首先要在bootstrap.php
中初始化所有服务,然后根据用户的输入($_POST
或{{1}开始查询存储}})。
就像,
$_GET
答案 1 :(得分:3)
对于一个小小的项目来说,全球使用不会太大。当项目规模开始增长时,事情开始变得糟糕。
如果somefunction()
使用5个全局变量在其中有300行,那么查看代码的人不会知道该函数使用外部变量,除非他们通过它查找全局变量。
另外,不使用全局变量很容易......为什么呢?
function somefunction( PDO $pdo ){
$statement = $pdo->prepare("some query");
$statement->execute();
}
修改强>
show_profile.php
是你的控制者。您的控制器收集视图的所有数据并加载视图。这是一个非常简化的版本。
require( 'functions.php' );
$db = new PDO();
$user = get_user( $db, $user_id );
require( 'view.php' );