将我的 PDO 连接保存为全局变量 [重复]

2024-01-14

在询问有关 PDO 查询的另一个问题时,我被告知将 PDO 连接对象保存为全局对象以在调用数据库查询的各种函数中使用它通常是不好的做法。

以下是我通常如何使用 PDO 对象:

function somefunction(){
    global $pdo;

    $statement = $pdo->prepare("some query");
    $statement->execute();
}

我读到的论点更多是关于代码维护和调试,很难跟踪谁修改了 PDO 对象以及它在代码中的位置。其他人只是简单地拒绝使用全局变量来存储 PDO 对象,但无法真正解释为什么全局变量是一个不好的方法。

但是,对于只有一个数据库的中小型项目,使用全局变量真的有缺点吗?我通常分别拥有连接脚本和函数脚本,其中函数脚本将 require_once() 连接脚本,其中创建我的 PDO 对象。这样,我的连接始终会建立,并且对 PDO 对象的所有修改都在我的连接脚本中完成。

使用这种方法有什么根本缺陷吗?


使用这种方法有什么根本缺陷吗?

你必须明白的第一件事是$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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将我的 PDO 连接保存为全局变量 [重复] 的相关文章

  • 将 Google 信任徽章添加到 Magento

    我正在尝试将 Google Trust Badge 添加到我的 magento 商店 我尝试在 Magento 网站上搜索扩展程序 但找不到 我是否需要将以下代码粘贴到产品和结账页面 还是必须对其进行更改 如果有人能引导我走向正确的方向 我
  • 如何解码 eval( gzinflate( base64_decode(

    我已将此代码注入到我的网站中 如何解码尾随字符串 我需要知道发生了什么以及其背后的代码是什么 这应该输出将被执行的代码eval 我希望这就是您正在寻找的
  • 强制 Composer 下载 git repo 而不是 zip

    我对作曲家有一些问题 require php gt 5 3 2 kriswallsmith buzz 0 7 Repo https github com kriswallsmith Buzz tree v0 7 https github c
  • 如何仅使用 PHP5 RecursiveDirectoryIterator 类递归显示具有特定文件类型的文件夹和子文件夹

    您好 我正在尝试使用 FilterIterator 上的扩展来获取 RecursiveDirectoryIterator 类 但由于某种原因 它仅在根目录上进行迭代 我的代码是这样的 class fileTypeFilter extends
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • 如何使用 PHP 对字符串进行 rot13 处理?

    我有一个很大的 php 代码 我想手动对其进行编码和解码 我的问题是 php 代码里面有很多单引号和双引号 因此我在使用时出现错误str rot13 功能如下 那么正确的语法是什么以及如何使用下面的函数进行编码 str rot13 That
  • 检查 $_POST 数据

    我正在对表单进行一些垃圾邮件检查 下面的代码在我的本地主机上正常工作 如果为 true 则重定向到 google com 但是 当它在生产服务器上时却不起作用 执行脚本的其余部分并且不重定向到 Google com if POST SERV
  • php curl 使用 GET 发送变量 奇怪的结果

    我正在尝试调用远程站点上页面中的网址 决定使用curl 在远程站点上 url 变量显示为 REQUEST Array var1 gt val1 amp var2 gt val2 amp var3 gt val3 被调用的url是 http
  • setcookie with expire=0 浏览器关闭后不会过期

    我使用setcookie来制作一个过期 0的cookie 从 PHP 文档来看 link http php net manual en function setcookie php cookie 过期的时间 这是一个 Unix 时间戳 所以
  • PHP 通过 SSL 连接到 MS SQL

    我想要实现的目标非常简单 我想通过安全连接从 PHP 脚本连接到外部 MS SQL 数据库 然而 这已被证明是有问题的 到目前为止 经过三个小时的研究 我不知所措 客户端的平台是Ubuntu 这意味着我无法使用SQLSRV 安全连接已经在不
  • AWS-PHP-SDK / SNS 直接寻址返回错误

    您好 我正在使用 Laravel 4 设置来利用 AWS SNS 向我的 iOS 设备发送推送消息 从 AWS 控制台向我的设备发布命令效果很好 然后我尝试从 PHP sns AWS get sns sns gt publish array
  • 如何使用 PHP 构建正确的 SOAP 请求

    我需要格式化 构建此 SOAP 服务 的请求 http api notificationmessaging com NMSOAP NotificationService wsdl http api notificationmessaging
  • CakePHP 视图包括其他视图

    我有一个 CakePHP 应用程序 在某些时候会显示带有产品媒体 图片或视频 的视图 我想知道是否有某种方式可以包含另一个威胁视频或威胁图片的视图 具体取决于标志 我想将这些 小视图 用于其他几个目的 所以它应该 像 蛋糕组件一样 以便重用
  • 访客模式如何不违反开放/封闭原则?

    来自维基百科 这个想法是 一旦完成 类的实现只能修改为 纠正错误 新的或更改的功能将需要创建不同的类 该类可以通过继承重用原始类的代码 据我了解 访问者模式是一种强大的技术 可以通过使用双重分派来遍历实现相同接口的相似但不同的对象 在我的一
  • Xdebug V3 不会停止 VSCode 中的断点

    我正在尝试使用 VSCode 在 XAMPP 上进行调试 但没有成功 我知道有很多关于这个的问题 我已经尽了一切努力 但仍然行不通 我的 xdebug 扩展确实有一件奇怪的事情 我目前使用 PHP v7 4 12 和 Xdebug 版本 3
  • 用于将 cython 中的许多 C++ 类包装到单个共享对象的项目结构

    我在文档 邮件列表和这个问题在这里 https stackoverflow com questions 10300660 cython and distutils 但我想得到一个更直接的答案来解决我的具体情况 我正在通过尝试一点一点地包装我
  • 使用 PHP/linux 将文件合并为单个 PDF

    我正在研究如何将多个 PDF 合并为一个 PDF 我正在寻找一个图书馆可靠且坚固尽可能 最好有一个库可以保留书签 鬼脚本 http pages cs wisc edu ghost 可以在保存书签的位置进行连接 但我遇到了麻烦 在一种情况下它
  • 委托给子组件的模式

    在我正在工作的产品中 非常基本的场景之一是类的序列化 通常 要序列化的类会在其子组件上调用序列化 例如如果有一个类 s t 班级 A B C D 那么A Pack会调用pack B C D 上的函数 由于有很多这样的类 因此必须一遍又一遍地
  • 使用值填充的 Symfony2 自定义字段类型

    这是先前问题的后续问题Symfony2 自定义表单类型或扩展 https stackoverflow com questions 24079288 symfony2 custom form type or extension 我正在尝试为订
  • docker 中的 php Curl 冲突 CURLOPT_FILE 和 CURLOPT_RETURNTRANSFER

    当我使用curl时CURLOPT FILE and CURLOPT RETURNTRANSFER选项 文件为空 没有任何curl错误 fp fopen saveTo w ch curl init fileUrl curl setopt ch

随机推荐