【问题标题】:Why do I get this function call error on an non-object when I am calling a function on an object? [duplicate]当我在对象上调用函数时,为什么在非对象上出现此函数调用错误? [复制]
【发布时间】:2009-06-05 20:43:54
【问题描述】:

错误:

致命错误:调用成员函数 bind_param() 在一个非对象上 /var/www/web55/web/pdftest/events.php 在第 76 行

代码:

public function countDaysWithoutEvents(){       
    $sql = "SELECT 7 - COUNT(*) AS NumDaysWithoutEvents
            FROM    
            (SELECT d.date 
                FROM cali_events e
                LEFT JOIN cali_dates d
                ON e.event_id = d.event_id
                WHERE YEARWEEK(d.date) = YEARWEEK(CURRENT_DATE())
                AND c.category_id = ?
                GROUP BY DAY(d.date)
            ) AS UniqueDates";
            
    $stmt = $this->link->prepare($sql);
    $stmt->bind_param('i', $this->locationID);
    $stmt->execute();
    
    $stmt->bind_result($count);
    $stmt->close();
    
    return $count;
}

$this->link->prepare($sql) 为 MySQLi 创建一个准备好的语句。

为什么会出现这个错误?

【问题讨论】:

标签: php mysqli prepared-statement


【解决方案1】:

AND c.category_id = ? - 您的查询中没有表别名 c。

除了尝试

$stmt = $this->link->prepare($sql);
if (!$stmt) {
  throw new ErrorException($this->link->error, $this->link->errno);
}

if (!$stmt->bind_param('i', $this->locationID) || !$stmt->execute()) {
  throw new ErrorException($stmt->error, $stmt->errno);
}

【讨论】:

  • +1:当我阅读它时,我没有注意到 c 丢失了。哎呀。
  • 无论如何,该查询都有某种“气味”,至少它似乎如果没有错的话不是最理想的;-)
  • 啊!呸!它应该是 e.category_id。 总台
【解决方案2】:

我认为问题显然在于 prepare 功能..

函数可能失败,在这种情况下,$stmt 将是 FALSE,因此没有 bind_param 方法作为成员。

来自php mysqli manual:
如果发生错误,mysqli_prepare() 返回一个语句对象或 FALSE。

检查您的查询!也许您的 SELECT 语句有问题。在尝试对您认为是 prepare 函数返回的对象执行任何成员函数之前,还要检查 FALSE。

if($stmt === FALSE)
    die("Prepare failed... ");// Handle Error Here

// Normal flow resumes here
$stmt->bind_param("i","");



编辑

我怀疑该语句可能由于子查询而出错:

SELECT d.date 
 FROM cali_events e
 LEFT JOIN cali_dates d
 ON e.event_id = d.event_id
 WHERE YEARWEEK(d.date) = YEARWEEK(CURRENT_DATE())
 AND c.category_id = ?
 GROUP BY DAY(d.date)

相反,你为什么不这样写你的查询:

public function countDaysWithoutEvents()
{
    $count = FALSE;

    $sql  = "SELECT COUNT(d.date) ";
    $sql .= " FROM cali_events e ";
    $sql .= "      LEFT JOIN cali_dates d ON e.event_id = d.event_id ";
    $sql .= " WHERE YEARWEEK(d.date) = YEARWEEK(CURRENT_DATE()) ";
    $sql .= "       AND c.category_id = ? ";
    $sql .= " GROUP BY DAY(d.date) ";

    $stmt = $this->link->prepare($sql);
    if($stmt !== FALSE)
    {                
        $stmt->bind_param('i', $this->locationID);
        $stmt->execute();
        $stmt->bind_result($count);
        $stmt->fetch();                    // I think you need to do a fetch
                                           // here to get the result data..
        $stmt->close();
    }else                                  // Or, provide your own error
        die("Error preparing Statement");  // handling here

    return (7 - $count);
}

附言我认为您也错过了对 fetch 的调用..(参见上面的示例)

【讨论】:

  • 但是查询在控制台中执行得很好
  • 嗯,可能是这样,但这并不意味着 MySQLi 不能抱怨什么。我知道从 PHP 执行 MySQL 代码有一些限制,主要是为了防止 SQL 注入。主要是关于子查询。
  • 我该如何纠正它,子查询确实需要在那里。
  • 不,他们查询返回不准确的结果。我正在计算没有附加事件的天数。
【解决方案3】:

$this->link->prepare 这个语句没有返回对象 所以它给你错误

【讨论】:

    猜你喜欢
    • 2017-07-31
    • 2014-06-14
    • 2019-05-21
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多