2011-05-30 131 views
3

我有幾個班,我目前正在建設一個應用程序,我想有一個訪問一些其他的成員函數,但我似乎無法做到這一點。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 

我已經看到了一些建議,建議把新的數據庫對象的會話類聲明中,但我想避免這樣做,因爲我使用的數據庫類代碼中與其它幾個地方,我不想打開到數據庫的多個連接。

回答

4

,因爲你希望有一個全局變量設置存取權限,您可以訪問它與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

2

您正在創建兩個全局變量。如果你正在做這樣的事情,你需要聲明要在函數中使用與「全局」關鍵字變量:

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

儘管這會工作,我強烈建議閱讀Dependecy注射機構中,你會將$database變量作爲參數傳遞給processlogin()方法,或者將其設置爲構造函數/設置器中該類的私有成員。這樣數據庫連接將是可以互換的,並且您的代碼將獲得更多靈活性。

2

$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

4

,你可以在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);