PHP类范围

问题描述:

我有几个班,我目前正在建设一个应用程序,我想有一个访问一些其他的成员函数,但我似乎无法做到这一点。PHP类范围

第一类叫做MySQLdb的:

class MySQLDB{ 
public $connection; 

function __construct(){ 
//connects to database 
} 

function login($username, $password){ 
//queries database... 
} 
} 

然后我就称为会话类:

class Session{ 
//variables 
//constructor 

function processlogin($username, $password){ 
$database->login($username, $password); 
} 

在此之后然后我有两个类声明:

$database = new MySQLDB(); 
$session = new Session(); 

无在这里,我把这些陈述关于类我仍然得到相同的错误:

PHP Notice: Undefined variable: database in C:\inetpub\wwwroot\cmu\include\session.php on line 52 
PHP Fatal error: Call to a member function login() on a non-object in C:\inetpub\wwwroot\cmu\include\session.php on line 52 

我已经看到了一些建议,建议把新的数据库对象的会话类声明中,但我想避免这样做,因为我使用的数据库类代码中与其它几个地方,我不想打开到数据库的多个连接。

,因为你希望有一个全局变量设置存取权限,您可以访问它与global

function processlogin($username, $password){ 
    global $database; 
    $database->login($username, $password); 
} 

或使用该变量作为用于构造器参数,并记忆在类Session数据库对象引用:

class Session{ 

    private $database; 

    function __construct($database){ 
     $this->$database = $database; 
    } 

    function processlogin($username, $password){ 
     $this->database->login($username, $password); 
    } 

} 

然后调用:

$database = new MySQLDB(); 
$session = new Session($database); 

这个就派上用场了,如果你使用更多的功能后记,也需要访问数据库对象。

+0

谢谢我刚刚使用'全球$数据库'语句,它现在工作得很好。我计划在尝试第二种方法时有机会,但我想与您核对以确保它引用对象并且不会创建副本。 – 2011-05-30 19:32:35

+0

我需要使用类似于我的最新项目,我意识到我正在运行大约10个数据库实例。如果'MySQLDB'实例需要被其他类同时使用,可能会有问题,因为'Session'实例中的'$ database'对象不会引用同一个实例。所以如果你从另一个地方改变这个对象,这个修改对你的班级将是不可见的。假设你想这样做:'$ database-> setEncoding('utf-8');';那么你将不得不为你的会话数据库做同样的事情:'$ session-> database-> setEncoding('utf-8')' – 2011-05-30 19:38:09

+0

这就是我所担心的。 – 2011-05-30 19:58:58

您正在创建两个全局变量。如果你正在做这样的事情,你需要声明要在函数中使用与“全局”关键字变量:

function processlogin($username, $password){ 
global $database; 
$database->login($username, $password); 
} 

尽管这会工作,我强烈建议阅读Dependecy注射机构中,你会将$database变量作为参数传递给processlogin()方法,或者将其设置为构造函数/设置器中该类的私有成员。这样数据库连接将是可以互换的,并且您的代码将获得更多灵活性。

$database没有在processlogin里定义,也没有作为参数传递,因此函数无法访问它。

你可以把它作为构造函数参数Session

class Session { 
    private $db; 

    public function __construct($database) { 
     $this->db = $database; 

    public function processlogin($username, $password){ 
     $this->$db->login($username, $password); 
    } 
} 

$database = new MySQLDB(); 
$session = new Session($database); 
+0

为什么不创建具有子类的父类,然后调用父类或子类呢? – 2014-11-06 04:15:01

+0

@Gerald:你的意思是'Session'应该是'MySQLDB'的孩子吗?继承表示* is-a *关系,但* Session *不是* MySQLDB *。会话*使用*数据库,这是什么组成。它只是更有意义的语义,但当然,你可以做任何你想做的;) – 2014-11-06 06:53:27

,你可以在Session构造函数传递给MySQLDB实例的引用。

class Session{ 
    public $db; 

    function __construct(&$db=null){ 
     if($db == null) 
      $this->db = new MySQLDB(); 
     else 
      $this->db = $db; 
    } 
    // .... 
} 

$database = new MySQLDB(); 
$session = new Session($database);