我正在尝试编写PHP函数。这很简单。它只是一个查询数据库的预准备语句,但我无法使其工作。我一直收到错误调用非对象上的成员函数prepare()。这是代码:
$DBH = new mysqli("host", "test", "123456", "dbname");
function selectInfo($limit, $offset){
$stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
$stmt->bind_param("ii", $limit, $offset);
$stmt->execute();
}
selectInfo();
每当我调用该函数时,我都会收到该错误。有人可以帮忙吗?
答案 0 :(得分:43)
这是一个范围错误。你正在使$DBH
成为一个全局变量。因此,当您输入函数时,全局变量不可用。你有5个真正的选择。
<强> 1。使用全局关键字
function doSomething() {
global $DBH;
//...
这不是一个好主意,因为它可以维护和测试PITA。想象一下尝试调试该函数调用。您现在需要找出定义$DBH
的位置,以试图找出正在发生的事情......
<强> 2。使$DBH
成为函数的参数
function doSomething(MySQLi $DBH) {
它具有明确的优点。但它仍然不是很好,因为调用代码需要跟踪全局变量。
第3。创建一个“获取”$DBH
对象
function getDBH() {
static $DBH = null;
if (is_null($DBH)) {
$DBH = new mysqli(...);
}
return $DBH;
}
function doSomething() {
$DBH = getDBH();
}
这具有完全解决全局变量问题的优点。但是也很难有多个连接或重复使用任何代码用于其他连接。
<强> 4。创建一个包装数据库访问的类
class Database {
public function __construct($host, $user, $pass) {
$this->DBH = new MySQli($host, $user, $pass);
}
public function doSOmething() {
$this->DBH->foo();
}
}
这为您封装了一切。所有数据库访问都将通过一个类,因此您无需担心全局变量访问或其他任何内容。
<强> 5。使用预先构建的类/框架
这是最好的选择,因为您不必担心自己这样做。
数据库访问类:
完整框架:
真的,选择是无止境的。找到你喜欢的东西,并坚持下去。它真的会让你的生活更轻松......
祝你好运!
答案 1 :(得分:7)
$DBH
不在范围内。您要么在函数中将$DBH
定义为全局:
$DBH = new mysqli("host", "test", "123456", "dbname");
function selectInfo($limit, $offset){
global $DBH;
$stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
$stmt->bind_param("ii", $limit, $offset);
$stmt->execute();
}
或者ircmaxell在他的优秀答案中指出了一个返回$DBH
的静态实例的函数。
答案 2 :(得分:3)
尝试在函数中添加global $DBH;
,或将其添加到函数的参数中。
答案 3 :(得分:3)
selectInfo($DBH);
function selectInfo($DBH,$limit, $offset){
$stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
$stmt->bind_param("ii", $limit, $offset);
$stmt->execute();
}
答案 4 :(得分:3)
这很简单。 $DBH
函数中不存在selectInfo()
。在全局范围内定义的变量在函数内不可见,反之亦然。在手册页上阅读有关variables scope的更多信息。
如何解决?将该变量作为函数的参数传递:
$dbh = new MySQLi(...);
function selectInfo(MySQLi $dbh, $limit, $offset) {
$stmt = $dbh->prepare(...);
...
}
答案 5 :(得分:3)
确保连接成功。
$DBH = @new mysqli("host", "test", "123456", "dbname");
if ($DBH->connect_errno) {
die('Connect Error: ' . $DBH->connect_errno);
}
或
$DBH = @mysqli_connect("host", "test", "123456", "dbname");
if (!$DBH ) {
die('Connect Error: ' . mysqli_connect_errno());
}
答案 6 :(得分:0)
让$ DBH全球化并不健康...... 除了你可以在类中保护$ DBH并将其设置为null。 并使用它..
答案 7 :(得分:0)
class PDOconnect extends PDO{
protected $ con = null;
public function __construct(){
try {
$this->con= new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD ); //our new PDO Object
$this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$this->con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
echo "hi.. you are connected succcessfully...";
}