PHP如何逐个校验函数结果后按序调用多搜索引擎查询函数
问题修复方案
现有代码核心问题
- 变量作用域错误:PHP函数默认使用局部作用域,函数内部无法直接读取外部定义的
$DataNumber变量 - 无返回值:三个校验函数执行完curl请求后没有返回抓取结果,外部调用时拿不到响应内容
- 逻辑不符合需求:当前随机抽取单条数据、随机选择校验函数的逻辑,无法实现「逐条数据按顺序轮询分配到三个搜索引擎、串行执行校验」的要求
- 接口与参数错误:第三个校验函数写的是示例域名而非Yahoo地址,且直接POST原始数据不符合搜索引擎的搜索参数规则,curl未开启跟随跳转无法拿到正常响应
- 函数调用错误:
strstr()缺少必要的查找关键词参数,执行时会直接抛出错误
修正后可直接运行的代码
<?php // 读取待校验数据 $DataCodeFile = __DIR__ . '\datacheck.json'; $DataCode = file_get_contents($DataCodeFile); $DataCode_Data = json_decode($DataCode, true); // 校验结果存储数组 $checkResult = []; /** * Google搜索校验 * @param string $keyword 待查询关键词 * @return string 搜索响应内容 */ function check1(string $keyword): string { $curl_handle = curl_init(); // Google搜索接口,q参数为查询词 curl_setopt($curl_handle, CURLOPT_URL, 'https://www.google.com/search?q=' . urlencode($keyword)); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, 1); // 跟随跳转 curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); // 本地调试可关闭SSL校验,生产环境建议开启 curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); // 模拟浏览器UA避免被拦截 $buffer = curl_exec($curl_handle); curl_close($curl_handle); return $buffer ?: ''; } /** * Bing搜索校验 * @param string $keyword 待查询关键词 * @return string 搜索响应内容 */ function check2(string $keyword): string { $curl_handle = curl_init(); // Bing搜索接口,q参数为查询词 curl_setopt($curl_handle, CURLOPT_URL, 'https://www.bing.com/search?q=' . urlencode($keyword)); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); $buffer = curl_exec($curl_handle); curl_close($curl_handle); return $buffer ?: ''; } /** * Yahoo搜索校验 * @param string $keyword 待查询关键词 * @return string 搜索响应内容 */ function check3(string $keyword): string { $curl_handle = curl_init(); // Yahoo搜索接口,p参数为查询词 curl_setopt($curl_handle, CURLOPT_URL, 'https://search.yahoo.com/search?p=' . urlencode($keyword)); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); $buffer = curl_exec($curl_handle); curl_close($curl_handle); return $buffer ?: ''; } // 按顺序逐条处理所有数据 foreach ($DataCode_Data as $index => $keyword) { // 根据索引对3取模,轮询分配三个搜索引擎:0→Google,1→Bing,2→Yahoo,3→Google以此类推 $engineIndex = $index % 3; $response = ''; $engineName = ''; switch ($engineIndex) { case 0: $response = check1($keyword); $engineName = 'Google'; break; case 1: $response = check2($keyword); $engineName = 'Bing'; break; case 2: $response = check3($keyword); $engineName = 'Yahoo'; break; } // 校验关键词是否存在于搜索结果中,PHP8以下版本可替换为 strpos($response, $keyword) !== false $isFound = str_contains($response, $keyword); $checkResult[] = [ 'keyword' => $keyword, 'engine' => $engineName, 'is_found' => $isFound ]; // 打印当前处理结果 echo "关键词【{$keyword}】通过{$engineName}校验,结果:" . ($isFound ? '已找到' : '未找到') . PHP_EOL; // 循环天然串行执行,当前条处理完成自动进入下一轮,不需要额外等待逻辑 } // 所有数据处理完成后可取消注释查看完整结果 // print_r($checkResult); ?>
关键逻辑说明
- 数据分配规则:遍历所有待校验数据时,用数据索引对3取模的方式轮询分配搜索引擎,完全符合「第一条Google、第二条Bing、第三条Yahoo、第四条回到Google」的需求
- 参数传递:将待查询关键词作为参数传入校验函数,避免全局变量的作用域问题,代码可维护性更高
- 串行执行:用
foreach循环逐条处理数据,上一个函数执行完成拿到结果后,才会进入下一条数据的处理流程,不会出现并发执行的问题 - 结果判断:修复了原代码
strstr参数缺失的问题,直接判断关键词是否存在于返回的页面内容中 - curl配置优化:补充了跟随跳转、模拟浏览器UA、超时时间调整、关键词url编码等配置,避免被搜索引擎反爬拦截、跳转导致拿不到结果的问题
注意:如果本地网络无法直接访问对应搜索引擎,需要在curl配置中添加代理选项,否则会出现请求超时的问题。
内容的提问来源于stack exchange,提问作者mah nasser
相关产品推荐
相关产品推荐

