我偶尔会遇到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()
正在调用一个查询,那么它可能只在特定的时间发生,具体取决于该查询的结果。