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

Php 致命错误:在布尔值上调用成员函数bind_param(),php,mysql,mysqli,Php,Mysql,Mysqli,我正忙于从DB获取设置的函数,突然,我遇到了以下错误: 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($sett

我正忙于从DB获取设置的函数,突然,我遇到了以下错误:

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%肯定它能按预期工作。 我正在配置文件中设置DB连接:

'database' => array(
    'hostname' => '127.0.0.1',
    'username' => 'root',
    'password' => ******,
    'database' => 'wscript'
)
现在奇怪的是;表存在,请求的设置存在,数据库存在,但是错误不会消失。这里有一些证据证明DB是正确的:

问题在于:

$query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?');
$query->bind_param('s', $setting);
该方法可以返回
false
,您应该对此进行检查。至于为什么返回
false
,可能是表名或列名(在
SELECT
WHERE
子句中)不正确


还考虑使用一些类似的方法来检查解析SQL时发生的错误。(我偶尔会回显实际的SQL语句字符串,并粘贴到phpMyAdmin中进行测试,但肯定有一些东西失败了。)

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

任何时候你得到

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

…这可能是因为您的查询存在问题。
prepare()
可能返回
FALSE
(一个布尔值),但是这个通用的失败消息不会给您留下太多线索。你如何找出你的问题所在?你问


首先,确保错误报告已打开且可见:在打开
后立即将这两行添加到文件的顶部,即使查询语法正确,prepare也可能返回false,前提是之前有一条语句且未关闭。
始终用以下语句结束您以前的语句

$statement->close();

如果语法正确,以下查询也会正常运行。

另一种可能导致此问题的情况是查询中的不正确强制转换


我知道这听起来很明显,但我是通过使用
tablename
而不是
tablename
实现的。检查您的查询,并确保您使用的大小写与表中列的实际名称相同。

有时,这也是由于prepare语句中的表名或列名错误造成的


请参阅。

您应该尽可能多地将语句放在try-catch块中。。。在这种情况下,它总是有帮助的,它会让你知道哪里出了问题。表名或列名可能是错误的

这一特定错误与实际错误关系不大。以下是我类似的经验和解决方案


我在我的语句中使用了一个带有
|数据库名|的表。登录名
复合名。我以为这不会是个问题。这确实是个问题。将它括在方括号内解决了我的问题(
[|数据库名称|].[login]
)。所以,问题是MySQL保留的单词(反过来说)。。。确保您的列也没有出现此类错误情况…

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

  • 列名或表名中的拼写错误
  • 以前建立的语句未关闭。在做准备好的陈述之前先把它关上


  • $stmt->close();// 有时,明确说明表列名(特别是在insert查询中)可能会有所帮助。例如,查询:

    INSERT INTO tableName(param1, param2, param3) VALUES(?, ?, ?)
    
    可能比以下情况更有效:

    INSERT INTO tableName VALUES(?, ?, ?)
    

    我注意到该错误是由我将表字段名作为变量传递引起的,即我发送了:

    $stmt=$this->con->prepare(“插入测试仪($test1,$test2)值(?)”

    而不是:

    $stmt=$this->con->prepare(“插入测试仪(test1,test2)值(?)”


    请注意字段名之前包含的表字段名
    $
    。它们不应该出现在
    $field1
    应该是
    field1

    根据我的经验,
    bind_参数
    很好,但我弄错了数据库名称,所以我只更改了连接参数中的数据库名称,它工作得很好


    我已经定义了根路径来表示根文件夹,include path来表示包含文件夹,基url表示网站的主url。这将用于在任何需要的地方给他们打电话。

    非常好的回答,主要是关于错误报告的建议。禁用错误报告的编程就像闭着眼睛下棋一样。人们也不知道如何使用调试器(或者调试器确实存在)。感谢您所做的伟大工作,这对@Jay Blanchard非常有帮助,但错误是致命错误并导致程序停止,因此关闭显示错误并不是一个好的解决方案。同时检查用户对数据库的权限。如果你说你的用户不能进行更新,那么你会得到这个错误,但是上面的(非常好的答案)可能不会发现这个错误。如果prepare方法在出现错误时返回false(因此$query将是false?),你为什么建议调用
    $query->error\u list
    。如果绑定参数或执行失败,调用
    $query->error\u list
    是有意义的,但是如果
    $query
    为false,则应该调用mysqli对象上的
    error
    error\u list
    ,即
    $this->db->conn->error\u list
    。当我遇到这个问题时,我删除了它”(“从SQL查询中。上一个是”SELECT)(用户id,价格)来自操作员
    $statement->close();
    
    $stmt->close(); // <<<-----This fixed the issue for me
    
    $stmt = $conn->prepare("Insert statement");
    
    INSERT INTO tableName(param1, param2, param3) VALUES(?, ?, ?)
    
    INSERT INTO tableName VALUES(?, ?, ?)