Hi everyone hope you can help me with this issue, I'm trying to make a login system that is object oriented so I have the following classes:

  • MySQLDB: Peforms all database operations, adding/removing members, checking passwords and usernames, also performing querys.
  • Session: Performs Session actions(log in/out, keeping track of guests )


The Session class needs the MySQLDB class but DOES NOT inherit it, so after I define the MySQLDB class I also instance it as a global variable ($database), then I define the Session class, I know the basics of OOP and stuff, but the part which confuses me is that if the database object should be instanced within the Session class definition (as a member of Session) or outside with global scope (as an independent object), I think it should be instanced within the session class, but the login example which I'm being based initializes the database outside of session and redeclares it as global each time a method of session requires it, this is the original script I'm using as a guide, a bit old but very clear (except for that hehe) Login System also here's my code it's a simplified version to better illustrate my point.

database.php

<?php
   class MySQLDB
   {
       private $link;
       private $etcetera;  
   }
   //Instanced outside of Session
   global $database;
   $database = new MySQLDB(); 
?>

session.php

<?php
   include "database.php"; 
   class session 
   {
       /*OR instance the database object here so it can be accessed from the diffrent functions*/
       private $database= new MySQLDB();
      
       function login($member,$password)
       {
           global $database; //or here?, every time a function needs it 
       }
   }
?>

Regards,Triztian

Personally I think the best implementation is to use the Singleton design pattern and not the global keyword in this instance. So your code for MYSQLDB class would be:

class MYSQLDB
{
  private static instance = null;
  // private constructor and clone methods
  private __construct()
  {
    // initialise any variables here
  }
  private __clone()
  {
  }
  public static function getInstance()
  {
    // this code ensures there is only ever at most one instance of this class
    if (instance == null)
        instance = new MYSQLDB();
    return instance;
  }
  public function validateLogin($member, $password)
  {
     // check the member/password details in the database...
  }
}

Then in your session class you call the getInstance method to initialise your database accessor like so:

class session
{
  private $database;
  public __constuct()
  {
    $this->database = MYSQLDB::getInstance();
  }
  function login($member, $password)
  {
    // now you can use your database variable like so:
    $this->database->validateLogin($member, $password);
  }
}

I believe this method is cleaner than the global approach, but I'll leave it up to you to decide what's best for your application.

Personally I think the best implementation is to use the Singleton design pattern and not the global keyword in this instance. So your code for MYSQLDB class would be:

class MYSQLDB
{
  private static instance = null;
  // private constructor and clone methods
  private __construct()
  {
    // initialise any variables here
  }
  private __clone()
  {
  }
  public static function getInstance()
  {
    // this code ensures there is only ever at most one instance of this class
    if (instance == null)
        instance = new MYSQLDB();
    return instance;
  }
  public function validateLogin($member, $password)
  {
     // check the member/password details in the database...
  }
}

Then in your session class you call the getInstance method to initialise your database accessor like so:

class session
{
  private $database;
  public __constuct()
  {
    $this->database = MYSQLDB::getInstance();
  }
  function login($member, $password)
  {
    // now you can use your database variable like so:
    $this->database->validateLogin($member, $password);
  }
}

I believe this method is cleaner than the global approach, but I'll leave it up to you to decide what's best for your application.

Hi, thank you for your reply.
Even though I understand the concept of the singleton Design pattern and I do think that that's the better approach would you mind clarifying some aspects of the code, for example.

  • What's the use of "public static function"?
  • How does it ensure that only on instance of the object is created, does it destroy other objects of the same class if they are created?
  • Why "static instance"?

Hope you don't mind it's a bit confusing.

public static function: this declaration indicates that the function is public so can be called from outside the class (for example, you can call the getInstance function from the session class. The static part of the declaration indicates that it is not called directly by a MYSQLDB instance variable. Instead, you call it like so:

$database = MYSQLDB::getInstance();

Because the constructor and clone functions have been made private, they can't be called from outside the class. This means that the only way to get an object of type MYSQLDB is by calling the getInstance function. This function creates an instance if it hasn't yet been created but if it has it is simply returned. Therefore there can only ever be one instance of the object.

Sorry, there are a couple of errors in my code for the MYSQLDB class, I was getting confused with C# syntax. The corrections are:

// this instantiates a class variable called $instance to a null value
private static $instance = null;
//...
public static function getInstance()
{
  // what we are doing here is checking whether the instance has been created
  // if it hasn't it is created
  if (MYSQLDB::instance == null)
    MYSQLDB::instance = new MYSQLDB();
  // now we return it
  return MYSQLDB::instance;
}

I hope this has helped, please let us know if you are still unsure of what I have described.

Darkagn, do I miss something here.
I think you forgot else clause. I stand to be corrected though.
I think if you call the function twice it wont return anything as the MYSQLDB::instance will not be null. Also in C++ you must Delete the instance once used but I think PHP does that for you.

public static function getInstance()
  {
    // this code ensures there is only ever at most one instance of this class
    if (instance == null){
        instance = new MYSQLDB();
		return instance;
	}
	else{
		return instance;
	}
  }

If the $instance variable is null, it is created then returned. If it is not null, it is simply returned without being re-created. Your example is equivalent however. Note that my code does not have curly braces for the if-statement, so only the first line after the condition is skipped if the condition is false.

Hi, thanks a lot for your help, cleared my doubts and learned something new, keep up the good work darkagn.

Regards, Triztian.

If the $instance variable is null, it is created then returned. If it is not null, it is simply returned without being re-created. Your example is equivalent however. Note that my code does not have curly braces for the if-statement, so only the first line after the condition is skipped if the condition is false.

I get it,
it is little tricky until you consider the "no brace" thing and static behaviour :twisted:
Thanks for explanations

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.