WordPress6.0扩展WP_List_Table报prepare_items兼容错误解决
WordPress 6.0 扩展WP_List_Table兼容性报错修复
问题现象
自定义插件扩展WP_List_Table类实现列表功能,在旧版本WordPress中运行正常,升级至WordPress 6.0后出现如下报错:
My_Cutsom_Table::prepare_items($additions) must be compatible with WP_List_Table::prepare_items()
相关原有代码
自定义列表类代码
class My_Cutsom_Table extends WP_List_Table { function get_columns() { $columns = array( 'display_name' => 'User', 'user_email' => 'Email', 'company' => 'Company', ); return $columns; } public function prepare_items() { $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); $this->items = $registrations; } function get_sortable_columns() { $sortable_columns = array( 'display_name' => array('display_name', false), 'user_email' => array('user_email', false), 'company' => array('school', false), 'created_at' => array('created_at', false) ); return $sortable_columns; } function column_default($item, $column_name) { if ($column_name == 'edit_delete') { return '<a href="/wp-admin/?page=bsog_events_registrations_delete&event_registration_id=' . $item['id'] . '&event_id=' . $_GET['event_id'] . '">Delete</a> | <a href="/wp-admin/?page=bsog_events_registrations_update&event_registration_id=' . $item['id'] . '&event_id=' . $_GET['event_id'] . '">Edit</a>'; } else { return $item[$column_name]; } } }
外部调用代码
function additions() { global $wpdb; $order_by = ""; $order = ""; $event_id = $_GET['event_id']; //$msg = $_GET['msg']; if (isset($_GET['orderby'])) { $order_by = "ORDER BY " . $_GET['orderby']; } if (isset($_GET['order'])) { $order = $_GET['order']; } $event = get_post($event_id); $table_name_reg = $wpdb->prefix . 'events_registrations'; $table_name_user = $wpdb->prefix . 'users'; $query = "SELECT * FROM `$table_name_reg` AS reg JOIN `$table_name_user` AS u ON `reg`.`user_id` = u.`ID` WHERE `reg`.`event_id`=%d $order_by $order"; $query = $wpdb->prepare($query, [$event_id]); $additions = $wpdb->get_results($query, 'ARRAY_A'); $myListTable = new My_List_Table(); $myListTable->prepare_items($additions); if ($wpdb->num_rows > 0) { $i = 1; include 'views/additions.php'; } else { echo '<div class="wrap"><p>No followers</p></div>'; } die(0); }
报错原因
- WordPress 6.0 版本起强化了核心类方法的签名校验,在PHP 8及以上环境中,子类重写父类方法时,参数规则必须和父类完全匹配,否则会抛出兼容性错误。
- 核心类
WP_List_Table的prepare_items()原生方法没有定义任何入参,但原有代码在调用该方法时传入了$additions参数,将数据传入逻辑绑定到重写的方法上,和父类方法签名不匹配,因此触发报错。 - 原有代码存在类名拼写不一致问题:类定义处写的是
My_Cutsom_Table,实例化时写的是My_List_Table,该拼写问题同样会导致运行异常。 - 原有代码中直接将前端传入的
orderby、order参数拼接进SQL语句,存在SQL注入风险。
修复方案
- 调整
prepare_items方法,移除所有入参,保证方法签名和父类完全一致;新增类属性和set方法用于传入外部查询的列表数据。 - 统一类名拼写,修正实例化时的类名错误。
- 对前端传入的排序参数做安全过滤,避免SQL注入风险。
修复后的列表类代码
// 修正类名拼写 class My_Custom_Table extends WP_List_Table { // 新增私有属性存储列表数据 private $list_data = []; // 新增数据传入方法 public function set_items($data) { $this->list_data = $data; } function get_columns() { $columns = array( 'display_name' => 'User', 'user_email' => 'Email', 'company' => 'Company', ); return $columns; } // 保持和父类方法签名一致:无入参 public function prepare_items() { $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); // 读取预先传入的列表数据赋值 $this->items = $this->list_data; } function get_sortable_columns() { $sortable_columns = array( 'display_name' => array('display_name', false), 'user_email' => array('user_email', false), 'company' => array('school', false), 'created_at' => array('created_at', false) ); return $sortable_columns; } function column_default($item, $column_name) { if ($column_name == 'edit_delete') { return '<a href="/wp-admin/?page=bsog_events_registrations_delete&event_registration_id=' . $item['id'] . '&event_id=' . $_GET['event_id'] . '">Delete</a> | <a href="/wp-admin/?page=bsog_events_registrations_update&event_registration_id=' . $item['id'] . '&event_id=' . $_GET['event_id'] . '">Edit</a>'; } else { return $item[$column_name]; } } }
修复后的调用代码
function additions() { global $wpdb; $order_by = ""; $order = ""; $event_id = intval($_GET['event_id']); if (isset($_GET['orderby'])) { // 对排序字段做安全过滤 $order_by = "ORDER BY " . sanitize_sql_orderby($_GET['orderby']); } if (isset($_GET['order'])) { // 对排序规则做安全过滤 $order = sanitize_text_field($_GET['order']); } $event = get_post($event_id); $table_name_reg = $wpdb->prefix . 'events_registrations'; $table_name_user = $wpdb->prefix . 'users'; $query = "SELECT * FROM `$table_name_reg` AS reg JOIN `$table_name_user` AS u ON `reg`.`user_id` = u.`ID` WHERE `reg`.`event_id`=%d $order_by $order"; $query = $wpdb->prepare($query, [$event_id]); $additions = $wpdb->get_results($query, 'ARRAY_A'); // 实例化时使用和类定义一致的类名 $myListTable = new My_Custom_Table(); // 先传入数据,再调用无参的prepare_items方法 $myListTable->set_items($additions); $myListTable->prepare_items(); if ($wpdb->num_rows > 0) { $i = 1; include 'views/additions.php'; } else { echo '<div class="wrap"><p>No followers</p></div>'; } die(0); }
内容的提问来源于stack exchange,提问作者Newsam
相关产品推荐
相关产品推荐

