PHP调用API分析CSV商品描述情感耗时过长问题求助
优化建议
1. 本地缓存API结果(解决重复执行等待的核心方案)
把API返回的结果持久化到本地文件,后续执行直接读取缓存,无需重复请求API,彻底解决代码变更后重新等待的问题:
// 缓存文件路径 $cacheFile = 'sentiment_cache.json'; $response_array = []; // 优先读取缓存 if (file_exists($cacheFile)) { $response_array = json_decode(file_get_contents($cacheFile), true) ?: []; } // 仅处理未缓存的条目 for($x = 1; $x < count($csv_data) - 1; $x++) { // 检查当前条目是否已缓存 $cachedItem = array_filter($response_array, fn($item) => $item[0] == $x); if (!empty($cachedItem)) continue; // 原有API请求逻辑... // 请求成功后写入缓存 if (isset($json["pos"])) { $newItem = [$x, "+" => $json["pos"], "-" => $json["neg"]]; $response_array[] = $newItem; file_put_contents($cacheFile, json_encode($response_array)); } }
2. 使用CURL多句柄实现并行请求
单条串行请求是耗时的主要原因,用curl_multi同时发起多个请求,并行处理能大幅压缩总耗时:
$maxParallel = 5; // 并行请求数,根据API限流规则调整 $active = 0; $multiCurl = curl_multi_init(); $handles = []; // 批量添加请求 for($x = 1; $x < count($csv_data) - 1; $x++) { $api_text = $csv_data[$x][1]; $api_text = str_replace('&', ' and ', $api_text); $postFields = http_build_query(['text' => $api_text]); // 自动URL编码,替代手动替换 $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => "https://text-sentiment.p.rapidapi.com/analyze", CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $postFields, CURLOPT_HTTPHEADER => [ "X-RapidAPI-Host: text-sentiment.p.rapidapi.com", "X-RapidAPI-Key: <snip>", "content-type: application/x-www-form-urlencoded" ], CURLOPT_TIMEOUT => 30, ]); $handles[$x] = $ch; curl_multi_add_handle($multiCurl, $ch); // 控制并行数,防止触发API限流 if (++$active >= $maxParallel) { do { $mrc = curl_multi_exec($multiCurl, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } // 处理剩余请求 do { $mrc = curl_multi_exec($multiCurl, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 等待并获取所有响应 while ($active && $mrc == CURLM_OK) { if (curl_multi_select($multiCurl) != -1) { do { $mrc = curl_multi_exec($multiCurl, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } // 解析响应并整理结果 foreach ($handles as $x => $ch) { $response = curl_multi_getcontent($ch); $err = curl_error($ch); curl_multi_remove_handle($multiCurl, $ch); curl_close($ch); if ($err) { echo "cURL Error #$x:" . $err; continue; } $json = json_decode($response, true); if (isset($json["pos"])) { $response_array[] = [$x, "+" => $json["pos"], "-" => $json["neg"]]; } } curl_multi_close($multiCurl);
3. 复用单个CURL句柄(轻量优化)
如果暂时不想用并行逻辑,至少复用CURL句柄,避免每次初始化/关闭的开销:
// 仅初始化一次CURL $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://text-sentiment.p.rapidapi.com/analyze", CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "X-RapidAPI-Host: text-sentiment.p.rapidapi.com", "X-RapidAPI-Key: <snip>", "content-type: application/x-www-form-urlencoded" ], CURLOPT_TIMEOUT => 30, ]); for($x = 1; $x < count($csv_data) - 1; $x++) { $api_text = $csv_data[$x][1]; $api_text = str_replace('&', ' and ', $api_text); $postFields = http_build_query(['text' => $api_text]); // 仅更新POST字段,复用其他配置 curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields); $response = curl_exec($curl); $err = curl_error($curl); // 后续解析逻辑... } curl_close($curl);
4. 优化CSV读取逻辑
原函数可能读取空行,添加过滤逻辑减少无效循环:
function extract_file($csv) { $file = fopen($csv, 'r'); $lines = []; while (($line = fgetcsv($file, 1000, ',')) !== false) { // 过滤全空的行 if (!empty(array_filter($line))) { $lines[] = $line; } } fclose($file); return $lines; }
5. 检查API批量支持
查看该RapidAPI的官方文档,确认是否支持一次性提交多条文本进行情感分析。如果支持,直接打包所有文本成一个请求,这是效率最高的方式。
内容的提问来源于stack exchange,提问作者S..
相关产品推荐
相关产品推荐

