count($spiderFiles), 'passed' => 0, 'failed' => 0, 'skipped' => 0, 'start_time' => date('Y-m-d H:i:s'), ]; if (!$isJson) { header('Content-Type: text/plain; charset=utf-8'); echo "╔══════════════════════════════════════════════════════════════╗\n"; echo "║ PHP Spider 批量测试工具 v1.0 ║\n"; echo "╚══════════════════════════════════════════════════════════════╝\n\n"; echo "📁 扫描目录: $dir\n"; echo "📄 发现 " . count($spiderFiles) . " 个待测试文件\n"; echo "⏰ 开始时间: " . $summary['start_time'] . "\n"; echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"; } foreach ($spiderFiles as $index => $file) { $filePath = $dir . DIRECTORY_SEPARATOR . $file; $testResult = [ 'file' => $file, 'status' => 'unknown', 'tests' => [], 'error' => null, 'total_time' => 0, ]; $fileStartTime = microtime(true); if (!$isJson) { $num = $index + 1; echo "┌─────────────────────────────────────────────────────────────┐\n"; echo "│ [$num/" . count($spiderFiles) . "] 测试文件: $file\n"; echo "└─────────────────────────────────────────────────────────────┘\n"; } try { // 使用输出缓冲捕获 require 过程中的输出 ob_start(); // 使用独立的命名空间避免类冲突 $tempFile = $dir . DIRECTORY_SEPARATOR . '.temp_test_' . uniqid() . '.php'; $wrapperCode = ' [ 'timeout' => 15, 'ignore_errors' => true, ] ]); $startTime = microtime(true); $response = @file_get_contents($testUrl, false, $ctx); $cost = round((microtime(true) - $startTime) * 1000, 2); if ($response !== false) { $data = json_decode($response, true); if (json_last_error() === JSON_ERROR_NONE) { $classes = $data['class'] ?? []; $list = $data['list'] ?? []; $testResult['tests']['home'] = [ 'status' => !empty($classes) ? 'pass' : 'warn', 'time' => $cost, 'classes' => count($classes), 'list' => count($list), ]; if (!$isJson) { if (!empty($classes)) { echo " ✅ 首页接口: 通过 (分类: " . count($classes) . ", 耗时: {$cost}ms)\n"; } else { echo " ⚠️ 首页接口: 无分类 (list: " . count($list) . ", 耗时: {$cost}ms)\n"; } } // 如果有分类,继续测试分类接口 if (!empty($classes)) { $tid = $classes[0]['type_id'] ?? null; if ($tid) { $catUrl = "http://$host/$file?t=$tid&ac=detail&pg=1"; $startTime = microtime(true); $catResponse = @file_get_contents($catUrl, false, $ctx); $catCost = round((microtime(true) - $startTime) * 1000, 2); if ($catResponse !== false) { $catData = json_decode($catResponse, true); $catList = $catData['list'] ?? []; $testResult['tests']['category'] = [ 'status' => !empty($catList) ? 'pass' : 'fail', 'time' => $catCost, 'count' => count($catList), ]; if (!$isJson) { if (!empty($catList)) { echo " ✅ 分类接口: 通过 (数据: " . count($catList) . " 条, 耗时: {$catCost}ms)\n"; } else { echo " ❌ 分类接口: 无数据 (耗时: {$catCost}ms)\n"; } } // 如果有数据,继续测试详情接口 if (!empty($catList)) { $vodId = $catList[0]['vod_id'] ?? null; if ($vodId) { $detailUrl = "http://$host/$file?ac=detail&ids=" . urlencode($vodId); $startTime = microtime(true); $detailResponse = @file_get_contents($detailUrl, false, $ctx); $detailCost = round((microtime(true) - $startTime) * 1000, 2); if ($detailResponse !== false) { $detailData = json_decode($detailResponse, true); $detailList = $detailData['list'] ?? []; $hasPlayUrl = !empty($detailList[0]['vod_play_url'] ?? ''); $testResult['tests']['detail'] = [ 'status' => !empty($detailList) ? ($hasPlayUrl ? 'pass' : 'warn') : 'fail', 'time' => $detailCost, 'has_play_url' => $hasPlayUrl, ]; if (!$isJson) { if (!empty($detailList)) { $name = $detailList[0]['vod_name'] ?? '未知'; if ($hasPlayUrl) { echo " ✅ 详情接口: 通过 ($name, 耗时: {$detailCost}ms)\n"; } else { echo " ⚠️ 详情接口: 无播放链接 ($name, 耗时: {$detailCost}ms)\n"; } } else { echo " ❌ 详情接口: 无数据 (耗时: {$detailCost}ms)\n"; } } } } } } } } $testResult['status'] = 'pass'; $summary['passed']++; } else { $testResult['status'] = 'fail'; $testResult['error'] = 'JSON 解析失败: ' . json_last_error_msg(); $summary['failed']++; if (!$isJson) { echo " ❌ 响应解析失败: " . json_last_error_msg() . "\n"; } } } else { $testResult['status'] = 'fail'; $testResult['error'] = 'HTTP 请求失败'; $summary['failed']++; if (!$isJson) { echo " ❌ HTTP 请求失败\n"; } } } else { // Spider 类不存在,直接 require 测试 ob_start(); require_once $filePath; ob_end_clean(); if (!class_exists('Spider')) { throw new Exception("未找到 Spider 类"); } $spider = new Spider(); $spider->init(); // 测试首页 $startTime = microtime(true); $home = $spider->homeContent(true); $cost = round((microtime(true) - $startTime) * 1000, 2); $classes = $home['class'] ?? []; $testResult['tests']['home'] = [ 'status' => !empty($classes) ? 'pass' : 'warn', 'time' => $cost, 'classes' => count($classes), ]; if (!$isJson) { if (!empty($classes)) { echo " ✅ 首页接口: 通过 (分类: " . count($classes) . ", 耗时: {$cost}ms)\n"; } else { echo " ⚠️ 首页接口: 无分类 (耗时: {$cost}ms)\n"; } } $testResult['status'] = 'pass'; $summary['passed']++; } } catch (Throwable $e) { $testResult['status'] = 'error'; $testResult['error'] = $e->getMessage(); $summary['failed']++; if (!$isJson) { echo " ⛔ 错误: " . $e->getMessage() . "\n"; } } $testResult['total_time'] = round((microtime(true) - $fileStartTime) * 1000, 2); $results[] = $testResult; if (!$isJson) { echo " ⏱️ 总耗时: " . $testResult['total_time'] . "ms\n"; echo "\n"; } } $summary['end_time'] = date('Y-m-d H:i:s'); if ($isJson) { header('Content-Type: application/json; charset=utf-8'); echo json_encode([ 'summary' => $summary, 'results' => $results, ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } else { echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"; echo "📊 测试汇总\n"; echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"; echo " 📄 总文件数: " . $summary['total'] . "\n"; echo " ✅ 通过: " . $summary['passed'] . "\n"; echo " ❌ 失败: " . $summary['failed'] . "\n"; echo " ⏭️ 跳过: " . $summary['skipped'] . "\n"; echo " ⏰ 结束时间: " . $summary['end_time'] . "\n"; echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"; }