在现代软件开发中,自动化数据收集和同步是提高效率的关键。今天,我将分享一个我最近开发的PHP脚本,它能够自动从GitHub API搜索特定关键词的仓库,并将这些数据同步到MySQL数据库中。这个过程不仅涉及到API调用和数据处理,还包括数据库操作和错误管理。让我们一步步深入了解这个脚本的实现。
关键词的筛选
首先,我定义了一个关键词数组,这些关键词是我希望通过GitHub API搜索的。这些关键词主要是与安全漏洞相关的CVE和CNVD标识符。
$keywords = ['CVE-2020', 'CVE-2021', 'CVE-2022', 'CVE-2023', 'CVE-2024', 'CNVD-'];
授权GitHub API访问
为了与GitHub API进行交互,我需要一个访问令牌。这个令牌是与GitHub账户关联的安全凭证,用于验证API请求的身份。出于安全考虑,我建议不要在代码中硬编码这个令牌,而是通过环境变量或其他安全措施来管理。
$accessToken = 'YOUR_GITHUB_ACCESS_TOKEN';
数据库连接配置
接下来,我配置了数据库连接信息,包括数据源名称、用户名和密码。这些信息同样需要保密,并且在生产环境中应该使用更安全的方法来存储和访问。
$dsn = 'mysql:host=localhost;dbname=your_database;charset=utf8';
$username = 'your_username';
$password = 'your_password';
创建PDO数据库连接
使用PDO(PHP Data Objects)扩展,我创建了一个数据库连接实例。PDO提供了一个数据访问抽象层,这意味着我可以轻松地切换到不同的数据库系统,而不需要修改太多的代码。
$pdo = new PDO($dsn, $username, $password);
初始化操作计数器
为了跟踪脚本的执行情况,我初始化了两个计数器:一个用于记录成功插入数据库的记录数,另一个用于记录遇到的错误数。
$successCount = 0;
$errorCount = 0;
遍历关键词与分页搜索
我遍历每个关键词,并构建GitHub API的搜索URL。为了不超出API的速率限制,我实现了分页逻辑,最多搜索50页。
foreach ($keywords as $keyword) {
for ($page = 1; $page <= 50; $page++) {
$url = "https://api.github.com/search/repositories?q=" . urlencode($keyword) . "&per_page=100&page=$page";
// ...
}
}
设置HTTP请求头
在发送HTTP请求之前,我设置了请求头,包括User-Agent和Authorization(Bearer Token),这是GitHub API要求的。
$options = [
"http" => [
"header" => "User-Agent: My PHP Script\r\n" .
"Authorization: Bearer $accessToken"
]
];
发送请求并处理响应
使用file_get_contents函数,我发送HTTP请求并获取响应。如果请求失败,我会输出错误信息并增加错误计数。
$response = file_get_contents($url, false, $context);
if ($response === false) {
echo "错误:无法从 GitHub API 获取数据,关键词:$keyword\n";
$errorCount++;
continue;
}
解析JSON响应与数据库操作
我将JSON响应解析为数组,并检查是否找到了搜索结果。对于每个结果,我检查数据库中是否已存在相同的仓库地址,如果不存在,则将其插入数据库。
$result = json_decode($response, true);
if (isset($result['items'])) {
foreach ($result['items'] as $item) {
// ...
$stmt = $pdo->prepare("INSERT INTO github_monitor (repo_name, repo_url, description, created_at) VALUES (?, ?, ?, ?)");
$result = $stmt->execute([$repoName, $repoUrl, $description, $createdAt]);
// ...
}
}
错误处理与分页逻辑
如果单页的结果少于100条,我假设已经获取了所有结果,并结束分页。
if (count($result['items']) < 100) {
break;
}
输出执行总结
最后,我输出了成功插入的仓库数和遇到的错误总数,以便了解脚本的执行效果。
echo "总共成功插入的仓库数:$successCount\n";
echo "遇到的错误总数:$errorCount\n";
在前端的呈现
总结与改进
通过这个脚本,我实现了自动化的数据收集和同步。然而,还有改进的空间,比如增强安全性、优化错误处理、提升性能和代码重构。这些改进将使脚本更加健壮和易于维护。
通过这篇文章,我希望能够分享我的实践经验,并为其他开发者提供一些有价值的见解。