php 致命错误:在布尔值上调用成员函数 bind_param()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27394710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fatal error: Call to a member function bind_param() on boolean
提问by Exotical
I'm busy on a function that gets settings from a DB, and suddenly, I ran into this error:
我正忙于从数据库获取设置的函数,突然间,我遇到了这个错误:
Fatal error: Call to a member function bind_param() on boolean in C:\xampp2\htdocs\application\classes\class.functions.php on line 16
Normally, this would mean that I'm selecting stuff from unexisting tables and stuff. But in this case, I 'm not...
通常,这意味着我从不存在的表和东西中选择东西。但在这种情况下,我不是...
Here's the getSetting
function:
这是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);
}
}
The $this->db
variable is passed through a constructor. In case of need, here is it:
该$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'));
}
Also, since I'm making use of a database, my database connection:
另外,由于我正在使用数据库,因此我的数据库连接:
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');
}
I've already tested the connection, 100% positive that it works as intended. I'm setting the DB connection things in a configuration file:
我已经测试了连接,100% 肯定它按预期工作。我在配置文件中设置数据库连接的东西:
'database' => array(
'hostname' => '127.0.0.1',
'username' => 'root',
'password' => ******,
'database' => 'wscript'
)
Now the weird thing is; the table exists, the requested setting exists, the DB exists, but still, that error won't leave. Here's some proof that the DB is correct:
现在奇怪的是; 表存在,请求的设置存在,数据库存在,但仍然不会留下该错误。这里有一些证据证明数据库是正确的:
回答by RobP
The problem lies in:
问题在于:
$query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?');
$query->bind_param('s', $setting);
The prepare()
method can return false
and you should check for that. As for why it returns false
, perhaps the table name or column names (in SELECT
or WHERE
clause) are not correct?
该prepare()
方法可以返回false
,您应该检查它。至于为什么它返回false
,也许表名或列名(在SELECT
或WHERE
子句中)不正确?
Also, consider use of something like $this->db->conn->error_list
to examine errors that occurred parsing the SQL. (I'll occasionally echo the actual SQL statement strings and paste into phpMyAdmin to test, too, but there's definitely something failing there.)
此外,请考虑使用类似$this->db->conn->error_list
检查解析 SQL 时发生的错误的方法。(我偶尔会回显实际的 SQL 语句字符串并粘贴到 phpMyAdmin 中进行测试,但肯定会出现问题。)
回答by Jay Blanchard
Any time you get the...
任何时候你得到...
"Fatal error: Call to a member function bind_param() on boolean"
“致命错误:在布尔值上调用成员函数 bind_param()”
...it is likely because there is an issue with your query. The prepare()
might return FALSE
(a Boolean), but this generic failure message doesn't leave you much in the way of clues. How do you find out what is wrong with your query? You ask!
...这可能是因为您的查询存在问题。将prepare()
可能会返回FALSE
(布尔),但这种通用的失败消息不离开你在多线索的方式。你如何找出你的查询有什么问题?你问!
First of all, make sure error reporting is turned on and visible: add these two lines to the top of your file(s) right after your opening <?php
tag:
首先,确保错误报告已打开且可见:将这两行添加到文件顶部,紧跟在开始<?php
标签之后:
error_reporting(E_ALL);
ini_set('display_errors', 1);
If your error reporting has been set in the php.ini you won't have to worry about this. Just make sure you handle errors gracefully and never reveal the true cause of any issues to your users. Revealing the true cause to the public can be a gold engraved invitation for those wanting to harm your sites and servers. If you do not want to send errors to the browser you can always monitor your web server error logs. Log locations will vary from server to server e.g., on Ubuntu the error log is typically located at /var/log/apache2/error.log
. If you're examining error logs in a Linux environment you can use tail -f /path/to/log
in a console window to see errors as they occur in real-time....or as you make them.
如果您的错误报告已在 php.ini 中设置,您就不必担心这一点。只要确保你优雅地处理错误,永远不要向你的用户透露任何问题的真正原因。对于那些想要损害您的网站和服务器的人来说,向公众揭示真正的原因可能是一份刻有金字的邀请。如果您不想向浏览器发送错误,您可以随时监控您的网络服务器错误日志。日志位置因服务器而异,例如,在 Ubuntu 上,错误日志通常位于/var/log/apache2/error.log
. 如果您正在检查 Linux 环境中的错误日志,您可以tail -f /path/to/log
在控制台窗口中使用它们来实时查看错误....或在您制作它们时。
Once you're squared away on standard error reporting adding error checking on your database connection and queries will give you much more detail about the problems going on. Have a look at this example where the column name is incorrect. First, the code which returns the generic fatal error message:
一旦您熟悉标准错误报告,在您的数据库连接和查询上添加错误检查将为您提供有关正在发生的问题的更多详细信息。看看这个列名不正确的例子。首先,返回通用致命错误消息的代码:
$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
$query = $mysqli->prepare($sql)); // assuming $mysqli is the connection
$query->bind_param('s', $definition);
$query->execute();
The error is generic and not very helpful to you in solving what is going on.
该错误是通用的,对您解决正在发生的事情没有很大帮助。
With a couple of more lines of code you can get very detailed information which you can use to solve the issue immediately. Check the prepare()
statement for truthiness and if it is good you can proceed on to binding and executing.
通过多几行代码,您可以获得非常详细的信息,您可以使用这些信息立即解决问题。检查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'
}
If something is wrong you can spit out an error message which takes you directly to the issue. In this case there is no foo
column in the table, solving the problem is trivial.
如果出现问题,您可以吐出一条错误消息,直接将您带到问题。在这种情况下foo
,表中没有列,解决问题是微不足道的。
If you choose, you can include this checking in a function or class and extend it by handling the errors gracefully as mentioned previously.
如果您愿意,您可以在函数或类中包含此检查,并通过如前所述优雅地处理错误来扩展它。
回答by Tamas Kalman
Even when the query syntax is correct, preparecould return false, if there was a previous statement and it wasn't closed. Always close your previous statement with
即使查询语法是正确的,prepare也可能返回 false,如果前面有一个语句并且它没有关闭。总是用
$statement->close();
If the syntax is correct, the following query will run well too.
如果语法正确,以下查询也将运行良好。
回答by meda
prepare
return a boolean only when it fails therefore FALSE
, to avoid the error you need to check if it is True
first before executing:
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);
}
回答by 4ndyG
Another situation that can cause this problem is incorrect casting in your queries.
可能导致此问题的另一种情况是查询中的错误转换。
I know it may sound obvious, but I have run into this by using tablename
instead of Tablename
. Check your queries, and make sure that you're using the same case as the actual names of the columns in your table.
我知道这听起来很明显,但我已经通过使用tablename
而不是Tablename
. 检查您的查询,并确保您使用的大小写与表中列的实际名称相同。
回答by Reejesh PK
回答by Sam Banana
You should always try as much as possible to always put your statements in a try catch block ... it will always help in situations like this and will let you know whats wrong. Perhaps the table name or column name is wrong.
您应该始终尽可能地将您的语句始终放在 try catch 块中……它在这种情况下总是有帮助的,并且会让您知道出了什么问题。也许表名或列名是错误的。
回答by Sam Saarian
This particular error has very little to do with the actual error. Here is my similar experience and the solution...
这个特定的错误与实际错误几乎没有关系。这是我的类似经历和解决方案...
I had a table that I use in my statement with |database-name|.login
composite name. I thought this wouldn't be a problem. It was the problem indeed. Enclosing it inside square brackets solved my problem ([|database-name|].[login]
). So, the problem is MySQL preserved words (other way around)... make sure your columns too are not failing to this type of error scenario...
我在我的语句中使用了一个带有|database-name|.login
复合名称的表。我以为这不会有问题。这确实是问题所在。将它括在方括号内解决了我的问题 ( [|database-name|].[login]
)。所以,问题是 MySQL 保留的单词(其他方式)......确保你的列也没有失败这种类型的错误场景......
回答by ebite Zion
Sometimes explicitly stating your table column names (especially in an insert query) may help. For example, the query:
有时明确说明您的表列名(尤其是在插入查询中)可能会有所帮助。例如,查询:
INSERT INTO tableName(param1, param2, param3) VALUES(?, ?, ?)
may work better as opposed to:
可能效果更好,而不是:
INSERT INTO tableName VALUES(?, ?, ?)
回答by Chrisogonas Odero Mc'Odhiambo
I noticed that the error was caused by me passing table field names as variables i.e. I sent:
我注意到错误是由我将表字段名称作为变量传递引起的,即我发送的:
$stmt = $this->con->prepare("INSERT INTO tester ($test1, $test2) VALUES (?, ?)");
$stmt = $this->con->prepare("INSERT INTO tester ($test1, $test2) VALUES (?, ?)");
instead of:
代替:
$stmt = $this->con->prepare("INSERT INTO tester (test1, test2) VALUES (?, ?)");
$stmt = $this->con->prepare("INSERT INTO tester (test1, test2) VALUES (?, ?)");
Please note the table field names contained $
before field names. They should not be there such that $field1
should be field1
.
请注意包含$
在字段名称之前的表字段名称。他们不应该有这样$field1
应该是field1
。