Php “故障排除”;不在对象上下文中使用$this“;尝试从父类访问子类的属性时

Php “故障排除”;不在对象上下文中使用$this“;尝试从父类访问子类的属性时,php,static-methods,Php,Static Methods,我有一个main类,它初始化main类函数中的另一个类,我需要从main类到另一个类获取一个变量(在本例中为$this->db)。例如,我有一个主类Wordle\u Admin: class Wordle_Admin { public function __construct() { $this->db = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); } public function vi

我有一个main类,它初始化main类函数中的另一个类,我需要从main类到另一个类获取一个变量(在本例中为
$this->db
)。例如,我有一个主类
Wordle\u Admin

class Wordle_Admin
{
   public function __construct()
   {
       $this->db = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
   }

   public function views()
   {
       include 'Wordle_Admin_Views.php';
       $wsa = new Wordle_Admin_Views();
       $view = @$_GET['view'];
       $id = @$_GET['id'];
       $type = @$_GET['type'];
       $action = @$_GET['action'];
       $msg = @$_GET['msg'];

       if( !empty( $view ) && method_exists( $wsa, $view ) ):
           $wsa::$view($id, $type, $action, $msg);
       elseif( !empty( $view ) && !method_exists( $wsa, $view ) ):
           echo'View does not exist.';
       else:
           $wsa::index($id, $type, $action, $msg);
       endif;
   }    

}
我还有一门课:

class Wordle_Admin_Views extends Wordle_Admin
{
    public function __construct()
    {
        parent::__construct();
    }

    public function index( $id = "", $type = "", $action = "", $msg = "" )
    {
        $this->db->query('SELECT * FROM wordle_post');
    }
}
我无法在
Wordle\u Admin\u视图中使用
$this->db
,它返回:

致命错误:在第22行的C:\Server\wordle\w-includes\wordle\u Admin\u Views.php中不在对象上下文中时使用$this


所以我的问题是,如何将一个变量从父类传递到另一个类?感谢您提供的各种帮助,我们也会敞开双手接受关于如何做不同的建议。

在您的世界管理课程中,尝试以下

class Wordle_Admin
{
    protected $db;

}

然后,当您调用$this->db时,应该继承您的db var,假设$this->db是在父类中定义的。

您的具体问题是静态调用该方法。静态上下文中没有对象,因此不能使用
$this

你的另一个问题似乎是你对继承有点误解。由于DB连接仅在实例化对象(
new Worlde\u Admin
)时创建,因此子对象也是如此

Wordle\u Admin\u视图
不能自动访问在
Worlde\u Admin
的某些实例中创建或未创建的DB连接。只有
Worlde\u Admin
实例具有该DB连接。您需要实例化一个
Wordle\u Admin\u视图
,这样它也会有一个连接(因为它继承了
Worlde\u Admin
的方法)

您应该研究依赖注入,这意味着您在类之外创建一个
mysqli
实例,并在实例化时将其注入每个实例

$db = new mysqli(...);

$admin = new Worlde_Admin($db);
$view  = new Wordle_Admin_Views($db);

在我看来,这可能是问题的一部分:

   include 'Wordle_Admin_Views.php';
   $wsa = new Wordle_Admin_Views();

   /* blah blah */

   if( !empty( $view ) && method_exists( $wsa, $view ) ):
       $wsa::$view($id, $type, $action, $msg);
   elseif( !empty( $view ) && !method_exists( $wsa, $view ) ):
       echo'View does not exist.';
   else:
       $wsa::index($id, $type, $action, $msg);
   endif;
您试图访问的静态函数不是类名,而是对象。它应该是
Wordle\u Admin\u视图::$view()
$wsa->$view()


你真的学过php吗?或者你是在假装它是其他语言(python?)而只是“随机应变”。

在没有对象上下文的情况下使用$this
与父母或孩子无关。这意味着在静态调用的函数中或在对象外部使用
$this
。如何调用这些函数?我在布局文件(如用户所见)中使用Wordle_Admin::views()来输出作为函数(Wordle_Admin_视图的函数)运行的页面。我的目标是能够在Wordle_Admin_视图中使用mysqli,而无需初始化新连接,而是使用在Wordle_Admin中初始化的连接。如果这是可能的,那就是。我猜这是被否决的,因为虽然它解决了OP所说的问题,但它没有解决实际问题(从评论和错误消息的性质推断)。我是否误读了什么?在父类中声明受保护的$db使$db对扩展该控制器的类可见。在子控制器中,您可以调用$this->db,如果实例化,它将返回父$db。这不是问题吗?@phoenix-真的吗?他说:“我需要从主类到另一个类获取一个变量(在本例中是$this->db)”,这不是为什么它不起作用。他问如何让它工作。你可能是对的。我没有否决你的回答;我只是好奇是否有办法改进它,让它升级。@Kai如果该属性在父级中没有明确声明为
private
,那么它是否被声明完全没有关系。首先,请看一个可爱的答案。这个解决方案就像一个符咒。在对象实例上调用静态方法或属性实际上是一个允许的快捷方式。当然,这不一定是个好主意。@deceze,我想他是在用另一种方法:将普通方法调用为静态方法(该方法中使用了
$this
),它解决了我遇到的问题,谢谢。至于我学到了什么;没有。然而我正在学习。也不,我不是在假装,因为我真的不懂任何其他语言。我来这里学习是因为对我来说,从别人的错误中学习是最好的方法。至于动机,我实际上偶尔喜欢用一个严厉的词。它使精神保持活力,并提醒我,我离我想去的地方还很远。所以我要加倍感谢你,这就是为什么我的回答是我投了反对票。类中没有任何东西将其声明为静态的,因此使用::调用它将产生相同的结果。所以我想。@KaiQing,是的,这是第一个想法,但是在中测试表明未声明的类变量没有设置为
private
   include 'Wordle_Admin_Views.php';
   $wsa = new Wordle_Admin_Views();

   /* blah blah */

   if( !empty( $view ) && method_exists( $wsa, $view ) ):
       $wsa::$view($id, $type, $action, $msg);
   elseif( !empty( $view ) && !method_exists( $wsa, $view ) ):
       echo'View does not exist.';
   else:
       $wsa::index($id, $type, $action, $msg);
   endif;