简介

本文将介绍如何使用 PHP 调用 DeepSeek API,实现流式对话并保存对话记录。PHP 版本使用面向对象的方式实现,代码结构清晰,易于维护。

1. 环境准备

1.1 系统要求

  • PHP 7.0 或更高版本
  • PHP cURL 扩展
  • 文件写入权限

1.2 项目结构

1

2

3

deepseek-project/

├── main.php          # 主程序

└── conversation.txt  # 对话记录文件

2. 完整代码实现

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

<?php

class DeepSeekChat {

    private $url = 'https://api.siliconflow.cn/v1/chat/completions';

    private $apiKey = 'YOUR_API_KEY'// 替换为你的 API Key

    private $logFile = 'conversation.txt';

    public function __construct() {

        // 确保日志文件存在且可写

        if (!file_exists($this->logFile)) {

            touch($this->logFile);

        }

    }

    private function saveToFile($content, $isQuestion = false) {

        $timestamp = date('Y-m-d H:i:s');

        $text = $isQuestion

            ? "\n[$timestamp] Question:\n$content\n\n[$timestamp] Answer:\n"

            : $content;

         

        file_put_contents($this->logFile, $text, FILE_APPEND);

    }

    private function processStreamingResponse($handle) {

        $buffer = '';

        while (!feof($handle)) {

            $chunk = fread($handle, 1024);

            $buffer .= $chunk;

            // 处理缓冲区中的每一行

            while (($pos = strpos($buffer, "\n")) !== false) {

                $line = substr($buffer, 0, $pos);

                $buffer = substr($buffer, $pos + 1);

                if (strlen(trim($line)) > 0) {

                    if (strpos($line, 'data: ') === 0) {

                        $data = substr($line, 6); // 移除 "data: " 前缀

                        if ($data === '[DONE]') {

                            continue;

                        }

                        $json = json_decode($data, true);

                        if ($json && isset($json['choices'][0]['delta']['content'])) {

                            $content = $json['choices'][0]['delta']['content'];

                            echo $content;

                            flush();

                            $this->saveToFile($content);

                        }

                    }

                }

            }

        }

    }

    public function chat() {

        while (true) {

            echo "\n请输入您的问题 (输入 q 退出): ";

            $question = trim(fgets(STDIN));

            if ($question === 'q') {

                echo "程序已退出\n";

                break;

            }

            // 保存问题

            $this->saveToFile($question, true);

            // 准备请求数据

            $data = [

                'model' => 'deepseek-ai/DeepSeek-V3',

                'messages' => [

                    [

                        'role' => 'user',

                        'content' => $question

                    ]

                ],

                'stream' => true,

                'max_tokens' => 2048,

                'temperature' => 0.7,

                'top_p' => 0.7,

                'top_k' => 50,

                'frequency_penalty' => 0.5,

                'n' => 1,

                'response_format' => [

                    'type' => 'text'

                ]

            ];

            // 准备 cURL 请求

            $ch = curl_init($this->url);

            curl_setopt_array($ch, [

                CURLOPT_POST => true,

                CURLOPT_POSTFIELDS => json_encode($data),

                CURLOPT_RETURNTRANSFER => true,

                CURLOPT_HTTPHEADER => [

                    'Content-Type: application/json',

                    'Authorization: Bearer ' . $this->apiKey

                ],

                CURLOPT_WRITEFUNCTION => function($ch, $data) {

                    echo $data;

                    return strlen($data);

                }

            ]);

            try {

                // 发送请求并处理响应

                $handle = curl_exec($ch);

                 

                if (curl_errno($ch)) {

                    throw new Exception(curl_error($ch));

                }

                // 添加分隔符

                echo "\n----------------------------------------\n";

                $this->saveToFile("\n----------------------------------------\n");

            } catch (Exception $e) {

                $error_msg = "请求错误: " . $e->getMessage() . "\n";

                echo $error_msg;

                $this->saveToFile($error_msg);

            } finally {

                curl_close($ch);

            }

        }

    }

}

// 运行程序

$chatbot = new DeepSeekChat();

$chatbot->chat();

3. 代码详解

3.1 类结构

  • DeepSeekChat: 主类,封装所有功能
  • __construct: 构造函数,初始化日志文件
  • saveToFile: 保存对话记录
  • processStreamingResponse: 处理流式响应
  • chat: 主对话循环

3.2 关键功能

文件操作

1

2

3

4

5

6

7

8

private function saveToFile($content, $isQuestion = false) {

    $timestamp = date('Y-m-d H:i:s');

    $text = $isQuestion

        ? "\n[$timestamp] Question:\n$content\n\n[$timestamp] Answer:\n"

        : $content;

     

    file_put_contents($this->logFile, $text, FILE_APPEND);

}

cURL 配置

1

2

3

4

5

6

7

8

9

curl_setopt_array($ch, [

    CURLOPT_POST => true,

    CURLOPT_POSTFIELDS => json_encode($data),

    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_HTTPHEADER => [

        'Content-Type: application/json',

        'Authorization: Bearer ' . $this->apiKey

    ]

]);

3.3 参数说明

  • model: 使用的模型名称
  • stream: 启用流式输出
  • max_tokens: 最大输出长度 (2048)
  • temperature: 控制随机性 (0.7)
  • top_ptop_k: 采样参数
  • frequency_penalty: 重复惩罚系数

4. 错误处理

代码包含完整的错误处理机制:

  • cURL 错误检查
  • JSON 解析错误处理
  • 文件操作错误处理
  • 异常捕获和日志记录

5. 使用方法

5.1 修改配置

在代码中替换 YOUR_API_KEY 为你的实际 API Key。

5.2 运行程序

1

php main.php

5.3 交互方式

  • 输入问题进行对话
  • 输入 ‘q’ 退出程序
  • 查看 conversation.txt 获取对话记录

6. 性能优化建议

  1. 内存管理

    • 使用适当的缓冲区大小
    • 及时清理变量
    • 避免大量数据积累
  2. 文件操作

    • 使用文件锁防止并发写入
    • 定期清理日志文件
    • 考虑使用数据库存储
  3. 网络请求

    • 设置合理的超时时间
    • 使用持久连接
    • 处理网络异常

总结

PHP 版本的 DeepSeek API 实现采用面向对象方式,代码结构清晰,易于维护和扩展。通过 cURL 实现流式处理,提供了良好的交互体验。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐