mysqli :: prepare()和bind_param()的问题 [英] Issues with mysqli::prepare() and bind_param()

查看:51
本文介绍了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;
}

}
    ?>       

小型应用程序基本上应该从url中获取page变量,并使用它来拉出页面的页眉,内容项和页脚,并使用也从数据库检索到的模板来呈现内容项.运行包含以下代码的索引文件时:

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();

我得到以下输出:

    Database connection established

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

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

有人能指出我为什么会遇到这些错误的正确方向吗?

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

第39行是以下语句:

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

第40行当然是:

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

任何帮助将不胜感激.

上面的代码现在已经根据下面的答案进行了更正,但是我仍然在第80行遇到以下错误:

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\forum\req\connection.php on line 80

这是哪一行:

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

有什么建议吗?

推荐答案

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);
}

上面的代码看起来像是问题(在其他问题中).您扩展了mysqli,覆盖了构造函数,并且不调用父构造函数.结果,没有一个基本的mysqli构造函数例程被调用,并且您没有任何连接.考虑重新设计对象,并将其传递给Connection对象,而不是将mysqli扩展到任何地方.我还将尝试避免在构造函数中完成所有这些工作.例如,您的页面类可能类似于:

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=?");
    //...
}

}

当我在上面打上其他"时(我不劝阻)时,我暗示-尽管错误的真正原因是构造函数-您的类和OOP概念的设计似乎有些混乱一般来说.

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();     
 }
}

在这里,您已使用Connection类扩展了mysqli,并正确调用了父构造函数,并传递了所有必需的参数以建立连接.如果实例化此类型$myConnection = new Connection(...)的对象,则它可以充当数据库的网关.

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.

其他类(例如Page)可能需要对数据库执行操作,并且它们可以通过Connection来实现,而不需要扩展mysqli本身.您可以在Page构造函数中传递Connection的实例以实现此目的.所以您的代码行在这里:

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();

将变为(经过对如上所示的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);

这篇关于mysqli :: prepare()和bind_param()的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆