2010-07-21 110 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();