致命错误:未捕获的错误:在 null 上调用成员函数 select()

Posted

技术标签:

【中文标题】致命错误:未捕获的错误:在 null 上调用成员函数 select()【英文标题】:Fatal error: Uncaught Error: Call to a member function select() on null 【发布时间】:2016-04-20 23:47:20 【问题描述】:

我对 php 中的 OOP 有点陌生,每次在模型中都会遇到这个问题,但我找不到导致此问题的错误。

我收到一条错误消息:致命错误:未捕获的错误:在 getCategories 函数中的 model 中调用成员函数 select() on null(参见下面的代码)。

<?php

class model_additem extends model
    public function __construct()
        DB::setConnection(DB_ADMIN,DB_ADMIN_PASS);
    

    public function insertItem($picName,$n,$d,$p,$ui,$ic,$pt,$pd="good")
        $data = ["pic_name"=>$picName,"pic_desc"=>$pd,"pic_type"=>$pt];
        $img = parent::$db->saveTo("pictures")->setData($data)->execute();

        if($img)
            $imgId = parent::$db->lastInsertId();

            $data = ["name"=>$n,"description"=>$d,"price"=>$p,"image_id"=>$imgId,"owner_id"=>$ui,"category_id"=>$ic];
            $prod = parent::$db->saveTo("products")->setData($data)->execute();
            return $prod;
        
        return false;
    

    public function getCategories()
        $data = parent::$db->select()->from('category')->fetch('all');
        if($data) return $data;
        return false;
    



这是我的 CONTROLLER 文件:

<?php

class controller_additem extends controller
    public function __construct()
        Load::view("admin".DS."header");
        Load::view('additem/additem');
        Load::view("admin".DS."footer");
        require_once 'CheckAdmin.php'; // Check if the user is admin to enter page + more.


    

    public function index()
        $item = $this->model("additem");
        if(isset($_POST["addItem"]))
            $iName = filter_input(INPUT_POST,"iName",FILTER_SANITIZE_MAGIC_QUOTES);
            $iDesc = filter_input(INPUT_POST,"iDesc",FILTER_SANITIZE_MAGIC_QUOTES);
            $iPrice = filter_input(INPUT_POST,"iPrice",FILTER_SANITIZE_NUMBER_FLOAT);
            $iCat = filter_input(INPUT_POST,"category",FILTER_SANITIZE_NUMBER_INT);
            $iPic = $_FILES["iPicture"];

            $extention = explode(".",$iPic["name"]);
            $ext = end($extention);
            //pre($iPic);
            //validation
            //if($iPic["size"]> 2000000)
            $picName = $iName.time().'.'.$ext;
            if(move_uploaded_file($iPic["tmp_name"],ROOT . "public/images/" . $picName))
                $userId = Session::get("userId");

                $result = $item->insertItem($picName,$iName,$iDesc,$iPrice,$userId,$iCat,$ext);
                if($result)
                    Session::set("result","Item has been inserted successfully");
                else
                    Session::set("result","Error occured");
                

            
        
        $cats = $item->getCategories();
        $uName = Session::get("userData")["name"];
        Load::view("additem/additem",$cats);
    

我的引擎文件中还有一个 db 类,用于处理与数据库相关的函数,并且 select 函数在其中:

class db
    private static $db = null;
    private $sql = "";
    private $save_type;
    private $binded = array();
    private $query = '';
    private $last_insert_id;

    public function __construct()
        if(self::$db == null)
            $user = DB_GUEST;
            $pass = DB_GUEST_PASS;
            if(Session::found("user_priv") == 'no')
                $user = DB_USER;
                $pass = DB_USER_PASS;
            
            if(Session::found("user_priv") == 'yes')
                $user = DB_ADMIN;
                $pass = DB_ADMIN_PASS;
            
            self::setConnection($user,$pass);
        
    

    public static function setConnection($user,$pass,$dbname=DB_NAME)
        try
            self::$db = new PDO("mysql:host=localhost;dbname=$dbname",$user,$pass);
            self::$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
            self::$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
            self::$db->exec("SET NAMES utf8");
        catch(PDOException $e)
            die($e->getMessage());
        
    

    public static function getDb()
        if(self::$db == null)
            $user = DB_GUEST;
            $pass = DB_GUEST_PASS;
            if(Session::found("userId"))
                $user = DB_USER;
                $pass = DB_USER_PASS;
            
            if(Session::found("admin"))
                $user = DB_ADMIN;
                $pass = DB_ADMIN_PASS;
            
            self::setConnection($user,$pass);
        
        return self::$db;
    

    //SELECT [name,pass,email]
    public function select(array $select=[])
        $sql = "SELECT ";
        if(empty($select))
            $sql .= "*";
        else
            filter_array($select);
            $select = implode(",",$select);
            $sql .= string($select);
        
        $this->sql = $sql;

        return $this;
    

    //FROM
    public function from($tbl)
        $this->sql .= " FROM " . string($tbl);
        return $this;
    

    //WHERE
    public function where(array $where)
        //filter_array($where);
        $sql = " WHERE ";
        foreach($where as $key => $val)
            $sql .= $key . " LIKE '".$val."' AND ";
        

        $this->sql .= rtrim($sql," AND ");
        return $this;
    

    //JOIN
    public function join(array $tbl,$type="LEFT JOIN")
        $sql = " ".strtoupper($type)." ";
        $sql .= implode(",",$tbl);

        $this->sql .= $sql;
        return $this;
    

    //ON
    public function on($cond1,$cond2)
        $sql = " ON ";
        $sql .= string($cond1) . " = " . string($cond2);

        $this->sql .= $sql;
        return $this;
    

    //ORDER BY
    public function order_by($order_by, $order_type="ASC")
        $sql = " ORDER BY ";
        $sql .= string($order_by)." ".strtoupper(string($order_type));

        $this->sql .= $sql;
        return $this;
    

    //LIMIT
    public function limit($limit)
        $this->sql .= " LIMIT " . int($limit);
        return $this;
    

    //FETCH
    public function fetch($fetch_type="")
        $fetch = "fetch";
        if($fetch_type)
            $fetch = "fetchAll";
        

        try
            $query = self::$db->query($this->sql);
            $this->reset();
            return $query->$fetch();
        catch(PDOException $e)
            die($e->getMessage());
        
    

    //saveTo
    public function saveTo($tbl,$type="insert")
        $tbl = string($tbl);
        $this->save_type = strtolower(string($type));

        if($this->save_type == "update")
            $sql = "UPDATE ";
        elseif($this->save_type == "replace")
            $sql = "REPLACE INTO ";
        else
            $sql = "INSERT INTO ";
        

        $sql .= $tbl . " SET ";
        $this->sql = $sql;
        return $this;
    

    //SET DATA
    public function setData(array $data,$filter="string")
        $filter = string($filter);

        foreach($data as $colomn => $value)
            $colomn = string($colomn);
            $value = $filter($value);
            $this->binded[$colomn] = $value;
            $this->sql .= $colomn . "=:" . $colomn . ",";
        
        //pre($this->binded);
        $this->sql = rtrim($this->sql,",");
        return $this;
    

    //execute
    public function execute()
        try
            $this->query = self::$db->prepare($this->sql);
            if($this->binded)
                foreach($this->binded as $colomn => $value)
                    $this->bind($colomn,$value);
                
            
            $result = $this->query->execute();

            if($this->save_type == 'insert')
                $this->last_insert_id = self::$db->lastInsertId();
            
            $this->reset();
            return $result;

        catch(PDOException $e)
            die($e->getMessage());
        
    

    //BIND
    private function bind($placeholder,$value,$filter="string",$bind_type="bindValue")
        return $this->query->$bind_type(":".$placeholder,$filter($value),PDO::PARAM_STR);
    

    public function lastInsertId()
        return $this->last_insert_id;
    

    //DELETE
    public function delete($tbl,$col=false)
        $this->sql = "DELETE ";
        if($col)
            $this->sql .= string($col)." ";
        
        $this->sql .= "FROM " . string($tbl);
        return $this;
    

    //TRUNCATE
    public function truncate($tbl)
        $this->sql = 'TRUNCATE ' . string($tbl);
        return $this;
    

    //View Query
    public function viewQ()
        echo $this->sql;
    

    //RESET
    private function reset()
        $this->sql = "";
        $this->save_type = "";
        $this->query = "";
        $this->binded = array();
    

问题是,如果您在模型中查看 saveTo 函数,它似乎可以工作。但是,select 和后面的函数都没有。

请帮助我,我试图搜索此错误,但找不到针对我的特定问题的解决方案。

非常感谢任何帮助! 提前致谢。

编辑:感谢大家的帮助!我想到了。模型类有错误,所以与数据库没有连接。

【问题讨论】:

我们真的需要这一切吗?从阅读开始minimal reproducible example 没有框架,我自己的MVC 我们需要查看定义 parent::$db 的代码。所有其他代码都无关紧要。 附注:所有这些静态调用使您的代码紧密耦合并且本质上是程序化的。另见***.com/questions/4595964/… 【参考方案1】:

似乎 $db 没有在父类中定义。哪个是模型。你确定你初始化了吗?

如果您在父构造函数中(在类模型中)初始化它,您需要在当前构造函数中显式调用它(在类 model_addItem 中)。 PHP 不会自动执行此操作。

【讨论】:

【参考方案2】:

该错误表明在 null 对象上调用了 select()。在您的 parent::$db 上执行 var_dump() 并确保该对象实际上不是空的。

【讨论】:

... 在 $db 上做 var dump 会给你一个错误。在 parent::$db 上做 vardum 会给你空值。这正是错误所说的。数据库未初始化,因此包含 db 连接对象的变量为空(null)【参考方案3】:

您的问题是parent::$dbnull。这意味着数据库连接未初始化。从找出原因开始,然后从那里开始工作。

【讨论】:

以上是关于致命错误:未捕获的错误:在 null 上调用成员函数 select()的主要内容,如果未能解决你的问题,请参考以下文章

致命错误:未捕获的错误:在 C:\xampp\phpMyAdmin\libraries\classes\DatabaseInterface.php:1544 中的 null 上调用成员函数存在()

PHP“致命错误:未捕获错误:调用成员函数prepare()为null”

PHP:致命错误:未捕获的错误:在布尔值上调用成员函数 execute() [重复]

致命错误:未捕获的错误:调用 bool 上的成员函数 execute() [重复]

PHP 致命错误:未捕获的错误:调用字符串中的成员函数 diff()

如何在php中修复“未捕获的错误:在null上调用成员函数insertOne()”