2012-03-15 85 views
0

如標題所示,訪問包含文件中的類(關聯數組)時出現問題。以下是源代碼類和包含文件:無法訪問包含文件中的變量

require("applications/cw_database.php"); 
require("config/dbConfig.php"); 
require("config/appConfig.php"); 

class APP_ASSESMENTS 
{ 
    private $dbObj; 
    private $DisplayOutput = ""; 

    public function __construct($PageParams) 
    { 
     try 
     { 
      $dbObj = new CW_DB($dbConfig['hostname'],$dbConfig['username'],$dbConfig['password'],$dbConfig['name'],$dbConfig['port']); 
     } catch (Exception $e) { 
      throw new ErrorException($e); 
     } 
    } 
... 

另一部分與$ dbConfig無關。 另外這是所包含的文件(配置/ dbConfig.php):

/* 
    Testing configuration for MySQL database 
*/ 
$dbConfig['username'] = "phpcoursework"; // changed on demand 
$dbConfig['password'] = "phpcoursework"; // changed on demand 
$dbConfig['hostname'] = "localhost";  // changed on demand 
$dbConfig['name']  = "students";  // changed on demand 
$dbConfig['port']  = 3306;    // default for MySQL 
+0

如果您沒有以某種方式將'$ dbConfig'傳遞給您的類,您如何期望您的類知道它是什麼?答案建議使用'global'關鍵字,這是一種非常糟糕的做法,因爲它會污染變量空間,您可能很容易造成錯誤。如果你需要這個變量,只需將它傳遞給你的構造函數。 – 2012-03-15 11:47:00

+0

在類中包含文件並將變量定義爲全局作品。 – Tosh 2012-03-15 11:49:12

+0

如果這對你來說看起來很不錯,那就試試吧。 – 2012-03-15 11:54:48

回答

0

首先,$dbObj不會自動的類成員範圍,它會創建CW_DB的本地副本,並在__construct返回時將其丟棄。您需要明確引用該屬性;

$this->dbObj = ... 

無論如何,全局狀態使用global的建議由他人將「工作」,但如果你使用OOP做法,你最好不要做。您可以從include()實際回報,所以一個辦法是做到以下幾點:

// your config file dbConfig.php 
return array(
    'username' => "phpcoursework", 
    'password' => "phpcoursework", 
    'hostname' => "localhost", 
    'name' => "students", 
    'port' => 3306, 
); 

,並將它注入到對象,通過構造函數或方法(這裏的構造

class APP_ASSESMENTS 
{ 

    private $dbObj; 

    public function __construct($dbConfig, $PageParams) 
    { 
     $dbObj = new CW_DB($dbConfig['hostname'], $dbConfig['username'], 
      $dbConfig['password'], $dbConfig['name'], $dbConfig['port']); 
     // ... 
    } 

} 

// include() here, will actually return the array from the config file 
$appAssesments = new \APP_ASSESMENTS(include('dbConfig.php'), $PageParams); 

它建議您再升級一層:相反,注入數據庫對象本身,從您的APP_ASSESSMENTS類中取出依賴項。

此外,PascalCase是類命名的典型慣例,如AppAssessmentsCwDb


$dbObj = new CwDb(include('dbConfig.php')); 
$appAssessments = new AppAssessments($dbObj, $etc, $etc); 

這個簡單的變化可以讓你從AppAssessments去除CwDb的依賴。這樣,如果你因爲某些原因延長CwDb,你可以通過在擴展類的實例,而無需更改任何代碼在AppAssessments

可以更改AppAssessments構造像這樣:

public function __construct(CwDb $db, $etc, $etc){ 
    $this->db = $db; 
    // ... 
} 

這利用了PHP(限制,儘管仍然有用)type-hinting,確保第一個參數總是正確的類型。

這是打開/關閉原則的一部分:類應該可以擴展,但可以修改。

+0

你是什麼意思注入對象本身?也感謝您的建議。 – Tosh 2012-03-15 11:59:30

+0

@MaDDoC沒問題:)通過注入對象本身,我的意思是創建'AppAssessments'對象的外部數據庫對象實例*(可能在*之前),然後傳入數據庫對象,而不是配置。我將編輯顯示。 – Dan 2012-03-15 12:01:06

+0

嗯,我明白了,但這裏是發生了什麼:我試圖使用MVC體系結構來創建Web應用程序,我曾經使用index.php創建將要顯示的頁面控制器的新實例。控制器本身也創建了實例,但也創建了實例,但是實例的數據庫。我有點困惑是使用這種架構的正確方法...... – Tosh 2012-03-15 12:08:33

-1
public function __construct($PageParams){ 
    global $dbConfig; 
    try{ 
     $dbObj = new CW_DB($dbConfig['hostname'],$dbConfig['username'],$dbConfig['password'],$dbConfig['name'],$dbC onfig['port']); 
    } catch (Exception $e) { 
     throw new ErrorException($e); 
    } 
} 

,或者您可以使用$GLOBALS['dbConfig']

0

包含用於訪問範圍。所以,爲了訪問變量,你需要在你的類中包含這些文件。正如前面提到的,全局將允許您訪問另一個範圍的變量。但全球應謹慎使用!請參閱文檔。

See the manual for more information.

編輯:我需要說清楚,全局永遠不會處理這些類型的關鍵變量的一個很好的選擇..