【问题标题】:Fatal error: Call to a member function close() on a non-object. MySQLi issue致命错误:在非对象上调用成员函数 close()。 MySQLi 问题
【发布时间】:2012-04-01 02:30:19
【问题描述】:

当我上传到实时服务器时,我遇到了以下错误。它在我认为很奇怪的本地主机上工作正常。

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

它所指的线

$stmt->close();

与数据库的连接

$connection=new mysqli($MYSQL_HOST,$MYSQL_USER,$MYSQL_PASS,$DB)or die(mysqli_error($connection));

类本身。

function getTimes(){ //this method just pulls the results of the query and returns them as an array
    global $connection;
    $route = $this->route;
    $station = $this->station;
    $day = $this->day;

    // create a prepared statement
    if ($stmt = $connection->prepare("select time from timetable where route=? and day=? and station=?")) {
        $stmt->bind_param("sss", $route, $day, $station);   // bind parameters for markers
        $stmt->execute();   //execute query             
        $stmt->bind_result($col1);  //bind result variables
        while ($stmt->fetch()){
            $results[]=$col1;
        }
    }
    $stmt->close();//close statement
    return $results;
}

【问题讨论】:

  • 看起来 $connection->prepare() 由于某种原因失败了。如果它返回 false 则 $stmt 为 false,而不是您预期的 mysqli 对象。
  • 您的 $connection 也有可能为空,而您没有检查它。但这不是你目前的错误
  • @Churk 这将导致致命错误:在非对象上调用成员函数 prepare()。无论哪种方式,我都同意您应该将连接作为参数传递:function getTimes(mysqli $connection) {}
  • @cbuckley 数据库单例会比将连接作为参数传递给需要数据库的每个函数更好(更易于维护)。喜欢$connection = myDatabase::getInstance();
  • @MrCode 我从来没有实现过单例,这很容易让我明白吗?我才刚刚开始从程序 php 转向 OOP PHP

标签: php class mysqli


【解决方案1】:

您应该将$stmt 放入您的 if 子句中。有一种可能性是 if (false) 仍然可以访问您的 $stmt->close();

【讨论】:

    【解决方案2】:

    您的问题是 $stmt 对象被实例化为 if 条件测试的一部分。在它失败的情况下,即当它返回 false 时,你仍然试图在它上面调用 ->close()。我在if 块中移动了方法调用。

    现在您需要添加一个else 子句来处理您的脚本无法准备语句的事实,并且假设您说这在本地工作但不能在您的实时服务器上工作,我建议存在一些配置差异导致问题这里。您需要使用display_errors('1')error_reporting(E_ALL) 打开错误处理。不要忘记在让世界看你的新剧本之前关闭这些功能。 :)

    function getTimes(){ //this method just pulls the results of the query and returns them as an array
            global $connection;
            $route = $this->route;
            $station = $this->station;
            $day = $this->day;
    
            // create a prepared statement
            if ($stmt = $connection->prepare("select time from timetable where route=? and day=? and station=?")) {
                $stmt->bind_param("sss", $route, $day, $station);   // bind parameters for markers
                $stmt->execute();   //execute query             
                $stmt->bind_result($col1);  //bind result variables
                while ($stmt->fetch()){
                    $results[]=$col1;
                }
                $stmt->close();//close statement
            }
    
            return $results;
        }
    

    【讨论】:

    • +1 在 else 子句中使用 $connection->error 进行一些错误处理将帮助您调试此场景。
    • 谢谢,一旦我将 close() 移到 if 语句中,它就会起作用。原来我正试图为一个当时没有信息的表格提取信息,这归因于该问题。
    【解决方案3】:

    close() 调用移动到您的 if 语句中,这样只有在成功创建 $stmt 时才会调用它。

        // create a prepared statement
        if ($stmt = $connection->prepare("select time from timetable where route=? and day=? and station=?")) {
            $stmt->bind_param("sss", $route, $day, $station);   // bind parameters for markers
            $stmt->execute();   //execute query             
            $stmt->bind_result($col1);  //bind result variables
            while ($stmt->fetch()){
                $results[]=$col1;
            }
            $stmt->close();//close statement
        }
    

    我怀疑在您的本地计算机上您没有打开错误,但在您上传到的服务器上,错误已打开。

    这里要解决的根本问题是prepare() 失败了。问题很可能是服务器上的数据库缺少timetable 表,或者该表缺少一个或多个字段routedaystation。正如 cbuckley 所说,请查看 $connection->error 以获取完整的错误消息。

    当您上传到服务器时,您是否还记得在服务器上进行任何数据库结构更改?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 2013-11-25
      • 2012-05-30
      • 2016-08-30
      • 2015-02-06
      相关资源
      最近更新 更多