2
\$\begingroup\$

I have one PHP file named database.php:

 try {
     $connection= new PDO(DB_DNS, DB_USER, DB_PASS);
     $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(Exception $e) {
     echo "Error: ".$e->getMessage();
     die();
}

and I have a user.php with class Users:

require_once(__DIR__."/../includes/config.php");
require_once(__DIR__."/../includes/database.php");

class User
{
    public function pronadjiSveUsere() {
        global $connection;
        $upit = $konekcija->prepare("SELECT * FROM users");
        $rezultat_upita = $upit->execute();
        return $rezultat_upita;
    }

    public function find_by_id($id = 0) {
        try {
            global $connection;
            $upit = $konekcija->prepare("SELECT * FROM users WHERE id = :id");
            $rezultat_upita = $upit->execute(array($id));
            return $rezultat_upita->fetch(PDO::FETCH_OBJ);
        } catch (Exception $e) {
            echo $e->getMessage();
            die();
        }
    }
}

So, you can see that there is a global $connection in each of the methods. Is this bad and why? If so, what would you do, as parameter passing, or with a constructor?

\$\endgroup\$
3
  • \$\begingroup\$ So, I always should do in this way: class User { public function find_by_id($id, $connection) { ..., right? \$\endgroup\$
    – PeraMika
    Commented Oct 26, 2015 at 16:58
  • 1
    \$\begingroup\$ No, I'd advice against that because: 1) There's no type-hint (I can pass an int as second argument, but you need $connection to be a PDO instance). 2) You don't want the caller to have to pass a DB connection for each method. Dependency Injection is what you really ought to be going for 3) PDO::prepare returns an instance of PDOStatement, which is reusable, your code doesn't take advantage of that fact. 4) try {} catch() { die;} is code smell: catch an exception if you know how to handle that exceptional case, if not: let the exception propagate to code that does \$\endgroup\$ Commented Oct 26, 2015 at 17:02
  • 1
    \$\begingroup\$ Posted a hasty review of your code there. Leave a comment if something is a tad unclear there \$\endgroup\$ Commented Oct 26, 2015 at 18:12

1 Answer 1

2
\$\begingroup\$

Use global scope for as little as possible. EVER.

Explicitly passing the connection it into the method is always the safe and happy. It allows for better testing by adhering to dependancy inversion principles.

You could also do it inside of the constructor if the the connection doesn't change during the life of the object, but I'm not a fan of this--I'd prefer a intitial() method to be called after instantiation or explicitly setting it with a set_connection() method.

\$\endgroup\$
4
  • \$\begingroup\$ So, I always should do in this way: class User { public function find_by_id($id, $connection) { ..., right? \$\endgroup\$
    – PeraMika
    Commented Oct 26, 2015 at 16:58
  • \$\begingroup\$ I'd put the connection as the first argument and specify the type PDO as in one of your comments on the OP \$\endgroup\$
    – Ray
    Commented Oct 26, 2015 at 17:03
  • \$\begingroup\$ @ray: it's far from fine: there's no type-hint. Each call will call PDO::prepare, creating the exact same prepared statement (not what you want) and try-catch-die is code smell, as is a method that echo's. Methods return, templates take care of output \$\endgroup\$ Commented Oct 26, 2015 at 17:04
  • \$\begingroup\$ Read my comment about the above yours about adding the type hint. The question is not about general improving the code overall, but about specifcally if they should be passing in or using a global connection. I think my word choice of 'method is fine' is poor as I was not referering to his classes method, but his suggestion of his plan to use the passing it into his method. I'm deleteing as my following comment is more clear. \$\endgroup\$
    – Ray
    Commented Oct 26, 2015 at 17:11

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.