12 Replies - 938 Views - Last Post: 16 July 2012 - 04:36 PM Rate Topic: -----

#1 Slice  Icon User is offline

  • D.I.C Addict


Reputation: 200
  • View blog
  • Posts: 599
  • Joined: 24-November 08

Having a class for database connection

Posted 15 July 2012 - 08:44 AM

So I'm trying to make a class to handle my database connection, while trying to focus on making it very portable for future projects. At the moment this is giving me an internal server error:

<?php

class connectDB {
	
	private $db_user,
			$db_pass,
			$db,
			$error,
			$dsn;
			
	public $pdo;
			
	public function __construct($db_user, $db_pass, $db)
	{
		$this->db_user = $db_user;
		$this->db_pass = $db_pass;
		$this->db = $db;
		$this->dsn = "mysql:host=localhost;dbname=" . $this->db;
	}
	
	public function connect()
	{	
		$user = $this->db_user; // This seemed to 
		$pass = $this->db_pass; // fix an undefined 
		$dsn = $this->dsn;	// error. Not sure why ..
		
		try
		{
			//$this->pdo = new PDO($this->dsn, $this->user, $this->pass); - undefined
			$this->pdo = new PDO($dsn, $user, $pass); // gives no error
		}
		catch (PDOException $e)
		{
			$this->error = "Connection Failed: " . $e->getMessage();
		}
	
	}
	
	public function getError(){ return $this->error; }
	
	
}


class session {

	private $email,
			$userid,
			$password,
			$firstname,
			$surname,
			$query_login,
			$query_register,
			$reg_result,
			$log_result,
			$db_user,
			$db_pass,
			$db;
			
	public function __construct($db_user, $db_pass, $db)
	{
		$this->db_user = $db_user;
		$this->db_pass = $db_pass;
		$this->db = $db;
	}
									
	public function register($email, $password, $firstname, $surname, $query)
	{
		$this->email = $email;
		$this->password = $password;
		$this->firstname = $firstname;
		$this->surname = $surname;
		$this->query_register = $query;
		
		$array = array(
			'email' => $this->email,
			'password' => hash('sha256', "mysalt" . $this->password),
			'firstname' => $this->firstname,
			'surname' => $this->surname
			);
			
		$this->connection = new connectDB($this->db_user, $this->db_pass, $this->db);
		
		$this->connection->connect();
						
		$ps = $this->connection->pdo->prepare($this->query_register); //not too sure if this is valid
			
		$this->reg_result = $ps->execute($array);
	}
	
	public function getRegResult()
	{
		return $this->reg_result;
	}
	
	
}

?>




and index.php has:
<?php
require_once("require/session.php");

error_reporting(E_ALL);

$session = new session("user","pass","database"); //database credentials

$query = "INSERT INTO users (email, password, firstname, surname) VALUES ( :email, :password, :firstname, :surname )";

$session->register("me@email.com", "password", "John", "Smith", $query);

$result = $session->getRegResult();

if($result)
{
	echo "Registration was succesful!";
}
else
{
	echo $session->getError();
}


?>



I think I've really gone off the rails here somewhere.. I'm not getting any exception errors, or any php errors in my IDE.

Sorry for the amount of code, but I have no idea where the server error is coming from. Any and all help is much appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Having a class for database connection

#2 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2505
  • View blog
  • Posts: 8,565
  • Joined: 08-August 08

Re: Having a class for database connection

Posted 15 July 2012 - 08:51 AM

I wouldn't name a class session. That may not be the source of your trouble, but it is confusing, especially if you're using $_SESSION variables.
Was This Post Helpful? 3
  • +
  • -

#3 Slice  Icon User is offline

  • D.I.C Addict


Reputation: 200
  • View blog
  • Posts: 599
  • Joined: 24-November 08

Re: Having a class for database connection

Posted 15 July 2012 - 09:31 AM

That's a good point, hadn't thought of it like that. I'll change it to something a little less familiar :P

EDIT:problem solved.

I've been working on this while I've been out on my laptop (running XAMPP on windows 7 locally with no internet connection). I copied the little I had over to my server when I get home and carried on from there. Files had some weird permissions which wouldn't let me access them. Figured it out from this apache error log:

Quote

[Sun Jul 15 17:47:58 2012] [error] [client 127.0.0.1] PHP Fatal error: Unknown: Failed opening required '/var/www/site/index.php' (include_path='.:/usr/share/php:/usr/share/pear') in Unknown on line 0


Silly XAMPP.

This post has been edited by Slice: 15 July 2012 - 10:09 AM

Was This Post Helpful? 0
  • +
  • -

#4 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 2937
  • View blog
  • Posts: 7,690
  • Joined: 08-June 10

Re: Having a class for database connection

Posted 15 July 2012 - 10:55 AM

If you’d ask me, drop the connectDB class. just instantiate PDO at the top of the script and pass it to any object that requires the connection. whether you pass the DB credentials to the connectDB object or instantiate PDO makes no difference with your code.

second, Exceptions are not errors. they work differently. you catch Exceptions where you can handle the problem. i.e. if the connection fails and you immediately catch the exception, the script would proceed execution and fail again (because there is no connection). if you enclose all your DB code in a try…catch block, a failed connection will skip all DB code and thus not produce any more errors.
Was This Post Helpful? 3
  • +
  • -

#5 Atli  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 3115
  • View blog
  • Posts: 4,675
  • Joined: 08-June 10

Re: Having a class for database connection

Posted 15 July 2012 - 12:31 PM

I would also suggest changing the name of the connectDB, if you intend on keeping it, to something else. That name sounds like a function name, in that it specifies an action, like: doSometing(), whereas class names should be more like actual names, like: SomeObject. In your case, I would consider something more like: DatabaseConnection, or perhaps DBConnect. (I prefer the longer version myself, just for clarity.) - It's also a good tradition to always use Pascal case (CamelCase starting with an upper-case letter) when naming classes. That sets it a part from the functions.


And, like Dormilich says, that class isn't altogether that useful in it's current state. It would actually be simpler to just use PDO in your session class. - I'd recommend using a Singleton class instead to handle the database connection. It's one step up from Dormilich's idea of creating the connection in the global scope and passing it into all functions/objects that need it, in that the functions/objects can simply fetch the connection themselves.
Was This Post Helpful? 3
  • +
  • -

#6 AyaneFukazawa  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 2
  • Joined: 09-July 12

Re: Having a class for database connection

Posted 15 July 2012 - 01:33 PM

I'm sure you are aware of it, but as you mentioned you wanted portability, you should not hardcode the host to localhost. Often enough you may need to connect to external databases.

Also, like Atli said, you should reconsider your naming convention for clarity.
Was This Post Helpful? 1
  • +
  • -

#7 Slice  Icon User is offline

  • D.I.C Addict


Reputation: 200
  • View blog
  • Posts: 599
  • Joined: 24-November 08

Re: Having a class for database connection

Posted 16 July 2012 - 03:33 AM

View PostDormilich, on 15 July 2012 - 11:55 AM, said:

If you’d ask me, drop the connectDB class. just instantiate PDO at the top of the script and pass it to any object that requires the connection. whether you pass the DB credentials to the connectDB object or instantiate PDO makes no difference with your code.


I did this last time but only got it to work with a global inside my class. How do I use it without globals?
Was This Post Helpful? 0
  • +
  • -

#8 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 2937
  • View blog
  • Posts: 7,690
  • Joined: 08-June 10

Re: Having a class for database connection

Posted 16 July 2012 - 04:27 AM

well, you pass it as parameter:
class Test
{
    private $pdo;

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

    // ...
}

try
{
    $pdo  = new PDO($dsn, $login, $pass, $options);
    $test = new Test($pdo);
    $test->doSomethingWithPdo();
}
catch (PDOException $e)
{
    echo "DB Error";
    send_error_mail($e->getMessage());
}

Was This Post Helpful? 0
  • +
  • -

#9 Slice  Icon User is offline

  • D.I.C Addict


Reputation: 200
  • View blog
  • Posts: 599
  • Joined: 24-November 08

Re: Having a class for database connection

Posted 16 July 2012 - 04:54 AM

Would PDO not then need to be initialized every time we start a new object?
Was This Post Helpful? 0
  • +
  • -

#10 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 2937
  • View blog
  • Posts: 7,690
  • Joined: 08-June 10

Re: Having a class for database connection

Posted 16 July 2012 - 05:20 AM

depends on where (in what scope) you start a new object. if it’s always in the same (e.g. the global scope), it doesn’t matter, if it’s different scopes, use a service provider (e.g. the Singleton Atli mentioned).
Was This Post Helpful? 0
  • +
  • -

#11 Slice  Icon User is offline

  • D.I.C Addict


Reputation: 200
  • View blog
  • Posts: 599
  • Joined: 24-November 08

Re: Having a class for database connection

Posted 16 July 2012 - 05:53 AM

I've made some changes to what I first had.

So in my class SessionControl (changed name for clarity), I have a constructor that makes a new connection.
	public function __construct($db_user, $db_pass, $db)
	{
		$this->db_user = $db_user;
		$this->db_pass = $db_pass;
		$this->db = $db;
		$this->connection = new DatabaseConnection($this->db_user, $this->db_pass, $this->db);
		$this->connection->connect();		
	}



and my DatabaseConnection class looks like:
class DatabaseConnection {
	
	private $db_user,
			$db_pass,
			$db,
			$dsn;
			
	public $pdo;
			
	public function __construct($db_user, $db_pass, $db)
	{
		$this->db_user = $db_user;
		$this->db_pass = $db_pass;
		$this->db = $db;
		$this->dsn = "mysql:host=localhost;dbname=" . $this->db;
	}
	
	public function connect()
	{	
		$user = $this->db_user; // This seemed to 
		$pass = $this->db_pass; // fix an undefined 
		$dsn = $this->dsn;		// error. Not sure why ..
		
		try
		{
			//$this->pdo = new PDO($this->dsn, $this->user, $this->pass); - undefined
			$this->pdo = new PDO($dsn, $user, $pass); // no undefined error
		}
		catch (PDOException $e)
		{
			echo "Connection Failed: " . $e->getMessage();
		}
	
	}
		
}	




This way the class SessionControl has database access via $this->connection , and in any page I need to use my SessionContol class, all I have to do is:
<?php
$SesControl = new SessionControl($user, $pass, $db); 
$SesControl->checkLogin(); //or register/login
?>



Is this method not easier? I know it's a lot of effort to have the class for connecting but it means only one line of code on any page wanting to use the ControlSession. Are there any security disadvantages here or is it mainly preference / bad practice?
Was This Post Helpful? 0
  • +
  • -

#12 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 2937
  • View blog
  • Posts: 7,690
  • Joined: 08-June 10

Re: Having a class for database connection

Posted 16 July 2012 - 06:05 AM

View PostSlice, on 16 July 2012 - 02:53 PM, said:

Is this method not easier?

not at all. your SessionControl class would have to know the DB credentials, which is not its responsibility. the database credentials are the sole responsibility of the DatabaseConnection class. and in the end it’s even more complicated than instantiating PDO by hand (which would need only the login, password and database name as variables as well).

it were sensible, if the DatabaseConnection class would get the DB credentials from a configuration file.
Was This Post Helpful? 2
  • +
  • -

#13 calebjonasson  Icon User is offline

  • $bert = new DragonUnicorn(); $bert->rawr();
  • member icon

Reputation: 198
  • View blog
  • Posts: 974
  • Joined: 28-February 09

Re: Having a class for database connection

Posted 16 July 2012 - 04:36 PM

Along with the previous recommendation of keeping connection information in a config file. You should:
  • Keep the config file outside of the hosting directory
  • Make your connection class extend PDO or Mysqli
  • I like to use a singleton wrapper to recycle connections and information. It's not a bad idea and will help you log and monitor errors internally to the application.

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1