tags:

views:

218

answers:

2

Below is a very basic example of the trouble I am having.

Now why must I use $session = new Session(); in the database.class.php file when in my system the files are included in a way that it would be visible already.

In other words I cannot call $session = new Session(); outside of any other classes, to make it work in other classes I have to call create a new objectof the session class in every class I want to use it in, how can I avoid this and make it work without doing that?

// Session.class.php
class Session{

    public function __construct()
    {
     session_start();
    }

    public function set($name, $value)
    {
     $_SESSION[$name] = $value;
    }
}

...

// Database.class.php
class Database{

    public static function mysql_query_2($query)
    {
     if ($session->get('user_role') == 10){
      $_SESSION['queries']++;
     }
     return mysql_query($query);
    }
}
+2  A: 

First and foremost, your Session class should be a singleton - the reason is that multiple calls to session_start() will get you nothing but problems (session id gets regenerated)

So...

/**
 * Session singleton class
 */
class Session
{
    // prevents object instanciation ($obj = new Session())
    protected function __construct() {
        session_start();
    }

    // prevents object cloning
    protected function __clone() {}

    public static function getInstance()
    {
     static $instance = null;
     if ($instance == null)
      $instance = new Session();
     return $instance;
    }

    // rest of the code
}

To use it you simply call:

$sess = Session::getInstance();
$sess->doSomething();

or simply

Session::getInstance()->doSomething();

Anywhere you need to use the session class.

Update: - I see you probably don't grasp the concept of singletons yet, so here's a proper wikipedia link 8)

jcinacio
You beat me to it and you provided an example. +1
MitMaro
You have some errors in your singleton though, you are not returning the instance.
MitMaro
yep, that's fixed - coffee time i guess 8)
jcinacio
getInstance() needs to be a static function
Josh
thanks, I will add this in and for my question, I am trying to start the new object 1 time in the header part of my script but then in class files that are included, it is requiring me to start a new object everytime, like a scope issue, do you know how I can fix that?
jasondavis
@jasondavis: Could you provide more code in your question. A singleton should fix your problem, unless we are still mis understanding it.
MitMaro
I will update the answer with a better explanation, but you don't instantiate singleton objects - there can be only one, and you just get it's instance.
jcinacio
+1  A: 

If I understand your problem correctly, one solution to your problem is to use a Singleton.

final class Singleton {

    protected static $_instance;

    // Singleton can't be constructed or cloned
    protected function __construct(){ }  
    protected function __clone() { }

    // Create an instance if necessary and return an instance.
    public static function getInstance(){
      if( self::$_instance === NULL ) {
        session_start();
        self::$_instance = new self();
      }
      return self::$_instance;
    }

    public function set($name, $value){
        $_SESSION[$name] = $value;
    }
}

In index.php you would have:

$session = Session::getInstance();
$session->get();

Then in your Database class you would have:

// Database.class.php
class Database{

    public static function mysql_query_2($query)
    {
        if (Session::getInstance()->get('user_role') == 10){
                $_SESSION['queries']++;
        }
        return mysql_query($query);
    }
}

You would only ever create one instance of the Session class (which is what I think your looking for). Then when you need the Session class somewhere else (ie your Database class) you just call Session::getInstance() again. There is only one instance of Session ever created and you can use it globally across your script.

MitMaro
thanks for the code, this is probably the only solution but I will ask anyways, is it possible to call something like $session = new $session(); in for instance an index.php file and then be able to use it's methods in other classes or any other file that is included into the index file without basicly creating a new instance in every file?
jasondavis
I updated my answer but it doesn't really answer your question here. You could use the $GLOBALS [ http://us2.php.net/manual/en/reserved.variables.globals.php ] but a Singleton is much better.
MitMaro
I understand the singleton thing now but I still have the same errors, basicly I get errors if I do not initaite the class on every physical page that I need to use it so my problem is somewhat the opposite of a singleton, instead of needing the class to start 1 time I need to start it in every single file I include into a page that needs to use the methods from the class. Hope I am making sense, it is driving me nuts trying to find out why I have to initiate it on every file. If there is an index.php and a test1.php, test2.php, test3.php all 3 included into the index.php file, to avoid an
jasondavis
error, I must initiate a new object/call to the class in all the files to be able to use the $session->get($var) function in all these files, any ideas why it is requiring this? It will say "Fatal error: Call to a member function get() on a non-object" if I use your code or even my code and the only way to make it work is to use something like $session = new Session(); in every file
jasondavis
for simplicity I will accept this and I have started a more specific question here http://stackoverflow.com/questions/1463459/how-can-i-initiate-a-php-class-and-use-it-in-several-files if you care to see, thanks for your help so far =)
jasondavis