AIStreamHandler.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. namespace App\Repositories\StreamHandler;
  3. use Illuminate\Support\Facades\Log;
  4. class AIStreamHandler
  5. {
  6. private $basePath;
  7. private $path;
  8. private $data_buffer;//缓存,有可能一条data被切分成两部分了,无法解析json,所以需要把上一半缓存起来
  9. private $counter;//数据接收计数器
  10. private $qmd5;//问题md5
  11. private $chars;//字符数组,开启敏感词检测时用于缓存待检测字符
  12. private $punctuation;//停顿符号
  13. private $dfa = NULL;
  14. private $check_sensitive = FALSE;
  15. public function __construct($params) {
  16. $ds = DIRECTORY_SEPARATOR;
  17. $userId = isset($params["user"])?$params["user"]:0;
  18. $this->basePath = storage_path("logs{$ds}curl{$ds}data{$ds}{$userId}{$ds}");
  19. if (!file_exists($this->basePath)){
  20. mkdir($this->basePath,0777,true);
  21. }
  22. $this->buffer = '';
  23. $this->counter = 0;
  24. $this->qmd5 = $params['qmd5'] ?? time();
  25. $this->chars = [];
  26. $this->lines = [];
  27. $this->punctuation = [',', '。', ';', '?', '!', '……'];
  28. $this->path = $this->basePath.'data.'.$this->qmd5.'.log';
  29. }
  30. public function getPath(): string
  31. {
  32. return $this->path;
  33. }
  34. /**
  35. * 得到结果数据
  36. * @param string|null $filePath
  37. * @return array
  38. * @throws \Exception
  39. */
  40. public function getData(string $filePath=null)
  41. {
  42. $filePath = $filePath==null?$this->path:$filePath;
  43. $content = file_get_contents($filePath);// 读取文件内容
  44. // 定义正则表达式模式
  45. // 匹配 JSON 对象(花括号包围的内容)
  46. $pattern = '/\{(?:[^{}]|(?R))*\}|(\[(?:[^[\]]|(?R))*\])/s';
  47. // 使用 preg_match_all 匹配所有 JSON 数据
  48. preg_match_all($pattern, $content, $matches);
  49. $result = [];
  50. // 检查是否找到匹配项
  51. if (!empty($matches[0])) {
  52. foreach ($matches[0] as $match) {
  53. // 解析 JSON 数据
  54. $jsonData = json_decode($match, true);
  55. // 检查解析是否成功
  56. if (json_last_error() === JSON_ERROR_NONE) {
  57. $result[] = $jsonData;
  58. }
  59. }
  60. }
  61. $answer = "";
  62. $conversation_id = "";
  63. foreach ($result as $val){
  64. if (isset($val["event"])){
  65. switch ($val["event"]){
  66. //获取回答数据
  67. case "agent_message":
  68. $answer.=$val["answer"];
  69. break;
  70. case "message_end":
  71. $conversation_id = $val["conversation_id"];
  72. break;
  73. }
  74. }
  75. }
  76. if (empty($answer) || empty($conversation_id)){
  77. throw new \Exception("获取结果失败");
  78. }
  79. return array(
  80. "answer"=>$answer,
  81. "conversation_id"=>$conversation_id,
  82. "path"=>$filePath
  83. );
  84. }
  85. public function callback($ch, $data) {
  86. $this->counter += 1;
  87. file_put_contents($this->path,$this->counter.'=='.$data.PHP_EOL, FILE_APPEND);
  88. $result = json_decode($data, TRUE);
  89. if(is_array($result)){
  90. throw new \Exception('openai 请求错误:'.json_encode($result));
  91. }
  92. return strlen($data);
  93. }
  94. }