改前

改后

<?php
header('Content-Type: application/json');

// 包含配置文件
include 'config.php';

try {
    // 从数据库获取DeepSeek API密钥
    $stmt = $pdo->prepare("SELECT config_value FROM user_configs WHERE config_key = ?");
    $stmt->execute(['deepseek_api_key']);
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    
    $apiKey = $result['config_value'] ?? '';
    
    // 检查API密钥是否存在
    if (!$apiKey || $apiKey === '') {
        http_response_code(401);
        echo json_encode(['error' => 'API密钥未配置或为空']);
        exit;
    }
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['error' => '获取API密钥失败: ' . $e->getMessage()]);
    exit;
}

$postData = json_decode(file_get_contents('php://input'), true);

// 检查是否接收到数据
if (!$postData) {
    http_response_code(400);
    echo json_encode(['error' => '无效的请求数据']);
    exit;
}

$ch = curl_init('https://api.deepseek.com/v1/chat/completions');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $apiKey
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);

// 检查cURL是否出错
if ($error) {
    http_response_code(500);
    echo json_encode(['error' => '请求失败: ' . $error]);
    exit;
}

// 检查HTTP状态码
if ($httpCode !== 200) {
    http_response_code($httpCode);
    // 尝试解析响应,如果无法解析则返回原始响应
    $decodedResponse = json_decode($response, true);
    if ($decodedResponse === null) {
        echo json_encode(['error' => 'API请求失败,状态码: ' . $httpCode, 'details' => $response]);
    } else {
        echo json_encode(['error' => 'API请求失败,状态码: ' . $httpCode, 'details' => $decodedResponse]);
    }
    exit;
}

// 直接输出API响应
echo $response;
?>
// 修改前端调用地址
const response = await fetch('./keyinfoapi/deepseek_proxy.php', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        // 原始请求数据
    })
});
这段代码是 [deepseek_proxy.php](file://e:\code\llm-findwork\keyinfoapi\deepseek_proxy.php) 的核心部分,用于从数据库获取API密钥。让我详细解释一下:

## 代码解释

```php
$stmt = $pdo->prepare("SELECT config_value FROM user_configs WHERE config_key = ?");
$stmt->execute(['deepseek_api_key']);
$result = $stmt->fetch(PDO::FETCH_ASSOC);

$apiKey = $result['config_value'] ?? '';
```

### 逐行分析:

1. **准备SQL查询语句**:
   ```php
   $stmt = $pdo->prepare("SELECT config_value FROM user_configs WHERE config_key = ?");
   ```
   - 使用 `$pdo->prepare()` 创建一个预处理语句
   - 查询 `user_configs` 表中 `config_key` 等于特定值的记录
   - `?` 是占位符,用于安全地插入参数,防止SQL注入攻击

2. **执行查询**:
   ```php
   $stmt->execute(['deepseek_api_key']);
   ```
   - 执行预处理语句,将 `'deepseek_api_key'` 作为参数传入
   - 这会查找 `config_key` 为 `'deepseek_api_key'` 的记录

3. **获取查询结果**:
   ```php
   $result = $stmt->fetch(PDO::FETCH_ASSOC);
   ```
   - 使用 `fetch()` 方法获取查询结果的第一行
   - `PDO::FETCH_ASSOC` 参数表示以关联数组形式返回结果
   - 返回的数组格式类似于:`['config_value' => '实际的API密钥']`

4. **提取API密钥值**:
   ```php
   $apiKey = $result['config_value'] ?? '';
   ```
   - 从结果数组中提取 `config_value` 字段的值
   - 使用空合并操作符 `??` 确保即使 `$result` 为空也不会出错
   - 如果 `$result` 为空或不包含 `config_value` 键,则默认为空字符串

## 整体流程

1. 从数据库 `user_configs` 表中查找 `config_key` 为 `'deepseek_api_key'` 的记录
2. 获取该记录的 `config_value` 字段值(即实际的API密钥)
3. 将获取到的API密钥存储在 `$apiKey` 变量中供后续使用

## 安全特性

- 使用预处理语句防止SQL注入攻击
- 使用空合并操作符避免因数组键不存在而产生的错误
- 包含错误处理机制检查API密钥是否为空

这是整个代理脚本的关键部分,确保了API密钥的安全存储和获取。

更多推荐