1<?php 2class OpenAIHttpClient { 3 private $apiKey; 4 private $baseUrl = ''; 5 6 public function __construct($serverUrl, $apiKey) { 7 $this->baseUrl = rtrim($serverUrl, '/'); 8 $this->apiKey = $apiKey; 9 } 10 11 /** 12 * 发送聊天请求 13 */ 14 public function chatCompletion($params) { 15 return $this->request('/chat/completions', $params); 16 } 17 18 /** 19 * 发送补全请求 20 */ 21 public function completion($params) { 22 return $this->request('/completions', $params); 23 } 24 25 /** 26 * 通用 HTTP 请求方法 27 */ 28 private function request($endpoint, $data) { 29 $url = $this->baseUrl . $endpoint; 30 31 $headers = [ 32 'Content-Type: application/json', 33 'Authorization: Bearer ' . $this->apiKey 34 ]; 35 36 $ch = curl_init($url); 37 38 curl_setopt_array($ch, [ 39 CURLOPT_RETURNTRANSFER => true, 40 CURLOPT_POST => true, 41 CURLOPT_HTTPHEADER => $headers, 42 CURLOPT_POSTFIELDS => json_encode($data), 43 CURLOPT_TIMEOUT => 300, 44 CURLOPT_SSL_VERIFYPEER => true, 45 CURLOPT_FAILONERROR => false 46 ]); 47 48 $response = curl_exec($ch); 49 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 50 $error = curl_error($ch); 51 curl_close($ch); 52 53 if ($error) { 54 throw new Exception("cURL Error: " . $error); 55 } 56 57 $decoded = json_decode($response, true); 58 59 if ($httpCode !== 200) { 60 $errorMsg = $decoded['error']['message'] ?? "HTTP {$httpCode}"; 61 throw new Exception("API Error: " . $errorMsg); 62 } 63 64 return $decoded; 65 } 66 67 /** 68 * 流式响应(适合长文本) 69 */ 70 public function streamChatCompletion($params, $callback) { 71 $params['stream'] = true; 72 $url = $this->baseUrl . '/chat/completions'; 73 74 $headers = [ 75 'Content-Type: application/json', 76 'Authorization: Bearer ' . $this->apiKey, 77 'Accept: text/event-stream', 78 'Cache-Control: no-cache' 79 ]; 80 81 $ch = curl_init($url); 82 83 curl_setopt_array($ch, [ 84 CURLOPT_RETURNTRANSFER => true, 85 CURLOPT_POST => true, 86 CURLOPT_HTTPHEADER => $headers, 87 CURLOPT_POSTFIELDS => json_encode($params), 88 CURLOPT_WRITEFUNCTION => function($ch, $data) use ($callback) { 89 $callback($data); 90 return strlen($data); 91 }, 92 CURLOPT_TIMEOUT => 120 93 ]); 94 95 curl_exec($ch); 96 curl_close($ch); 97 } 98 99 /** 100 * 获取可用模型列表 101 */ 102 public function listModels() { 103 $url = $this->baseUrl . '/models'; 104 105 $headers = [ 106 'Authorization: Bearer ' . $this->apiKey 107 ]; 108 109 $ch = curl_init($url); 110 curl_setopt_array($ch, [ 111 CURLOPT_RETURNTRANSFER => true, 112 CURLOPT_HTTPHEADER => $headers, 113 CURLOPT_TIMEOUT => 10 114 ]); 115 116 $response = curl_exec($ch); 117 curl_close($ch); 118 119 return json_decode($response, true); 120 } 121} 122