2009-09-22 131 views
0

下面是我遇到的麻烦的一个非常基本的例子。PHP类范围问题

现在为什么我必须使用$ session = new Session();database.class.php文件,当我在我的系统中的文件被包含在一个方式,它已经可见了。

换句话说,我不能调用$ session = new Session();在任何其他类之外,为了使它在其他类中工作,我必须调用在每个要使用它的类中创建会话类的新对象,我如何避免这种情况并使其工作,而无需这样做?

// 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); 
    } 
} 
+1

我在任何地方都看不到'$ session = new Session();'。它可以帮助我们理解你的问题。 – MitMaro 2009-09-23 00:00:10

+0

@MitMaro对不起,这个类是在脚本的其他地方启动的,我只想开始它,但是这种方式现在要求我在每个使用另一个文件中的类的类文件中启动它 – JasonDavis 2009-09-23 00:13:35

回答

1

如果我理解你的问题正确,一个解决问题的方法是使用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; 
    } 
} 

index.php你会:

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

然后在您的数据库类,你将有:

// 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); 
    } 
} 

你永远只能创建会话类的一个实例(这是我认为你在寻找什么)。然后,当你需要其他地方的Session类(即你的数据库类)时,你可以再次调用Session::getInstance()。只有一个会话创建实例,您可以在脚本中全局使用它。

+0

感谢代码,这可能是唯一的解决方案,但我会问无论如何,是否有可能调用类似$ session = new $ session();例如一个index.php文件,然后能够在其他类中使用它的方法或者包含在索引文件中的任何其他文件,而不必在每个文件中创建新的实例? – JasonDavis 2009-09-23 00:16:12

+0

我更新了我的答案,但它并没有真正回答你的问题。你可以使用$ GLOBALS [http://us2.php.net/manual/en/reserved.variables.globals.php],但Singleton更好。 – MitMaro 2009-09-23 00:28:34

+0

我现在明白单身的事情,但我仍然有同样的错误,基本上我得到错误,如果我不启动每个物理页面上的类,我需要使用它,所以我的问题有点是与单身人士相反,而不是需要该类开始1次我需要在包含在需要使用该类中的方法的页面中的每个文件中启动它。希望我是有道理的,这迫使我试图找出为什么我必须在每个文件上启动它。如果index.php和test1.php,test2.php,test3.php都包含在index.php文件中,为避免出现 – JasonDavis 2009-09-23 01:00:00

2

首先,你的会话类应该是一个单 - 的原因是多次调用在session_start()将让你什么,但问题(会话ID获取再生)

所以......

/** 
* 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 
} 

要使用它,你只需拨打:

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

或者干脆

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

你需要的地方使用会话类。

更新: - 我看你可能不把握单身的概念还没有,所以这里是一个正确的wikipedia link 8)

+0

You beat我对它和你提供了一个例子。 +1 – MitMaro 2009-09-23 00:02:50

+0

虽然你在单例中有一些错误,但你没有返回实例。 – MitMaro 2009-09-23 00:03:40

+0

是的,这是固定的 - 咖啡时间我猜8) – 2009-09-23 00:04:27