【问题标题】:Call to a member function prepare() on a non-object PHP Help在非对象 PHP 帮助中调用成员函数 prepare()
【发布时间】: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();

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

【问题讨论】:

    标签: php mysqli prepared-statement


    【解决方案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.使用预构建的类/框架

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

    数据库访问类:

    完整的框架:

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

    【讨论】:

    【解决方案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...";
                                }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-05-22
                • 1970-01-01
                • 1970-01-01
                • 2014-09-04
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多