致命错误:在非对象上调用成员函数 close()。MySQLi 问题

Fatal error: Call to a member function close() on a non-object. MySQLi issue

提问人:cosmicsafari 提问时间:3/15/2012 最后编辑:Dharmancosmicsafari 更新时间:5/31/2020 访问量:29969

问:

当我上传到实时服务器时,我收到以下错误。它在 localhost 上运行正常,我认为这很奇怪。

致命错误:在非对象上调用成员函数 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;
}
PHP MySQLI

评论

1赞 Crashspeeder 3/15/2012
由于某种原因,$connection->prepare() 似乎失败了。如果它返回 false,则 $stmt 是 false,而不是您预期的 mysqli 对象。
0赞 Churk 3/15/2012
还有一种可能性是,您的$connection也是空的,并且您没有检查它。但这不是你现在的错误
1赞 cmbuckley 3/15/2012
@Churk这将导致致命错误:在非对象上调用成员函数 prepare()。无论哪种方式,我都同意您应该将连接作为参数传入:function getTimes(mysqli $connection) {}
0赞 MrCode 3/15/2012
@cbuckley数据库单例会比将连接作为参数传递给需要数据库的每个函数更好(更易于维护)。喜欢$connection = myDatabase::getInstance();
0赞 cosmicsafari 3/16/2012
@MrCode我从未实现过单例,那么让我的头脑变得容易吗?我才刚刚开始从过程式php转向OOP PHP

答:

3赞 deed02392 3/15/2012 #1

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

现在你需要添加一个子句来处理你的脚本无法准备语句的事实,并且你说这在本地工作,但不能在你的实时服务器上工作,我建议有一些配置差异导致这里出现问题。您需要使用 和 打开错误处理。在让世界看到你的新脚本之前,别忘了关闭它们。:)elsedisplay_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赞 cmbuckley 3/15/2012
+1 在 else 子句中使用一些错误处理将帮助您调试此方案。$connection->error
0赞 cosmicsafari 3/15/2012
谢谢,一旦我将 close() 移动到 if 语句中,它就可以工作了。原来我试图提取当时没有信息的表的信息,这归因于该问题。
4赞 Churk 3/15/2012 #2

你应该把你 if 子句。有一种可能性是,如果(假)并且仍然得到你的$stmt$stmt->close();

2赞 MrCode 3/15/2012 #3

将调用移动到 if 语句中,以便仅在成功创建 a 时才调用该语句。close()$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
    }

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

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

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