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

Posted

技术标签:

【中文标题】在非对象 PHP 帮助中调用成员函数 prepare()【英文标题】:Call to a member function prepare() on a non-object PHP Help 【发布时间】:2011-05-26 16:39:17 【问题描述】:

我正在尝试编写一个 php 函数。这很简单。这只是一个查询数据库的准备好的语句,但我无法让它工作。我不断收到错误 Call to a member function prepare() on a non-object。这是代码:

$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();

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

【问题讨论】:

【参考方案1】:

这是一个范围错误。您正在使 $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.使用预构建的类/框架

这是最好的选择,因为您不必担心自己动手。

数据库访问类:

A quick google search to get you started Doctrine ORM - 具有完整 ORM(对象映射)的完整数据库访问库 ADODB - 与数据库无关的数据库访问库 Pear MDB2 - 另一个数据库访问库

完整的框架:

Zend Framework Lithium Framework Code Igniter (真的还有很多,我不会再麻烦列出了,因为这是另一个问题......)

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

【讨论】:

它对我不起作用:***.com/questions/40080426/…【参考方案2】:

$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 的静态实例。

【讨论】:

谢谢。我将如何使其成为全球性的并且仍然保持安全?我会将连接包装在一个函数中,然后为其分配一个变量,例如 function connect() new myqsli("host", "test", "123456", "dbname") $DBH = new connect(); (连接变量实际上隐藏在另一个文件中。) 是的,我会做一些函数并从那里获取连接。 @ircmaxell 完成。你当然是对的。为每个方法调用建立新连接是个坏主意。【参考方案3】:

尝试在函数中添加global $DBH;,或者添加到函数的参数中。

【讨论】:

【参考方案4】:
selectInfo($DBH);

function selectInfo($DBH,$limit, $offset)
    $stmt = $DBH->prepare("SELECT * FROM information LIMIT ?,?");
    $stmt->bind_param("ii", $limit, $offset);
    $stmt->execute();
    

【讨论】:

【参考方案5】:

这很简单。 $DBH 不存在于 selectInfo() 函数中。在全局范围内定义的变量在函数中不可见,反之亦然。在手册页上阅读有关 variables scope 的更多信息。

如何解决?将该变量作为函数的参数传递:

$dbh = new MySQLi(...);

function selectInfo(MySQLi $dbh, $limit, $offset) 
    $stmt = $dbh->prepare(...);
    ...

【讨论】:

【参考方案6】:

确保连接成功。

$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());

【讨论】:

【参考方案7】:

使 $DBH 全局化并不健康... 除了您可以在类中保护您的 $DBH 并将其设置为 null .. 并使用它..

【讨论】:

【参考方案8】:
class PDOconnect extends PDO

受保护的 $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...";
                  

【讨论】:

以上是关于在非对象 PHP 帮助中调用成员函数 prepare()的主要内容,如果未能解决你的问题,请参考以下文章

PDO 致命错误:在非对象上调用成员函数 prepare()

PHP 致命错误:在第 45 行的 admin\includes\html\database.class.php 中的非对象上调用成员函数 prepare()

致命错误:在非对象 cakephp 上调用成员函数 save()

致命错误:在非对象上调用成员函数 fetch_array()

在非对象上调用成员函数 select() : codeigniter over XAMPP

PHP“致命错误:未捕获错误:调用成员函数prepare()为null”