1

I'm facing some doubts in PHP database connections. Since I can't just put a large try/catch/finally block on my method (Java style), what's the best approach to properly closing all connections and prepared statements when size/logic tends to increase? Considering the next method, is everything done right?

public function createRegister($register) {
        $this->openConnection();

        $query = "INSERT INTO register (username, password, email, confirmationToken) VALUES (?, ?, ?, ?)";
        $result = $this->mysqli->query($query);

        if ($statement = $this->mysqli->prepare($query)) {  
            $statement->bind_param("ssss", $register->username, $register->passwordHash, $register->email, $register->confirmationToken);

            if (!$statement->execute()) {
                $this->closeConnection();
                throw new DAOException("Failed to execute statement: " . $statement->error);
            }

            $statement->close();

        } else {
            $this->closeConnection();
            throw new DAOException("Failed to prepare statement: " . $this->mysqli->error);
        }

        $this->closeConnection();
    }
Rui
  • 5,900
  • 10
  • 38
  • 56
  • 1
    do you really want to open/close connection for each query? and why are you mixing code for different layers? you should encapsulate the query execution into a separate function.. – Karoly Horvath Feb 28 '12 at 18:13
  • @yi_H: Excellent point. In my response, I mentioned the ability to recycle connections via singleton/factory patterns. – Mike Purcell Feb 29 '12 at 21:28

1 Answers1

0

You can still use try/catch in PHP:

public function createRegister($register) {

    $this->openConnection();

    $query = "INSERT INTO register (username, password, email, confirmationToken) VALUES (?, ?, ?, ?)";

    try {

        // This line is not needed
        // $result = $this->mysqli->query($query);

        if ($statement = $this->mysqli->prepare($query)) {

            $statement->bind_param("ssss", $register->username, $register->passwordHash, $register->email, $register->confirmationToken);

            if (!$statement->execute()) {                   
                throw new DAOException("Failed to execute statement: " . $statement->error);
            }

            $statement->close();

        } else {
            throw new DAOException("Failed to prepare statement: " . $this->mysqli->error);
        }
    } catch (Exception $e) {

        if ((isset($statement)) && (is_callable(array($statement, 'close')))) {
            $statment->close();
        }

        $this->closeConnection();

        throw $e;
    }

    $this->closeConnection();
}

This works well for establishing a connection for one specific task, but what if you want to share the same connection for multiple tasks that also need access to the same schema? You may want to consider a more advanced solution using a singleton/factory pattern for creating and access database connections. I posted such an example as a solution to another question. It is a bit more advanced but once you get your head around it, it is more performant.

Community
  • 1
  • 1
Mike Purcell
  • 19,847
  • 10
  • 52
  • 89