You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用户未传图时WordPress表单出现数组转字符串错误排查

问题:Woocommerce账户设置表单未上传图片时触发数组转字符串错误

我有一个支持用户修改账户设置(含头像)的Woocommerce表单,正常使用无异常,但用户未上传图片就保存设置时,会触发数组转字符串错误。

执行var_dump($attachment_id)得到:

object (WP_Error) #25169 (3) {["errors"] => array(1) {["upload_error"] => array(1) {[0] => string(21) "No file was uploaded. " }} ["error_data"] => array(0) {} ["additional_data": protected] => array (0) {}}

错误发生在以下代码行:

if ( is_wp_error( $attachment_id ) ) {
      // The error occurs on the next line (update_uder_meta)
      update_user_meta( $user_id, 'image', $_FILES['image'] . ": " . $attachment_id->get_error_message() ); 
}

完整代码如下:

// Save Avatar Action
function action_woocommerce_save_account_details( $user_id ) {  
  if ( isset( $_FILES['image'] ) ) {
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    require_once( ABSPATH . 'wp-admin/includes/file.php' );
    require_once( ABSPATH . 'wp-admin/includes/media.php' );

    function wp_set_custom_upload_folder($uploads) {
        $uploads['path'] = $uploads['basedir'] . '/avatar-upload';
        $uploads['url'] = $uploads['baseurl'] . '/avatar-upload';    
        if (!file_exists($uploads['path'])) {
          mkdir($uploads['path'], 0755, true);
        }
        return $uploads;
    }
    add_filter('upload_dir', 'wp_set_custom_upload_folder');    
      
    $attachment_id = media_handle_upload( 'image', 0 );

    if ( is_wp_error( $attachment_id ) ) {
      // The error occurs on the next line (update_uder_meta)
      update_user_meta( $user_id, 'image', $_FILES['image'] . ": " . $attachment_id->get_error_message() ); 

    } else {
      $old_attachment_id = get_user_meta( $user_id, 'image', true );
      wp_delete_attachment($old_attachment_id);
      update_user_meta( $user_id, 'image', $attachment_id );
    } 
    remove_filter('upload_dir', 'wp_set_custom_upload_folder');
  }

}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );

问题原因与修复方案

核心问题

  1. 数组转字符串错误:$_FILES['image']是一个数组,你直接将它与字符串拼接,PHP会强制尝试把数组转为字符串,从而触发报错。
  2. 逻辑不合理:用户未上传图片时,你不需要用错误信息覆盖用户原有的头像设置,反而应该跳过上传逻辑,保留原有数据。
  3. 嵌套函数风险:在action_woocommerce_save_account_details内部定义wp_set_custom_upload_folder,会导致每次执行该函数时都尝试重新定义函数,引发PHP重复定义错误。

修正后的代码

// 自定义上传文件夹(移到外部,避免重复定义)
function wp_set_custom_upload_folder($uploads) {
    $uploads['path'] = $uploads['basedir'] . '/avatar-upload';
    $uploads['url'] = $uploads['baseurl'] . '/avatar-upload';    
    if (!file_exists($uploads['path'])) {
        mkdir($uploads['path'], 0755, true);
    }
    return $uploads;
}

// 保存头像逻辑
function action_woocommerce_save_account_details( $user_id ) {  
    // 仅当存在文件且无上传错误时,才执行上传逻辑
    if ( isset( $_FILES['image'] ) && $_FILES['image']['error'] === UPLOAD_ERR_OK ) {
        require_once( ABSPATH . 'wp-admin/includes/image.php' );
        require_once( ABSPATH . 'wp-admin/includes/file.php' );
        require_once( ABSPATH . 'wp-admin/includes/media.php' );

        add_filter('upload_dir', 'wp_set_custom_upload_folder');    
        $attachment_id = media_handle_upload( 'image', 0 );
        remove_filter('upload_dir', 'wp_set_custom_upload_folder');

        if ( is_wp_error( $attachment_id ) ) {
            // 记录错误日志,不覆盖用户原有头像
            error_log('用户ID ' . $user_id . ' 头像上传失败:' . $attachment_id->get_error_message());
        } else {
            $old_attachment_id = get_user_meta( $user_id, 'image', true );
            if ($old_attachment_id) {
                wp_delete_attachment($old_attachment_id, true); // 同时删除服务器上的旧文件
            }
            update_user_meta( $user_id, 'image', $attachment_id );
        } 
    }
}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );

关键优化点

  • 增加$_FILES['image']['error'] === UPLOAD_ERR_OK判断,确保只有真正上传文件时才执行后续逻辑,避免无文件时触发错误。
  • 移除数组与字符串的错误拼接,改用error_log记录上传错误,不影响用户原有头像设置。
  • 将嵌套函数移到外部,避免重复定义函数的PHP错误。
  • 删除旧头像时增加true参数,确保服务器上的旧文件也被删除。

内容的提问来源于stack exchange,提问作者Snorlax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 08:15:30