PHP 8中strftime()触发TypeError:传入字符串而非整数时间戳
WooCommerce订单自提日期列PHP8兼容问题修复
这段代码用于在WooCommerce订单列表添加「Afhaaldatum(自提日期)」列,在PHP7.4运行正常,但PHP8下触发致命错误,核心原因是strftime()函数在PHP8中强制要求第二个参数为?int类型(整数或null),但从订单配送项元数据中获取的_pickup_appointment_start可能是字符串(甚至空字符串),不符合参数类型要求。
原代码
// Add a Header function filter_manage_edit_shop_order_columns( $columns ) { // Add new column $columns['pickup_date'] = 'Afhaaldatum'; return $columns; } add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 ); // Populate the Column function action_manage_shop_order_posts_custom_column( $column, $post_id ) { // Compare if ( $column == 'pickup_date' ) { // Get order $order = wc_get_order( $post_id ); // Loop though order shipping methods foreach( $order->get_items('shipping') as $shipping_item ) { // Get appoitment start $pickup_appointment_start = $shipping_item->get_meta( '_pickup_appointment_start' ); date_default_timezone_set('Europe/Amsterdam'); /* Set locale to Dutch */ setlocale(LC_ALL, 'nl_NL'); $startdate = strftime('%e %B %Y om %H:%M uur', $pickup_appointment_start ); if(!empty($startdate)) echo '<p>' .$startdate. '</p>'; // Testing (to be removed) - Empty value case else echo '<small>-</small>'; break; } } } add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );
错误信息
Fatal error: Uncaught TypeError: strftime(): Argument #2 ($timestamp) must be of type ?int, string given in /home/website/domains/WEBSITEX/public_html/debug/wp-content/plugins/insert-php/includes/class.execute.snippet.php(635) : eval()'d code:29 Stack trace: #0 /home/website/domains/WEBSITEX/public_html/debug/wp-content/plugins/insert-php/includes/class.execute.snippet.php(635) : eval()'d code(29): strftime('%e %B %Y om %H:...', '') #1 /home/website/domains/WEBSITEX/public_html/debug/wp-includes/class-wp-hook.php(308): action_manage_shop_order_posts_custom_column('pickup_date', 49721) #2 /home/website/domains/WEBSITEX/public_html/debug/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters(NULL, Array) #3 /home/website/domains/WEBSITEX/public_html/debug/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #4 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/includes/class-wp-posts-list-table.php(1363): do_action('manage_shop_ord...', 'pickup_date', 49721) #5 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/includes/class-wp-list-table.php(1532): WP_Posts_List_Table->column_default(Object(WP_Post), 'pickup_date') #6 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/includes/class-wp-posts-list-table.php(1397): WP_List_Table->single_row_columns(Object(WP_Post)) #7 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/includes/class-wp-posts-list-table.php(807): WP_Posts_List_Table->single_row(Object(WP_Post), 0) #8 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/includes/class-wp-posts-list-table.php(783): WP_Posts_List_Table->_display_rows(Array, 0) #9 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/includes/class-wp-list-table.php(1444): WP_Posts_List_Table->display_rows() #10 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/includes/class-wp-list-table.php(1371): WP_List_Table->display_rows_or_placeholder() #11 /home/website/domains/WEBSITEX/public_html/debug/wp-admin/edit.php(487): WP_List_Table->display() #12 {main} thrown in /home/website/domains/WEBSITEX/public_html/debug/wp-content/plugins/insert-php/includes/class.execute.snippet.php(635) : eval()'d code on line 29
修复方案
核心修改点:
- 类型验证与转换:先检查
$pickup_appointment_start是否为有效数字,再转换为整数类型,避免传入字符串/空值给strftime - 提前判断空值:在调用strftime前先判断元数据是否存在且有效,避免无效调用
- 优化性能:将时区和区域设置移到函数外部,避免每次渲染列时重复执行
修改后的代码
// 全局设置时区和区域,只需执行一次 date_default_timezone_set('Europe/Amsterdam'); setlocale(LC_ALL, 'nl_NL'); // Add a Header function filter_manage_edit_shop_order_columns( $columns ) { $columns['pickup_date'] = 'Afhaaldatum'; return $columns; } add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 ); // Populate the Column function action_manage_shop_order_posts_custom_column( $column, $post_id ) { if ( $column !== 'pickup_date' ) { return; } $order = wc_get_order( $post_id ); $display_date = '<small>-</small>'; // 默认空值显示 foreach( $order->get_items('shipping') as $shipping_item ) { $pickup_appointment_start = $shipping_item->get_meta( '_pickup_appointment_start' ); // 验证值是否为有效整数(或可转换为整数的字符串) if ( is_numeric($pickup_appointment_start) && (int)$pickup_appointment_start > 0 ) { $timestamp = (int)$pickup_appointment_start; $display_date = '<p>' . strftime('%e %B %Y om %H:%M uur', $timestamp) . '</p>'; } break; // 只取第一个配送项 } echo $display_date; } add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );
说明:
- 提前设置时区和区域,避免在循环中重复执行,提升性能
- 先判断列是否匹配,不匹配直接返回,减少不必要的执行
- 对元数据做严格的数字验证,确保转换为整数后再传给strftime
- 预设默认显示内容,避免多次echo分支判断
内容的提问来源于stack exchange,提问作者Suikerspin
相关产品推荐
相关产品推荐

