PHP解决WordPress向Google Sheet批量同步数据的31秒读取超时问题
WordPress用户批量同步Google Sheet超时问题解决方案
问题背景
将WordPress用户信息同步至Google Sheet时,单用户同步正常,但批量调用updateUsersToSheet($api_url)时仅部分用户同步成功,服务器报错:
read data timeout in 31 seconds
已设置ini_set('max_execution_time', 900)和ini_set('default_socket_timeout', 900),但问题依旧。
优化解决方案
1. 批量发送数据+改用POST请求(最优先推荐)
当前代码每个用户发起一次GET请求,频繁的HTTP握手和Google Sheet写入操作是超时核心原因。改为批量打包用户数据,一次性POST到Web App,大幅减少请求次数和Sheet操作次数:
修改PHP端代码
function updateUsersToSheet($api_url,$ids = NULL){ $userDataList = []; if (!isset($ids)) { $users = get_users(); $admins = [1,7,29,30,35,40]; foreach ($users as $user ){ if (!in_array($user->ID,$admins)) { $userDataList[] = getWPUserData($user); } } } else { $ids = is_array($ids)?$ids:array($ids); foreach($ids as $id) { $user = get_user_by('ID',$id); $userDataList[] = getWPUserData($user,1); } } // 批量发送数据 sendBatchPostToSheet($userDataList,$api_url); } function sendBatchPostToSheet($dataList,$api_url){ $options = [ 'method' => 'POST', 'headers' => ['Content-Type' => 'application/json'], 'body' => json_encode($dataList) ]; // 使用WordPress内置的WP_Http更稳定 $response = wp_remote_post($api_url, $options); if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) { mylogfunction(wp_remote_retrieve_body($response)); } else { $errorMsg = is_wp_error($response) ? $response->get_error_message() : 'HTTP Code: '.wp_remote_retrieve_response_code($response); wp_mail('shenkwen@gmail.com', '批量同步Sheet失败', $errorMsg, ['Content-Type: text/html; charset=UTF-8']); } }
修改Google Apps Script端代码
替换doGet为doPost,接收批量数据后一次性写入Sheet:
function doPost(e) { const userSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('你的工作表名称'); const dataList = JSON.parse(e.postData.contents); // 转换为Sheet需要的二维数组格式 const rows = dataList.map(item => [ item.last_name, item.first_name, item.phone, item.email, item.degree, item.roles, item.church, item.cn_name, item.bday, item.gender ]); // 找到最后一行的下一行开始写入 const lastRow = userSheet.getLastRow(); userSheet.getRange(lastRow + 1, 1, rows.length, rows[0].length).setValues(rows); return ContentService.createTextOutput(JSON.stringify({status: 'success', count: rows.length})); }
2. 异步分批处理(适合超大量用户)
如果用户数量超过100+,可以用WordPress的WP Cron定时分批同步,避免单次请求超时:
function sync_users_in_batches($api_url, $batchSize = 20) { $admins = [1,7,29,30,35,40]; $users = get_users(['exclude' => $admins]); $total = count($users); $batches = array_chunk($users, $batchSize); // 清除已有定时任务 wp_clear_scheduled_hook('sync_single_user_batch'); foreach ($batches as $index => $batch) { $userIds = wp_list_pluck($batch, 'ID'); // 延迟执行每个批次,间隔1分钟 wp_schedule_single_event(time() + ($index * 60), 'sync_single_user_batch', [$api_url, $userIds]); } } // 注册钩子处理单个批次 add_action('sync_single_user_batch', function($api_url, $userIds) { $userDataList = []; foreach($userIds as $id) { $user = get_user_by('ID',$id); $userDataList[] = getWPUserData($user,1); } sendBatchPostToSheet($userDataList,$api_url); }, 10, 2);
调用方式:sync_users_in_batches($api_url);
3. 优化Google Apps Script执行效率
- 关闭Sheet自动计算:处理前关闭,完成后恢复
function doPost(e) { const ss = SpreadsheetApp.getActiveSpreadsheet(); // 关闭自动计算 ss.setCalculationMode(SpreadsheetApp.CalculationMode.MANUAL); const userSheet = ss.getSheetByName('你的工作表名称'); // ... 处理数据写入逻辑 ... // 恢复自动计算 ss.setCalculationMode(SpreadsheetApp.CalculationMode.AUTOMATIC); return ContentService.createTextOutput(JSON.stringify({status: 'success'})); }
4. 添加请求重试机制
针对偶尔的网络超时,在PHP请求中添加重试逻辑:
function sendBatchPostToSheet($dataList,$api_url,$retryTimes = 3){ $options = [ 'method' => 'POST', 'headers' => ['Content-Type' => 'application/json'], 'body' => json_encode($dataList), 'timeout' => 60 // 单次请求超时时间 ]; $attempts = 0; do { $response = wp_remote_post($api_url, $options); $attempts++; if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) { mylogfunction(wp_remote_retrieve_body($response)); return true; } // 重试前等待2秒 sleep(2); } while ($attempts < $retryTimes); // 所有重试失败发送邮件 $errorMsg = is_wp_error($response) ? $response->get_error_message() : 'HTTP Code: '.wp_remote_retrieve_response_code($response); wp_mail('shenkwen@gmail.com', '批量同步Sheet重试失败', $errorMsg, ['Content-Type: text/html; charset=UTF-8']); return false; }
内容的提问来源于stack exchange,提问作者shenkwen
相关产品推荐
相关产品推荐

