Yii框架TbGridView调用类函数报执行超时错误如何解决
一、TbGridView 配置中调用其他类函数的实现方式
TbGridView 是 Yii1 版本 Bootstrap 扩展的表格组件,列配置中调用外部类方法有两种通用写法:
- 匿名函数写法(PHP 5.3及以上版本推荐)
在列的value配置项中传入闭包,闭包接收两个参数:$data为当前行的模型实例,$row为行序号,闭包内可以直接调用任意类的方法:
'columns' => [ [ 'header' => '内容列', 'type' => 'raw', // 若返回内容含HTML必须加此配置,否则标签会被转义为普通文本 'value' => function($data, $row) { // 调用其他类的静态方法 $html = HtmlHelper::buildRowHtml($data); // 调用实例方法 // $service = new ScrapeService(); // $html .= $service->getStatusTag($data->status); return $html; } ] ]
- 数组回调写法(兼容低版本PHP)
如果运行环境PHP版本低于5.3不支持闭包,可以直接把符合回调格式的数组传入value,注意对应回调方法必须接收$data、$row两个入参:
'columns' => [ [ 'name' => 'number', 'type' => 'raw', 'value' => ['ResultFormatter', 'formatNumberColumn'] ] ] // 对应外部类的方法定义 class ResultFormatter { public static function formatNumberColumn($data, $row) { return '<div class="row-fluid"><span class="num">'.$data->number.'</span></div>'; } }
二、执行超时错误排查解决
报错指向Result.php第57行,结合GridView渲染的场景,按以下优先级排查即可解决:
- 优先排查死递归问题
你贴的代码片段里有return $result->number;的逻辑,90%的同类报错都是模型里的属性访问/自定义方法触发了无限递归。最典型的错误是在模型的魔术方法、属性getter、关系定义里,访问了会触发自身调用的属性:
// 错误写法:访问$this->number会自动调用getNumber(),形成死循环直到超时 public function getNumber() { return $this->number; }
如果是这类问题,直接修改属性读取逻辑,避免自调用即可:
// 正确写法 public function getNumber() { return $this->getAttribute('number'); }
排查时可以在报错行打印debug_backtrace(),如果调用栈里反复出现同一个方法,就能确认是死递归。
2. 检查是否关闭了分页一次性加载全量数据
如果手动把TbGridView的分页关闭,当Result表数据量达到几千上万条时,数据查询+渲染的耗时很容易超过120秒上限。检查你的dataProvider配置,不要把pagination设为false,配置合理的每页条数:
// 数据提供器配置示例 new CActiveDataProvider('Result', [ 'criteria' => $criteria, 'pagination' => [ 'pageSize' => 20, // 不要设pageSize=0关闭分页 ] ]);
- 排查列渲染时的重复耗时操作
如果在每一列的value回调里执行了数据库查询、HTTP请求、大文件读取这类耗时操作,比如每页20条就要执行20次重复查询,累计耗时很容易超时。这类逻辑要提前在数据查询阶段批量处理完,不要放到渲染层循环执行。
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

