easygithdev / php-openai
PHPOpenAI 是一个用于访问 OpenAI API 的封装器
Requires
- php: >=8.1
- ext-curl: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpunit/phpunit: ^9.5
README
PHPOpenAI
是一个由社区维护的库,它允许在 PHP 中使用 OpenAI
API。
该项目用 PHP 编写,可以轻松地将 OpenAI API
集成到现有的 PHP 项目中。
系统需求
该项目基于 PHP 8.1 版本,以便使用枚举等特性。该项目不要求任何外部依赖。但是,您必须安装 cURL 扩展才能正常工作。
- PHP 版本 >= 8.1
- cURL 扩展
安装
该项目使用 Composer 管理依赖。如果您尚未安装 Composer,可以按照官方 Composer 网站上的说明进行安装。
Packagist 安装
要安装该项目,您可以使用以下命令从 packagist.org 安装包
composer require easygithdev/php-openai
编写第一个示例
要使用 OpenAI API
,您需要在他们的网站上注册并获取 API 密钥。一旦您有了 API 密钥,您就可以在 PHP 代码中使用它来向 OpenAI API 发送请求。
要了解如何获取您的密钥,请访问以下地址
https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key.
以下是一个示例代码,展示如何在 PHP 中使用 OpenAI API
<?php require_once __DIR__ . '/vendor/autoload.php'; use EasyGithDev\PHPOpenAI\Helpers\ModelEnum; use EasyGithDev\PHPOpenAI\OpenAIClient; $apiKey = getenv('OPENAI_API_KEY'); $response = (new OpenAIClient($apiKey))->Completion()->create( ModelEnum::TEXT_DAVINCI_003, "Say this is a test", )->toObject(); // Response as stClass object echo '<pre>', print_r($response, true), '</pre>';
此代码使用 API 密钥实例化一个新的 OpenAIApi
对象,然后创建一个新的 Completion
对象,使用 OpenAI 提供的 GPT-3 AI 语言模型进行文本完成。
在 Completion
对象上调用 create()
方法以生成新的文本完成。它接受两个参数
- 第一个参数是要用于完成的 GPT-3 模型的 ID。在这种情况下,它使用 TEXT_DAVINCI_003 模型。
- 第二个参数是要生成完成的提示或输入文本。在这种情况下,提示是 "这是一个测试"。
完成的结果存储在 $response
变量中。然后可以使用该结果进行进一步处理,例如显示完成的文本或将其输入程序的其他部分进行进一步处理。
管理 API 密钥
您可以使用环境变量来存储您的密钥。然后您可以在以下示例中使用此变量
export OPENAI_API_KEY="sk-xxxxxxxxxxx"
您可以将变量放入 Apache 配置文件中
<VirtualHost hostname:80>
...
SetEnv OPENAI_API_KEY sk-xxxxxxxxxxx
...
</VirtualHost>
然后重启服务。
现在,您可以通过调用 PHP 的 getenv()
函数来使用环境变量。
<?php $response = (new OpenAIApi(getenv('OPENAI_API_KEY')))->Completion()->create( ModelEnum::TEXT_DAVINCI_003, "Say this is a test", );
管理组织
如果您想提供有关您组织的信息,必须按以下步骤操作。
<?php $apiKey = getenv('OPENAI_API_KEY'); $org = getenv('OPENAI_API_ORG'); // Passing the organization to the client $response = (new OpenAIClient($apiKey, $org))
管理 API 的 URL
如果您需要修改 API 的 URL,可以按以下步骤操作
<?php $apiKey = getenv('OPENAI_API_KEY'); // Create a new router, with origine url and version $route = new OpenAIRoute( 'https://api.openai.com', 'v1' ); // Get a specific Url echo $route->completionCreate() , '<br>'; // Passing the router to the client $response = (new OpenAIClient($apiKey)) ->setRoute($route);
要重新定义路由,需要扩展 OpenAIRoute
类或实现 Route
接口。
管理响应
API 以 JSON 格式返回响应。为了方便访问不同的信息,您可以调用 Handler 对象的 toObject()
或 toArray()
方法来访问数据。
<?php $response = (new OpenAIClient($apiKey))->Completion()->create( ModelEnum::TEXT_DAVINCI_003, "Say this is a test", )->toObject(); // Response as a stClass object echo '<pre>', print_r($response, true), '</pre>'; $response = (new OpenAIClient($apiKey))->Completion()->create( ModelEnum::TEXT_DAVINCI_003, "Say this is a test", )->toArray(); // Response as an associative array echo '<pre>', print_r($response, true), '</pre>';
管理错误
有时,API 会返回错误。因此,有必要能够识别导致问题的原因。为了处理这种困难,您有许多选择。
如果您使用具有 toObject()
或 toArray()
方法的 Handler 对象,只需使用 try-catch
结构即可。
try { $response = (new OpenAIClient('BAD KEY')) ->Completion() ->create( ModelEnum::TEXT_DAVINCI_003, "Say this is a test", ) ->toObject(); } catch (Throwable $t) { echo nl2br($t->getMessage()); die; }
如果您正在使用 CurlResponse
对象,您可以使用验证器检查是否发生了错误。
$handler = (new OpenAIClient('BAD KEY'))->Completion()->create( ModelEnum::TEXT_DAVINCI_003, "Say this is a test", ); $response = $handler->getResponse(); $contentTypeValidator = $handler->getContentTypeValidator(); if (!(new StatusValidator($response))->validate() or !(new $contentTypeValidator($response))->validate()) { echo $response->getBody(); }
应用示例
这是一个视频,展示了允许您使用用户定义的绘画风格创建图像的应用程序。此应用程序使用 PHPOpenAI 项目创建。
playground.mp4
在此处找到代码
https://github.com/EasyGithDev/PHPOpenAI-Playground.git.
代码示例
现在将 OpenAI 集成到您的应用程序中就像几行代码那么简单。
您可以在以下位置找到所有代码
https://github.com/EasyGithDev/PHPOpenAI-Examples.
使用 ChatGPT 进行文本补全
$response = (new OpenAIClient($apiKey))->Chat()->create( ModelEnum::GPT_3_5_TURBO, [ new ChatMessage(ChatMessage::ROLE_SYSTEM, "You are a helpful assistant."), new ChatMessage(ChatMessage::ROLE_USER, "Who won the world series in 2020?"), new ChatMessage(ChatMessage::ROLE_ASSISTANT, "The Los Angeles Dodgers won the World Series in 2020."), new ChatMessage(ChatMessage::ROLE_USER, "Where was it played?"), ] )->toObject();
使用 GPT-3 进行文本补全
$response = (new OpenAIClient($apiKey))->Completion()->create( ModelEnum::TEXT_DAVINCI_003, "Say this is a test", )->toObject();
使用流进行文本补全
OpenAI API 中的流属性是一个可选参数,您可以使用它来控制 API 返回的数据流。如果您将此选项设置为 True,API 将以流数据的形式返回响应,而不是单个响应。
这意味着您可以在数据可用时检索 API 的结果,而不是在处理之前等待完整的响应。此选项对于需要实时处理大量数据的应用程序非常有用。
openai-completion-stream.mp4
<?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); ... (new OpenAIClient($apiKey))->Completion()->create( model: "text-davinci-003", prompt: "Translate this into 1. French, 2. Spanish and 3. Japanese:\n\nWhat rooms do you have available?\n\n1.", temperature: 0.3, max_tokens: 100, top_p: 1.0, frequency_penalty: 0.0, presence_penalty: 0.0, stream: true )->getResponse();
<html> <body> <div id="result"></div> <script> function nl2br(str, replaceMode, isXhtml) { var breakTag = (isXhtml) ? '<br />' : '<br>'; var replaceStr = (replaceMode) ? '$1' + breakTag : '$1' + breakTag + '$2'; return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, replaceStr); } if (typeof (EventSource) !== 'undefined') { console.info('Starting connection...'); var source = new EventSource('stream.php'); source.addEventListener('open', function (e) { console.info('Connection was opened.'); }, false); source.addEventListener('error', function (e) { var txt; switch (event.target.readyState) { // if reconnecting case EventSource.CONNECTING: txt = 'Reconnecting...'; break; // if error was fatal case EventSource.CLOSED: txt = 'Connection failed. Will not retry.'; break; } console.error('Connection error: ' + txt); }, false); source.addEventListener('message', function (e) { if (e.data == "[DONE]") { source.close(); return; } document.getElementById('result').innerHTML += nl2br(JSON.parse(e.data).choices[0].text); }, false); } else { alert('Your browser does not support Server-sent events! Please upgrade it!'); console.error('Connection aborted'); } </script> </body> </html>
文本编辑
$response = (new OpenAIClient($apiKey))->Edit()->create( "What day of the wek is it?", ModelEnum::TEXT_DAVINCI_EDIT_001, "Fix the spelling mistakes", )->toObject();
使用 DALL·E 进行图像生成
function displayUrl($url) { return '<img src="' . $url . '" />'; } $response = (new OpenAIClient($apiKey))->Image()->create( "a rabbit inside a beautiful garden, 32 bit isometric", n: 2, size: ImageSizeEnum::is256, )->toObject();
<?php foreach ($response->data as $image) : ?> <div> <?= displayUrl($image->url) ?> </div> <?php endforeach; ?>
使用 DALL·E 进行图像变异
$response = (new OpenAIClient($apiKey))->Image()->createVariation( __DIR__ . '/../../assets/image_variation_original.png', n: 2, size: ImageSizeEnum::is256 )->toObject();
使用 DALL·E 进行图像编辑
$response = (new OpenAIClient($apiKey))->Image()->createEdit( image: __DIR__ . '/../../assets/image_edit_original.png', mask: __DIR__ . '/../../assets/image_edit_mask2.png', prompt: 'a sunlit indoor lounge area with a pool containing a flamingo', size: ImageSizeEnum::is512, )->toObject();
嵌入
$response = (new OpenAIClient($apiKey))->Embedding()->create( ModelEnum::TEXT_EMBEDDING_ADA_002, "The food was delicious and the waiter...", )->toObject();
使用 Whisper 进行音频转录(语音转文本)
$response = (new OpenAIClient($apiKey))->Audio() ->addCurlParam('timeout', 30) ->transcription( __DIR__ . '/../../assets/openai.mp3', ModelEnum::WHISPER_1, response_format: AudioResponseEnum::SRT )->toObject();
使用 Whisper 进行音频翻译(语音转文本)
$response = (new OpenAIClient($apiKey))->Audio() ->addCurlParam('timeout', 30) ->translation( __DIR__ . '/../../assets/openai_fr.mp3', 'whisper-1', response_format: AudioResponseEnum::TEXT )->toObject();
模型列表
$response = (new OpenAIClient($apiKey)) ->Model() ->list() ->toObject();
模型检索
$response = (new OpenAIClient($apiKey)) ->Model() ->retrieve('text-davinci-001') ->toObject();
模型删除
$response = (new OpenAIClient($apiKey)) ->Model() ->delete( $_POST['model'] )->toObject();
文件列表
$response = (new OpenAIApi($apiKey)) ->File() ->list() ->toObject();
文件上传
$response = (new OpenAIApi($apiKey)) ->File() ->create( __DIR__ . '/../../assets/mydata.jsonl', 'fine-tune', ) ->toObject();
文件删除
$response = (new OpenAIApi($apiKey)) ->File() ->delete('file-xxxx') ->toObject();
文件检索
$response = (new OpenAIApi($apiKey)) ->File() ->retrieve('file-xxxx') ->toObject();
文件检索内容
$response = (new OpenAIApi($apiKey)) ->File() ->download('file-xxxx') ->toObject();
微调列表
$response = (new OpenAIApi($apiKey)) ->FineTune() ->list() ->toObject();
微调创建
$response = (new OpenAIApi($apiKey)) ->FineTune() ->create( 'file-xxxx' ) ->toObject();
微调检索
$response = (new OpenAIApi($apiKey)) ->FineTune() ->retrieve('ft-xxx') ->toObject();
微调事件列表
$response = (new OpenAIApi($apiKey)) ->FineTune() ->listEvents('ft-xxx') ->toObject();
微调取消
$response = (new OpenAIApi($apiKey)) ->FineTune() ->Cancel('ft-xxx') ->toObject();
内容审核
$response = (new OpenAIClient($apiKey)) ->Moderation() ->create('I want to kill them.') ->toObject();
测试
运行所有测试
composer test tests
只运行一个测试
composer test tests/[NAME]Test.php
摘要
PHPOpenAI 是一个有用的项目,对于想要轻松将 OpenAI API 集成到他们项目中的 PHP 开发人员来说非常有用。通过简单的安装和使用 Composer,您可以将文本分类、图像生成和命名实体识别集成到您的 PHP 应用程序中。