在非对象PHP帮助上调用成员函数prepare()

mcb*_*eav 12 php mysqli prepared-statement

我正在尝试编写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();
Run Code Online (Sandbox Code Playgroud)

每当我调用该函数时,我都会收到该错误.有人可以帮忙吗?

irc*_*ell 43

这是一个范围错误.你正在制作$DBH一个全局变量.因此,当您输入函数时,全局变量不可用.你有5个真正的选择.

1.使用global关键字

function doSomething() {
    global $DBH;
    //...
Run Code Online (Sandbox Code Playgroud)

这不是一个好主意,因为它可以维护和测试PITA.想象一下尝试调试该函数调用.你现在需要找出$DBH定义的地方,试图弄清楚发生了什么......

2. $DBH为函数创建一个参数

function doSomething(MySQLi $DBH) {
Run Code Online (Sandbox Code Playgroud)

它具有明确的优点.但它仍然不是很好,因为调用代码需要跟踪全局变量.

3.创建一个"获取" $DBH对象的函数

function getDBH() {
    static $DBH = null;
    if (is_null($DBH)) {
        $DBH = new mysqli(...);
    }
    return $DBH;
}

function doSomething() {
    $DBH = getDBH();
}
Run Code Online (Sandbox Code Playgroud)

这具有完全解决全局变量问题的优点.但是也很难有多个连接或重复使用任何代码用于其他连接.

4.创建一个包装数据库访问的类

class Database {
    public function __construct($host, $user, $pass) {
        $this->DBH = new MySQli($host, $user, $pass);
    }
    public function doSOmething() {
        $this->DBH->foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

这为您封装了一切.所有数据库访问都将通过单个类,因此您无需担心全局变量访问或其他任何问题.

5.使用预先构建的类/框架

这是最好的选择,因为您不必担心自己这样做.

数据库访问类:

完整框架:

真的,选择是无止境的.找到你喜欢的东西,并坚持下去.它真的会让你的生活更轻松......

祝好运!


Jim*_*Jim 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();
}
Run Code Online (Sandbox Code Playgroud)

或者正如ircmaxell在他的优秀答案中指出的那样,它具有一个返回静态实例的函数$DBH.