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

时间:2010-12-16 17:09:23

标签: 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();

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

8 个答案:

答案 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...";
                  }