调用未定义的方法stdClass


Call to undefined method stdClass

我偶尔会遇到PHP致命错误:在agent.PHP的第25行调用未定义的方法stdClass::transition()(我在代码中标记了第25行)。这个代码经常被调用,所以很难理解为什么会发生这种情况。

以下是agent.php的片段,它调用

   function agent_exam_complete($exam){
    $ce = $exam->educational();
    $ce->exam_id = $exam->exam_id;
    $ce->exam_grade = $exam->score;
    $ce->exams_remaining -= 1;
    $ce->exam_received_date = sql_now();
    if($exam->status()=='passed'){
        $ce->transition('passed');
    }elseif($ce->exams_remaining <= 0){
        $ce->transition('failed');
    }
    $ce->save();
    if($ce->is_certification_completed($ce->certification_id, $ce->client_no)){
        agent_certification_complete($ce->certification_id, $ce->client_no);
    }
}

function agent_certification_complete($certification_id, $client_no){
    $ce = ClientPurchase::find('first', array('conditions' => "certification_id = '$certification_id' and is_certification = 1 and client_no='$client_no'"));
    $ce->certification_date = date('Y-m-d');
    $ce->transition('passed'); **//Line 25**
    $ce->save();
}

transition()是在另一个文件中定义的,并且经常被调用。我已经包含了一些它的代码,只是为了调味。

function transition($event_tag){
    $old_status = $this->status;
    $next_status = $this->next_status_for_transition($event_tag);
    if($next_status==''){ 
    return; }
    $this->status = $next_status;

我的问题是,为什么我只是周期性地出现这个错误,而不是一直出现?我该怎么做才能为我的客户消除错误和随后的空白屏幕?我只注意到这种情况发生在那些使用Firefox或Chrome的人身上。

提前感谢,Jim

包含函数的对象$ce被多次生成。我想这是因为transition是为调用的任何对象定制的。

为什么不为可重复使用的功能创建另一个对象?考虑扩展函数,使其与所有使用它的对象兼容。

$my = new functionClass;
class functionClass
{
    function transition()
    {
        $old_status = $this->status;
        $next_status = $this->next_status_for_transition($event_tag);
        if($next_status==''){ 
        return; }
        $this->status = $next_status;
    }
}
$my->transition( 'passed' );

这样的事情可以减少不可预测性,我相信可以解决你的问题。

试试这段代码,看看发生了什么:

$ce = false;
$ce->certification_date = date('Y-m-d');
var_dump($ce);

在这种情况下,当您尝试设置属性(certification_date)时,$ce将强制转换为stdClass的对象。

现在您的代码:

function agent_certification_complete($certification_id, $client_no){
    $ce = ClientPurchase::find('first', array('conditions' => "certification_id = '$certification_id' and is_certification = 1 and client_no='$client_no'"));
    //$ce is probably false or null
    //it gets cast to a stdClass object
    $ce->certification_date = date('Y-m-d');
    //stdClass does not have a transition method; ERROR
    $ce->transition('passed'); **//Line 25**
    $ce->save();
}

因此,在您的代码中,如果find()返回null或false,或者可能返回其他一些选择值,那么$ce将被强制转换为下一行的stdClass对象。然后该stdClass对象没有transition()方法,所以您会得到一个错误。要解决此问题,请调整find方法或检查其返回值并进行相应处理。

至于它只发生在特定的浏览器中,我认为这是一个错误的结论。如果find()正在调用一个查询,那么它可能只在特定的时间发生,具体取决于该查询的结果。