doucan9079 2013-02-05 00:45
浏览 22
已采纳

mysqli :: prepare()和bind_param()[关闭]的问题

I have the following classes in my application:

    <?php

    class Connection extends Mysqli{

public function __construct($mysqli_host,$mysqli_user,$mysqli_pass, $mysqli_db) {
    parent::__construct($mysqli_host,$mysqli_user,$mysqli_pass,$mysqli_db);
    $this->throwConnectionExceptionOnConnectionError();     
}

private function throwConnectionExceptionOnConnectionError(){

    if(!$this->connect_error){
        echo "Database connection established<br/>";
    }else{
    //$message = sprintf('(%s) %s', $this->connect_errno, $this->connect_error);
        echo "Error connecting to the database."; 
    throw new DatabaseException($message);
    }
}
    }

    class DatabaseException extends Exception
    {
    }

class Page extends Mysqli{

private $con; 

public function __construct(Connection $con) {
    $this->con = $con;
    if(isset($_GET['id'])){
    $id = $_GET['id'];
    }else{      
    $id = 1;
    }       
    $this->get_headers($id);
    $this->get_content($id);
    $this->get_footer($id);
}

private function get_headers($pageId){ 
    $retrieveHead = $this->con->prepare("SELECT headers FROM pages WHERE page_id=?");
    $retrieveHead->bind_param('i',$pageId);
    $retrieveHead->execute();
    $retrieveHead->bind_result($header);
    $retrieveHead->fetch();
    $retrieveHead->close();
    echo $header;   
}

private function get_footer($pageId){ 
    $retrieveFooter = $this->con->prepare("SELECT footer FROM pages WHERE page_id=?");
    $retrieveFooter->bind_param('i',$pageId);
    $retrieveFooter->execute();
    $retrieveFooter->bind_result($footer);
    $retrieveFooter->fetch();
    $retrieveFooter->close();
    echo $footer;   
}

private function get_content($pageId){
    $retreiveContent = $this->con->prepare("SELECT template_id, section_title, i1, i2 FROM content WHERE page_id=? ORDER BY sequence DESC");
    $retreiveContent->bind_param('i',$pageId);
    $retreiveContent->execute();
    $retreiveContent->bind_result($template_id, $section_title, $i1, $i2);
         while ($retreiveContent->fetch()) {
            //Variables will be populated for this row.
            //Update the tags in the template.
            $template = $this->get_template($template_id);
            $template = str_replace('[i1]',$i1,$template);
            $template = str_replace('[i2]',$i2,$template);
            //$theTemplate is populated with content. Probably want to echo here
            echo $template;
        }
}

private function get_template($template_id){
    $retreiveTemplate = $this->con->prepare("SELECT code FROM templates WHERE template_id=?");
    $retreiveTemplate->bind_param('i',$template_id);
    $retreiveTemplate->execute();
    $retreiveTemplate->bind_result($template);
    $retreiveTemplate->fetch();
    $retreiveTemplate->close();
    return $template;
}

}
    ?>       

The small application should basically get the page variable from the url and use it to pull out the header, content items and footer of the page with the content items being rendered using a template which is also retreived from the database. When running my index file which contains the following code:

    require ("/req/db_connection.php");
    require ("/req/connection.php");
    $dbConnection = new Connection($mysqli_host,$mysqli_user,$mysqli_pass, $mysqli_db);
    $page = new Page();

I get the following output:

    Database connection established

    Warning: mysqli::prepare(): Couldn't fetch Page in C:\xampp\htdocs\forumeq\connection.php on line 39

    Fatal error: Call to a member function bind_param() on a non-object in C:\xampp\htdocs\forumeq\connection.php on line 40

Could anyone point in the right direction as to why I am experiencing these errors?

Line 39 is the following statement:

     $retrieveHead = $this->prepare("SELECT headers FROM pages WHERE page_id=?");

And line 40 is of course:

     $retrieveHead->bind_param('i',$pageId);

Any help would be greatly appreciated.

N.B. The code above has now been corrected based on the answers below however I am still experiencing the following error at line 80:

    Call to a member function bind_param() on a non-object in C:\xampp\htdocs\forumeq\connection.php on line 80

Which is this line:

    $retreiveTemplate->bind_param('i',$template_id);

Any suggestions?

  • 写回答

2条回答 默认 最新

  • duanpanyang1962 2013-02-05 10:37
    关注
    class Page extends Mysqli{
    public function __construct() {
        if(isset($_GET['id'])){
        $id = $_GET['id'];
        }else{      
        $id = 1;
        }       
        $this->get_headers($id);
        $this->get_content($id);
        $this->get_footer($id);
    }
    

    This code above looks like the problem (amongst others). You extend mysqli, override the constructor and do not call the parent constructor. As a result none of the base mysqli constructor routines are invoked and you are left with no connection. Consider redesigning your objects and pass them your Connection object as opposed to extending mysqli everywhere. I'd also try to avoid doing all that work in the constructor. For example your page class could look something like:

    class Page{
    
    private $con;
    
    public function __construct(Connection $con) {
        $this->con = $con;
    }
    
    public function get_headers($pageId){ 
        $retrieveHead = $this->conn->prepare("SELECT headers FROM pages WHERE page_id=?");
        //...
    }
    
    }
    

    When I quipped "amongst others" (no discouragement intended) above I was hinting that -- while the actual cause of your error was the constructor -- there looks to be some confusion in the design of your classes and of OOP concepts in general.

    class Connection extends Mysqli{
    
     public function __construct($mysqli_host,$mysqli_user,$mysqli_pass, $mysqli_db) {
        parent::__construct($mysqli_host,$mysqli_user,$mysqli_pass,$mysqli_db);
        $this->throwConnectionExceptionOnConnectionError();     
     }
    }
    

    Here you have extended mysqli with your Connection class, and correctly called the parent constructor and passed all the required parameters to establish a connection. If you instantiate an object of this type $myConnection = new Connection(...) it can act as your gateway to the database.

    Other classes like Page may need to perform operations on the database and they can do it via Connection not by extending mysqli itself. You can pass an instance of Connection in the Page constructor to achieve this. So your lines of code here:

    $dbConnection = new Connection($mysqli_host,$mysqli_user,$mysqli_pass, $mysqli_db);
    $page = new Page();
    

    Would become (after some modification to Page class like shown above):

    $dbConnection = new Connection($mysqli_host,$mysqli_user,$mysqli_pass, $mysqli_db);
    $page = new Page($dbConnection);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100