2010-07-21 49 views
0

PHP類中的範圍問題:PHP中的類範圍問題

爲什麼這樣工作?

class index extends Application 
    { 
     function ShowPage() 
     { 
      $smarty = new Smarty();   // construct class 
      $smarty->assign('name', 'Ned');  // then call a method of class 
      $smarty->display('index.tpl'); 
     } 

} 

$ index_instance = new index; $ index_instance-> ShowPage();

但這不起作用?

class index extends Application 
{ 

    function ShowPage() 
    { 

     $smarty->assign('name', 'Ned'); 
     $smarty->display('index.tpl'); 
    } 
} 

$index_instance = new index; 
$smarty = new Smarty(); 
$index_instance->ShowPage(); 

回答

3

歡迎來到PHP變量範圍的精彩世界。

函數和方法看不到在它們外面定義的任何變量。您必須使用關鍵字global來聲明您希望訪問在函數作用域之外定義的變量。

這是行不通的:

class Foo { 
    public function bar() { 
     echo $baz; 
    } 
} 
$f = new Foo(); 
$baz = 'Hello world!'; 
$f->bar(); // "Notice: Undefined variable: ..." 

工作:

class Foo2 { 
    public function bar() { 
     global $baz; // <- "I want $baz from the global scope" 
     echo $baz; 
    } 
} 
$f = new Foo2(); 
$baz = 'Hello world!'; 
$f->bar(); // "Hello world!" 

即使一切正常,你應該避免使用它。有更好的方法去傳遞外部對象。一種方式被稱爲「dependency injection」,這是一種說法「在施工期間傳遞外部依賴性」的奇特方式。例如:

class Index extends Application { 
    private $smarty; 
    public function __construct(Smarty $smarty) { 
     $this->smarty = $smarty; 
    } 
    public function showPage() { 
     $smarty->assign('foo', 'bar'); 
     $smarty->display('index.tpl'); 
    } 
} 
$sm = new Smarty(...); 
$whatever = new Index($sm); 
$whatever->showPage(); 

另一種方式是使用註冊表,這是一種用於存儲可能是全局變量的事物的模式。我們以Zend Registry爲例。

class Index extends Application { 
    public function showPage() { 
     $smarty = Zend_Registry::get('smarty'); 
     $smarty->assign('foo', 'bar'); 
     $smarty->display('index.tpl'); 
    } 
} 
$sm = new Smarty(...); 
Zend_Registry::set('smarty', $sm); 
$whatever = new Index(); 
$whatever->showPage(); 
+0

'global'不是來自前一個範圍的變量,而是來自全局範圍。 – NullUserException 2010-07-21 16:18:48

+0

好,我糾正了誤導評論。 – Charles 2010-07-21 16:23:35

+0

謝謝你的作品! – 2010-07-21 16:45:11

1

簡單:因爲$ smarty在$ index_instance範圍內不存在。

如果你想實例化一個新的Smarty索引類以外,那麼你需要的智者傳遞給指數實例:

class index extends Application 
{ 
    private $smarty = null; 

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

    function ShowPage() 
    { 

     $this->smarty->assign('name', 'Ned'); 
     $this->smarty->display('index.tpl'); 
    }  
} 

$smarty = new Smarty(); 
$index_instance = new index($smarty); 
$index_instance->ShowPage(); 
0

我現在用依賴注入方法。

require_once("/classes/Conf.php"); 
require_once("/classes/Application.php"); 

class index extends Application 
{ 
    private $template_instance; 

    public function __construct(Smarty $template_instance) 
    { 
     $this->template_instance = $template_instance; 
    } 

    function ShowPage() 
    { 
     $this->template_instance->assign('name', 'Ned'); 
     $this->template_instance->display('index.tpl'); 
    } 
} 

$template_instance = new Smarty(); 
$index_instance = new Index($template_instance); 
$index_instance->showPage();