【问题标题】:Fatal error: Call to a member function bind_param() on boolean [duplicate]致命错误:在布尔值上调用成员函数 bind_param() [重复]
【发布时间】:2015-02-08 06:37:09
【问题描述】:

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

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'
)

现在奇怪的是;表存在,请求的设置存在,数据库存在,但仍然不会出现该错误。这是数据库正确的一些证据:

【问题讨论】:

标签: php mysql mysqli


【解决方案1】:

根据我的经验,bind_param 很好,但我弄错了数据库名称,所以我只更改了连接参数中的数据库名称,它运行良好。

我已经定义了根路径来指示根文件夹,包含文件夹的路径和网站主 URL 的基本 URL。这将用于在需要它们的任何地方调用它们。

【讨论】:

  • 请提供一些代码,让您的回答更有帮助和实用。
【解决方案2】:

有时也是因为错误的表名称或列名称在准备语句中

this

【讨论】:

  • 这是我的问题,错误的表名!希望我早点看到这条评论!
【解决方案3】:

此特定错误与实际错误几乎没有关系。这是我的类似经历和解决方案...

我有一个表,我在我的语句中使用|database-name|.login 复合名称。我以为这不会是个问题。这确实是问题所在。将它括在方括号内解决了我的问题([|database-name|].[login])。所以,问题是 MySQL 保留字(其他方式)...确保您的列也不会出现这种类型的错误场景...

【讨论】:

    【解决方案4】:

    有时明确说明您的表列名称(尤其是在插入查询中)可能会有所帮助。例如查询:

    INSERT INTO tableName(param1, param2, param3) VALUES(?, ?, ?)
    

    可能比以下效果更好:

    INSERT INTO tableName VALUES(?, ?, ?)
    

    【讨论】:

      【解决方案5】:

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

      $stmt = $this->con->prepare("INSERT INTO tester ($test1, $test2) VALUES (?, ?)");

      代替:

      $stmt = $this->con->prepare("INSERT INTO tester (test1, test2) VALUES (?, ?)");

      请注意字段名称前包含$ 的表字段名称。他们不应该在那里,这样$field1 应该是field1

      【讨论】:

        【解决方案6】:

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

        1. 列名或表名中的拼写错误
        2. 先前建立的语句未关闭。只需在准备好的语句之前将其关闭即可。

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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

              【解决方案9】:

              即使查询语法正确,prepare 也可能返回 false,前提是之前有一条语句并且它没有关闭。 总是用

              结束你之前的陈述
              $statement->close();
              

              如果语法正确,下面的查询也会运行良好。

              【讨论】:

                【解决方案10】:

                问题出在:

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

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

                另外,考虑使用$this-&gt;db-&gt;conn-&gt;error_list 之类的东西来检查在解析SQL 时发生的错误。 (我偶尔会回显实际的 SQL 语句字符串并粘贴到 phpMyAdmin 中进行测试,但那里肯定有一些问题。)

                【讨论】:

                • 当出现错误时,如果准备方法返回 false(因此 $query 会为 false?),您为什么建议调用 $query-&gt;error_list
                • @Adam 你说得有道理。如果 bind_param 或执行失败,则调用 $query-&gt;error_list 是有意义的,但如果 $query 为假,则应在 mysqli 对象上调用 errorerror_list,即 $this-&gt;db-&gt;conn-&gt;error_list
                • 当我遇到这个问题时,我从 SQL 查询中删除了 "("。以前是 "SELECT (user_id, price) FROM operations WHERE user_id = 1。正确的版本是 "SELECT user_id, price FROM .. . 当我删除“()”时,我摆脱了这个错误。
                • 这个错误是相当误导的。与其他语言不同,没有指出根本原因。当错误由第一行“prepare”引起时,抛出的错误表明“bind_param”是原因。 Qudos!!
                【解决方案11】:

                任何时候你得到...

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

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

                首先,确保错误报告已打开且可见:将这两行添加到文件顶部,紧跟在打开 &lt;?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 来查看实时发生的错误......或您自己制作的错误。

                一旦您熟悉标准错误报告,在您的数据库连接和查询上添加错误检查将为您提供有关正在发生的问题的更多详细信息。看看这个列名不正确的例子。首先,返回通用致命错误消息的代码:

                $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 列,解决问题很简单。

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

                【讨论】:

                • 非常好的答案,主要是关于错误报告的建议。禁用错误报告的编程就像闭着眼睛下棋一样。人们也不知道如何使用调试器(甚至不知道它确实存在)。
                • 感谢您的出色工作,这对@Jay Blanchard 很有帮助
                • 但是错误是Fatal Error并且死掉了程序,所以关闭显示错误不是很好的解决方案。
                • 同时检查您的用户对您的数据库的权限。如果说您的用户无法进行更新,那么您会收到此错误,但上述(非常好的答案)可能无法解决。
                【解决方案12】:

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

                【讨论】:

                  猜你喜欢
                  • 2017-06-07
                  • 2018-05-06
                  • 2016-09-24
                  • 2017-01-14
                  • 1970-01-01
                  • 2018-03-04
                  • 1970-01-01
                  相关资源
                  最近更新 更多