web-dev-qa-db-ja.com

致命的なエラー:キャッチされていないエラー:nullのメンバー関数select()の呼び出し

私はPHPのOOPにちょっと慣れており、モデルで毎回この問題に直面していますが、これを引き起こすエラーを見つけることができません。

次のようなエラーが表示されます:致命的なエラー:キャッチされていないエラー:getCategories関数のmodelのnullでメンバー関数select()を呼び出します(以下のコードを参照)。

<?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 [〜#〜] file:

<?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クラスがあり、選択機能がそこにあります。

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はそれ以降の機能もそうではありません。

このエラーを検索しようとしましたが、特定の問題の解決策が見つかりませんでした。

どんな助けも大歓迎です!前もって感謝します。

[〜#〜] edit [〜#〜]:あなたの助けをありがとう!私はそれを考え出した。モデルクラスに間違いがあったため、dbとの接続はありませんでした。

6
Jamal Jubran

$ dbは親クラスで定義されていないようです。モデルです。初期化してもよろしいですか?

(クラスモデル内の)親コンストラクターで初期化した場合、現在のコンストラクター(モデルmodel_addItem内)で明示的に呼び出す必要があります。 PHPはそれを自動的に行いません。

6
Erik Kalkoken

このエラーは、nullオブジェクトでselect()が呼び出されることを示唆しています。 _parent::$db_でvar_dump()を実行し、オブジェクトが実際に空でないことを確認します。

2
Last Templar

あなたの問題はparent::$dbnullです。つまり、データベース接続は初期化されていません。理由を理解することから始めて、そこから働きます。

1
Auris