Php 对非对象调用成员函数

Php 对非对象调用成员函数,php,mysqli,Php,Mysqli,我是php oop新手,所以有点挣扎 我有一个数据库连接类,即: class config{ protected $HOST = "localhost"; protected $USERNAME = "something" ; protected $PASSWORD = "something"; protected $DATABASE = "something"; // Constructor - open DB connection function __con

我是php oop新手,所以有点挣扎

我有一个数据库连接类,即:

  class config{

   protected $HOST = "localhost";
   protected $USERNAME = "something" ;
   protected $PASSWORD = "something";
   protected $DATABASE = "something";

// Constructor - open DB connection
function __construct() {

try {
    $this->db = new mysqli($this->HOST, $this->USERNAME, $this->PASSWORD, $this-
    >DATABASE);
    $this->db->autocommit(FALSE);
    }
catch(Exception $e)
    {   
    if($this->db->connect_errno > 0){

    echo 'Caught exception: ',  $e->getMessage(), "\n";
    }
    }

    }

   // Destructor - close DB connection
     function __destruct() {
    $this->db->close();
    }


 }

 $api = new Config();
现在我有另一个类,我需要从中执行一些任务…但我得到了致命的错误

二等舱:

  class Myclass extends config {

   function __construct(){}

   public function myfunction()
   {
    try{


     $stmt = $this->db->stmt_init();   /* Error here : Fatal error: Call to a member                 
                                          function stmt_init() on a non-object */
 $query = "SELECT ABC FROM table " ;

 $stmt = $this->db->prepare($query); /* Error here : Fatal error: Call to a member                 
                                          function prepare() on a non-object   */
      }
     catch(){}

   }

   }

请用正确的补救代码片段指导我

您的派生类构造函数没有调用基构造函数,因此
$this->db
没有它应该具有的值。在PHP中


在这种特殊情况下,您应该完全删除派生构造函数,因为它什么都不做。这将允许PHP直接使用基构造函数。

在子类中,需要调用父构造函数。当子类被实例化时,PHP不会自动调用父构造函数

 class Myclass extends config {

     function __construct($h, $u, $p, $d){ parent::__construct($h, $u, $p, $d); }
另外,父类中没有
$db
属性,因此添加该属性

 class config{

   protected $db;
   protected $HOST = "localhost";
   protected $USERNAME = "something" ;
   protected $PASSWORD = "something";
   protected $DATABASE = "something";
编辑:依赖项注入方法:

class config{
   public $HOST = "localhost";
   public $USERNAME = "something" ;
   public $PASSWORD = "something";
   public $DATABASE = "something";
}

class Myclass
{
   protected $db;

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

   public function myfunction()
   {
       // do whatever with $this->db
   }
}

$config = new Config();

try
{
    $db = new mysqli($config->HOST, $config->USERNAME, $config->PASSWORD, $config->DATABASE);
    $db->autocommit(FALSE);
}
catch(Exception $e)
{   
    if($db->connect_errno > 0){
        echo 'Caught exception: ',  $e->getMessage(), "\n";
    }
}

$myclass = new Myclass($db);

看看依赖注入。这是处理需要访问数据库的类的有利方法。不要让所有类扩展数据库,而是在创建新类(需要db)时将datsbase对象作为参数传递。

正确的补救方法不是更多代码,它正在学习如何调试你已经拥有的东西。你得到的fata错误是什么?我已经在我的代码中对此进行了注释。请看一下第二类代码片段嘿,谢谢!这起作用了。。。我想知道更多一点,我是否使用require_('Config.php')而不是扩展类;那我需要做些什么改变。。。。因为这样我无法访问父构造函数…如果不扩展,您可以在两个类之外创建
$db
,当您基于这些类创建新对象时,将
$db
传递给构造函数,并让类将其存储为属性,所以这些类仍然可以在整个过程中使用
$this->db
。如果你能用一些小例子来解释这一点就太好了。添加了一个基本依赖注入的例子,顺便问一下,哪种方法更好?扩展类或您的依赖方法。。。。想想我的包裹里没有别的类了…