将我的PDO连接保存为全局变量 [英] Saving my PDO connection as a global variable

查看:136
本文介绍了将我的PDO连接保存为全局变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在提出关于PDO查询的另一个问题时,我已经被告知将PDO连接对象保存为全局,以便在我调用数据库查询的各种函数中使用它。



这里是我通常使用我的PDO对象的方法:

  function somefunction(){
global $ pdo;

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

我读过的参数更多的是关于代码维护和调试,很难跟踪谁修改PDO对象和代码中的位置。其他人只是简单地拒绝使用全局变量存储PDO对象,但不能真正解释为什么全局变量是一个坏的方法。



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



使用这种方法有什么根本性的缺陷? p>

解决方案


使用此方法是否有任何根本性缺陷?


< blockquote>

你必须理解的第一件事是 $ pdo 存储的一部分逻辑。也就是说,它只能在执行抽象数据访问的类中使用,无论是SQL表还是集合。



您的代码

  function somefunction(){
global $ pdo;

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

如果你想从MySQL切换到Mongo / MSSQL / PgSQL,未来?
那么你将不得不重写很多代码。



对于每个数据库供应商,你必须创建一个具有不同变量的分隔文件。就像这样

  function somefunction(){
global $ mongo;
return $ mongo-> fetch(...);
}





通过使用全局状态,您最终会遇到质量代码复制,因为您无法传递参数,因此无法在运行时更改函数的行为。


< blockquote>

现在让我们来看看



  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(...)

//类本身,应该看起来像这样
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();
}
}



结论




  • 如果你的项目很小或者很大,你并不重要,你应该避免所有形式的全局状态(全局变量,静态类,单例) strong>为了代码可维护性


  • 您必须记住, $ pdo 不是您的业务逻辑的一部分。它是存储逻辑的一部分。这意味着,在你甚至开始使用业务逻辑,比如重型计算之前,你应该真的抽象表访问(包括CRUD操作)。


  • 数据访问抽象和计算逻辑通常称为服务

    / li>
  • 您应该始终将函数的需要作为参数传递


  • 您最好不要担心代码并开始思考抽象层。


  • 最后,在你开始做任何事情之前,首先要在 bootstrap.php ,然后根据用户输入( $ _ POST $ _ GET )开始查询存储。




就像,

  public function indexAction()
{
$ id = $ _POST ['id']; //可能是$ this-> request-> getPost('id')
$ result = $ this-> dataMapper-> fetchById($ id);

return print_r($ result,true);
}


While asking another questions about PDO queries, I've been told that saving my PDO connection object as global to use it in my various functions that call queries to my database is generally bad practice.

Here is how I generally use my PDO object:

function somefunction(){
    global $pdo;

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

The arguments I've read are more about code maintenance and debugging, where it's hard to trace who modified the PDO object and where in the code it would be. Other people just simply reject using global variables for storing the PDO object, but can't really explain why global variables are a bad approach.

However, for a small-medium projects with only one database, is there really a disadvantage to using a global variable? I usually have my connection script and my functions script separately, where the functions script will require_once() the connection script, where my PDO object is created. In this way, my connection is always established and all modifications to the PDO object are done in my connection script.

Is there any fundamental flaws in using this approach?

解决方案

Is there any fundamental flaws in using this approach?

The very first thing you have to understand, is that $pdo is a part of storage logic. That means, it should be only used inside classes that do abstract data access, be it a SQL table or a collection.

Let's look at your code,

function somefunction(){
    global $pdo;

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

What if you want to switch from MySQL to Mongo/MSSQL/PgSQL, in future? Then you will have to rewrite a lot of code.

And for each database vendor, you will have to create a separated file with different variable. Just like this

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.

Now let's look at this,

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

Here, $pdo is passed as an argument, thus there's no global state. But the problem still remains, you end up violating the Single-Responsibility Principle

If you really want something that is maintainable, clean and very readable, you'd better stick with DataMappers. Here's an example,

$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();
    }
}

Conclusion

  • It doesn't really matter if your project is small or large, you should always avoid global state in all it forms (global variables, static classes, Singletons) - For the sake of code maintainability

  • You have to remember, that $pdo is not a part of your business logic. Its a part of storage logic. That means, before you even start doing something with business logic, like heavy computations, you should really abstract table access (including CRUD operations)

  • The bridge that brings together your data access abstraction and computation logic is usually called Service

  • You should always pass the things function's need as parameters

  • You'd better stop worrying about your code and start thinking about abstraction layers.

  • And finally, before you even start doing any stuff, you'd firstly initialize all your services in bootstrap.php and then start querying storage according to user's input ($_POST or $_GET).

Just like,

public function indexAction()
{
    $id = $_POST['id']; // That could be $this->request->getPost('id')
    $result = $this->dataMapper->fetchById($id);

    return print_r($result, true);
}

这篇关于将我的PDO连接保存为全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆