如果存在__construct函数,则调用null上的成员函数prepare()

时间:2017-09-25 09:37:36

标签: php pdo constructor

我最近遇到了分页的需要,我会使用它很多,所以我认为一个课程是完美的,因为某些原因,当我尝试使用__construct时,我得到了致命的错误:

  

在null上调用成员函数prepare()       在第31行的'\ App \ Helpers \ PaginationHelper.php'中抛出

第31行是:

$sth = $this->db->prepare('SELECT * FROM '. $this->table_name .' ORDER BY id LIMIT :page_first_result, :per_page');

在retrieveData函数中。

这是一个很大的混乱,因为我刚刚开始,但对于我的生活,我无法弄清楚这个错误,我已经阅读了一些其他问题有相同的错误,但他们都与PDO无关连接,不像这个问题。

\ Core \ Model只是扩展了一个pdo连接

class PaginationHelper extends \Core\Model {

    public $results = [];
    public $tabs = '';
    public $set_data;
    public $table_name;
    public $results_per_page;

    public function __construct($sd){
        $this->set_data = $sd;
    }

    public function table_name($tn){
        $this->table_name = $tn;
    }

    public function results_per_page($rpp){
        $this->results_per_page = $rpp;
    }

    public function retrieveData($page_first_result, $per_page){
        $sth = $this->db->prepare('SELECT * FROM '. $this->table_name .' ORDER BY id LIMIT :page_first_result, :per_page');
        $sth->bindValue(':page_first_result', $page_first_result, PDO::PARAM_INT);
        $sth->bindValue(':per_page', $per_page, PDO::PARAM_INT);
        $sth->execute();

        return $sth->fetchAll(PDO::FETCH_ASSOC);
    }

    public function getResults(){
        $number_of_results = $this->set_data;

        $this->number_of_pages = ceil( count($number_of_results) / $this->results_per_page);

        // determine which page number visitor is currently on
        if (!isset($_GET['pagination'])) {
          $this->page = 1;
        } else {
          $this->page = $_GET['pagination'];
        }

        $this_page_first_result = ($this->page - 1) * $this->results_per_page;

        $fetch = $this->retrieveData($this_page_first_result, $this->results_per_page);

        foreach($fetch as $data){
            $this->results[] = $data;
        }

        return $this;
    }

    public function loopResults(){
        return $this->results;
    }

    public function getTabs(){

        if($this->page == 1){
            $this->back = $this->page;
        } else {
            $this->back = $this->page-1;
        }

        if($this->page == $this->number_of_pages){
            $this->next = $this->page;
        } else {
            $this->next = $this->page + 1;
        }

        $this->tabs .= '
            <div class="pagination">
                <a class="pagination__buttons-href" href="?pagination='.$this->back.'"><span class="pagination__buttons flaticon-keyboard-left-arrow-button"></span></a>
                <span class="pagination__current_page"> '. $this->page .' </span>
                <a class="pagination__buttons-href" href="?pagination='. $this->next .'"><span class="pagination__buttons flaticon-keyboard-right-arrow-button"></span></a>
            </div>
        ';

        return $this->tabs;
    }
}

现在,这里有一些有趣的事情:如果我删除__construct function,并创建一个新方法来放置$ set_data属性,如下所示,一切都运行良好。

public function set_data($sd){
    $this->set_data = $sd;
}

这就是我打电话给班级的方式:

这就是我用函数set_data调用类的方法:

$pagination = new PaginationHelper();
$pagination->set_data($array_data);
$pagination->table_name('recipe');
$pagination->results_per_page(20);
$pagination->getResults();

3 个答案:

答案 0 :(得分:3)

当你扩展一个类并且在其中有一个__constructor()函数时,你也应该调用它的父类的构造函数:

parent::__construct();

如果跳过此行,则永远不会调用\ Core \ Model的构造函数。如果删除构造函数,则会自动调用它。

答案 1 :(得分:3)

如果定义自己的构造函数,则不会自动调用父的构造函数。

尝试这样做:

public function __construct($sd){
    parent::__construct();
    $this->set_data = $sd;
}

直接引用文档(http://php.net/manual/en/language.oop5.decon.php):

  

注意:如果子类定义了构造函数,则不会隐式调用父构造函数。为了运行父构造函数,需要在子构造函数中调用parent :: __ construct()。如果子进程没有定义构造函数,那么它可以像普通的类方法一样从父类继承(如果它没有被声明为私有)。

答案 2 :(得分:1)

尝试这个

public function __construct($sd){
parent::__construct();
$this->set_data = $sd;

}

手动调用父构造函数