我正忙于从数据库获取设置的函数,突然间,我遇到了这个错误:
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'
)
现在奇怪的是;表存在,请求的设置存在,数据库存在,但仍然,该错误不会离开 . 以下是DB正确的证明:
11 回答
问题在于:
prepare()方法可以返回
false
,您应该检查它 . 至于为什么它返回false
,表名或列名(在SELECT
或WHERE
子句中)可能不正确?另外,请考虑使用类似$this->db->conn->error_list之类的内容来检查解析SQL时发生的错误 . (我确实在那里失败了 . )
任何时候你得到......
...可能是因为您的查询存在问题 .
prepare()
可能会返回FALSE
(布尔值),但是这个通用的失败消息并没有给您留下太多线索 . 你怎么知道你的查询有什么问题?你问!首先,确保打开并显示错误报告:在打开
<?php
标记后立即将这两行添加到文件的顶部:如果您在php.ini中设置了错误报告,则不必担心这一点 . 只需确保您优雅地处理错误,并且永远不会向用户透露任何问题的真正原因 . 向公众展示真正的事业可以为那些想要伤害您的网站和服务器的人提供金色邀请函 . 如果您不想将错误发送到浏览器,则可以始终监视Web服务器错误日志 . 日志位置因服务器而异,例如,在Ubuntu上,错误日志通常位于
/var/log/apache2/error.log
. 如果您正在检查Linux环境中的错误日志,您可以在控制台窗口中使用tail -f /path/to/log
来查看实时发生的错误....或者在您创建错误时 .一旦您对标准错误报告进行了 balancer ,就会在数据库连接上添加错误检查,并且查询将为您提供有关正在进行的问题的更多详细信息 . 看一下列名不正确的示例 . 首先,返回通用致命错误消息的代码:
该错误是通用的,对您解决正在发生的事情没有多大帮助 .
通过几行代码,您可以获得非常详细的信息,您可以使用这些信息立即解决问题 . 检查
prepare()
语句是否真实,如果它是好的,您可以继续绑定和执行 .如果出现问题,您可以吐出一条错误消息,直接告诉您该问题 . 在这种情况下,表中没有
foo
列,解决问题是微不足道的 .如果选择,您可以在函数或类中包含此检查,并通过如前所述优雅地处理错误来扩展它 .
prepare
仅在失败时返回布尔值FALSE
,以避免在执行之前首先检查是否为True
的错误:即使查询语法正确, prepare 也可能返回false,如果有前一个语句且未关闭 . 始终关闭您之前的声明
如果语法正确,以下查询也将运行良好 .
另一种可能导致此问题的情况是查询中的错误转换 .
我知道这听起来很明显,但我已经通过使用
tablename
而不是Tablename
遇到了这个问题 . 检查您的查询,并确保您使用与表中列的实际名称相同的大小写 .你应该尽可能多地尝试将你的语句总是放在try catch块中......它总是会在这种情况下有所帮助,并会让你知道什么是错的 . 表名或列名可能是错误的 .
以下两个是此问题的最可能原因:
拼写列名或表名中的错误
以前 Build 的声明未结束 . 在准备好陈述之前先关闭它 .
我注意到错误是由于我将表字段名称作为变量传递,即我发送:
$stmt = $this->con->prepare("INSERT INTO tester ($test1, $test2) VALUES (?, ?)");
代替:
$stmt = $this->con->prepare("INSERT INTO tester (test1, test2) VALUES (?, ?)");
请注意,表字段名称包含字段名称前的
$
. 他们不应该在那里$field1
应该field1
.有时显式声明您的表列名称(尤其是在插入查询中)可能会有所帮助 . 例如,查询:
可能会更好,而不是:
此特定错误与实际错误几乎没有关系 . 这是我的类似经历和解决方案......
我有一个表,我在我的声明中使用
|database-name|.login
复合名称 . 我认为这不是问题 . 这确实是问题所在 . 将它括在方括号内解决了我的问题([|database-name|].[login]
) . 所以,问题是MySQL保留的单词(换句话说)...确保你的列也没有失败到这种类型的错误场景......有时候,这也是因为 wrong table 名称或 column name in the prepare statement .
见this .