【问题标题】:class scope question in PHPPHP中的类范围问题
【发布时间】:2023-03-30 20:34:01
【问题描述】:

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 = 新索引; $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();

【问题讨论】:

    标签: php class scope


    【解决方案1】:

    欢迎来到 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();
    

    【讨论】:

    • global 不是用于前一个作用域的变量,而是用于全局作用域的变量。
    【解决方案2】:

    简单:因为 $smarty 不存在于 $index_instance 的范围内。

    如果你想在你的索引类之外实例化一个新的 Smarty,那么你需要将 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(); 
    

    【讨论】:

      【解决方案3】:

      我现在正在使用依赖注入方法。

      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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-10
        • 2011-04-18
        • 2015-01-24
        • 1970-01-01
        • 2010-09-13
        相关资源
        最近更新 更多