0

Let's pretend I have a database.php file which contains a persistent access to the database.

<?php
$database = new PDO('mysql:host=xxx', "xxx", "xxx", array(
    PDO::ATTR_PERSISTENT => true
));
?>

Every time I want to query the database within a controller, what should I do?

1/ Use the global keyword to get my global $database variable

<?php

include '../app/config/Database.php';

function getLastOfTheWeek()
{
    global $database;
    $database->query('SELECT * FROM `xxx`');
    ...
}
?>

2/ Include database.php within the function

<?php

function getLastOfTheWeek()
{
    include '../app/config/Database.php';
    $database->query('SELECT * FROM `xxx`');
    ...
}
?>

3/ Give this man some doc, he needs it

Or both are evil anyway, and I should use another method.

9
  • This isn't so much about global versus include, this is about instantiating a new PDO connection instance every time versus re-using the same connection. Commented Oct 23, 2017 at 17:27
  • I think you should not mix up your business layer with controller layer. Commented Oct 23, 2017 at 17:27
  • 1
    Use a DIC stackoverflow.com/questions/2255771/… Commented Oct 23, 2017 at 17:28
  • @bassxzero the "DIC" in the accepted answer is terrible. It's the opposite of how DI should work. Commented Oct 23, 2017 at 18:05
  • @ishegg so go answer the question yourself. I'm just pointing him in the right direction. Hopefully he will google around instead of copying and pasting. Commented Oct 23, 2017 at 18:06

2 Answers 2

2
  1. Global state is bad.
  2. Repeatedly creating DB connections is bad.

Good:

$dbh = new PDO (...);

function doSomething($dbh) {
  $dbh->query(...);
}

OK:

class Something {
  protected $dbh;

  public function __construct($db_config) {
    $this->dbh = new PDO($db_config); // still bad
  }

  public function doSomething() {
    $this->dbh->query();
  }
}

God Tier:

class Something {
  protected $dbh;

  public function __construct(PDO $dbh) {
    $this->dbh = $dbh;
  }

  public function doSomething() {
    $this->dbh->query();
  }
}

$dbh = new PDO(...);
$s = new Something($dbh);
$s->doSomething;

See: http://www.phptherightway.com/#dependency_injection

Sign up to request clarification or add additional context in comments.

4 Comments

A good answer! ;-) Just a note though: the "OK" version I would directly entitle as "BAD" (regarding config array and tight coupling): The Clean Code Talks - Don't Look For Things! and James Mallison - Dependency Injection and Dependency Inversion in PHP.
Let's pretend I have a basic website, with index.php, home.php, contact.php... All of them needs database connection. We choose the "God Tier" solution, then where the PDO instance will be made? In order to re-use the same databse connection any time?
In the ideal situation you don't have a 1:1 mapping of PHP files and pages. You have an application with a request router (eg: FastRoute) and the application is built from the inside out with DI.
Do you have an example?
1

In this simplified example, the global would be better performance assuming you have multiple functions or function calls as the global would re-use the same connection.

However, this does not mean that including Database.php multiple times is always going to be slower. Assuming you have opcache enabled, including the same file multiple times will have very little overhead. The problem is that you are opening a new PDO connection every time you include this file because of how your code is written.

There are a lot of other solutions that do not involve using a global. DI containers are often used to resolve dependencies at the start of an application. The singleton design pattern could also be beneficial if you always want to re-use the same connection.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.