首页 文章

致命错误:在布尔值上调用成员函数bind_param()

提问于
浏览
50

我正忙于从数据库获取设置的函数,突然间,我遇到了这个错误:

Fatal error: Call to a member function bind_param() on boolean in C:\xampp2\htdocs\application\classes\class.functions.php on line 16

通常情况下,这意味着我正在从未出现的表和东西中选择内容 . 但在这种情况下,我不是......

这是 getSetting 函数:

public function getSetting($setting)
{
    $query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?');
    $query->bind_param('s', $setting);
    $query->execute();
    $query->bind_result($value, $param);
    $query->store_result();
    if ($query->num_rows() > 0)
    {
        while ($query->fetch()) 
        {
            return $value;
            if ($param === '1')
            {
                $this->tpl->createParameter($setting, $value);
            }
        }
    }
    else
    {
        __('invalid.setting.request', $setting);
    }
}

$this->db 变量通过构造函数传递 . 如有需要,请点击此处:

public function __construct($db, $data, $tpl)
{
    $this->db = $db;
    $this->tpl = $tpl;
    $this->data = $data;
    $this->data->setData('global', 'theme', $this->getSetting('theme'));
}

此外,由于我正在使用数据库,我的数据库连接:

class Database
{
    private $data;

    public function __construct($data)
    {
    $this->data = $data;
    $this->conn = new MySQLi(
      $this->data->getData('database', 'hostname'), 
      $this->data->getData('database', 'username'), 
      $this->data->getData('database', 'password'), 
      $this->data->getData('database', 'database')
    );
    if ($this->conn->errno)
    {
        __('failed.db.connection', $this->conn->errno);
    }
    date_default_timezone_set('Europe/Amsterdam');
}

我已经测试了连接,100%肯定它按预期工作 . 我在配置文件中设置数据库连接:

'database' => array(
    'hostname' => '127.0.0.1',
    'username' => 'root',
    'password' => ******,
    'database' => 'wscript'
)

现在奇怪的是;表存在,请求的设置存在,数据库存在,但仍然,该错误不会离开 . 以下是数据库正确的证据:

IMG

10 回答

  • 18

    问题在于:

    $query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?');
    $query->bind_param('s', $setting);
    

    prepare()方法可以返回 false ,您应该检查它 . 至于为什么它返回 false ,表名或列名(在 SELECTWHERE 子句中)可能不正确?

    另外,请考虑使用类似$this->db->conn->error_list之类的内容来检查解析SQL时发生的错误 . (我确实在那里失败了 . )

  • 99

    任何时候你得到...

    “致命错误:在布尔值上调用成员函数bind_param()”

    ...可能是因为您的查询存在问题 . prepare() 可能会返回 FALSE (布尔值),但是这个通用的失败消息并没有给你带来太大的线索 . 你怎么知道你的查询有什么问题?你问!

    首先,确保错误报告已打开且可见:在打开 <?php 标记后立即将这两行添加到文件顶部:

    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    

    如果您在php.ini中设置了错误报告,则无需担心这一点 . 只需确保您优雅地处理错误,并且永远不会向用户透露任何问题的真正原因 . 向公众展示真正的事业可以为那些想要伤害您的网站和服务器的人提供金色邀请函 . 如果您不想向浏览器发送错误,则可以始终监视Web服务器错误日志 . 日志位置因服务器而异,例如,在Ubuntu上,错误日志通常位于 /var/log/apache2/error.log . 如果您正在检查Linux环境中的错误日志,您可以在控制台窗口中使用 tail -f /path/to/log 来查看实时发生的错误....或者在您创建错误时 .

    一旦您对标准错误报告进行了 balancer ,就会对数据库连接添加错误检查,并且查询将为您提供有关正在进行的问题的更多详细信息 . 看一下列名不正确的示例 . 首先,返回通用致命错误消息的代码:

    $sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
    $query = $mysqli->prepare($sql)); // assuming $mysqli is the connection
    $query->bind_param('s', $definition);
    $query->execute();
    

    该错误是通用的,对您解决正在发生的事情没有多大帮助 .

    通过几行代码,您可以获得非常详细的信息,您可以使用这些信息立即解决问题 . 检查 prepare() 语句是否真实,如果它是好的,您可以继续绑定和执行 .

    $sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
    if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection
        $query->bind_param('s', $definition);
        $query->execute();
        // any additional code you need would go here.
    } else {
        $error = $mysqli->errno . ' ' . $mysqli->error;
        echo $error; // 1054 Unknown column 'foo' in 'field list'
    }
    

    如果出现问题,您可以吐出一条错误消息,直接告诉您该问题 . 在这种情况下,表中没有 foo 列,解决问题是微不足道的 .

    如果选择,您可以在函数或类中包含此检查,并通过如前所述优雅地处理错误来扩展它 .

  • 0

    prepare 仅在失败时返回布尔值 FALSE ,以避免在执行之前首先检查是否为 True 的错误:

    $sql = 'SELECT value, param FROM ws_settings WHERE name = ?';
    if($query = $this->db->conn->prepare($sql)){
        $query->bind_param('s', $setting);
        $query->execute();
        //rest of code here
    }else{
       //error !! don't go further
       var_dump($this->db->error);
    }
    
  • 11

    即使查询语法正确,如果有先前的语句且未关闭, prepare 也可能返回false . 始终关闭您之前的声明

    $statement->close();
    

    如果语法正确,以下查询也将运行良好 .

  • 0

    另一种可能导致此问题的情况是查询中的错误转换 .

    我知道这可能听起来很明显,但我通过使用 tablename 而不是 Tablename 遇到了这个问题 . 检查您的查询,并确保使用与表中列的实际名称相同的大小写 .

  • 1

    有时,它也是因为 wrong table 名称或 column name in the prepare statement .

    看到这个:

    https://www.youtube.com/watch?v=LGHdQ1bBho8

  • 7

    你应该尽可能多地尝试将你的语句总是放在try catch块中...它会在这种情况下一直有用,并会让你知道什么是错的 . 表名或列名可能不对 .

  • 0

    此特定错误与实际错误几乎没有关系 . 这是我的类似经验和解决方案......我在我的语句中使用了一个表,其中包含“| database-name | .login”复合名称 . 我认为这不是问题 . 这确实是问题所在 . 将它括在方括号内解决了我的问题(“[| database-name |] . [login]”) . 所以,问题是MySQL保留的单词(反过来;))...确保你的列也没有失败到这种类型的错误scdenario ...

  • 0

    以下两个是此问题的最可能原因:

    • 在列名或表名中拼写错误

    • 以前 Build 的声明未结束 . 在准备好声明之前先关闭它 .


    $stmt->close(); // <<<-----This fixed the issue for me
    
    $stmt = $conn->prepare("Insert statement");
    
  • 0

    有时显式声明您的表列名称(特别是在插入查询中)可能会有所帮助 . 例如,查询: INSERT INTO tableName(param1,param2,param3) VALUES(?,?,?) 可能更好,而不是: INSERT INTO tableName VALUES(?,?,?)

相关问题