easygithdev/php-openai

PHPOpenAI 是一个用于访问 OpenAI API 的封装器

v2.3 2024-02-25 12:55 UTC

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; ?>

rabit-32bits

了解更多关于图像生成信息.

使用 DALL·E 进行图像变异

 $response = (new OpenAIClient($apiKey))->Image()->createVariation(
        __DIR__ . '/../../assets/image_variation_original.png',
        n: 2,
        size: ImageSizeEnum::is256
    )->toObject();

variation-1

了解更多关于图像变异信息.

使用 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();

img-edit

了解更多关于图像编辑信息.

嵌入

$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 应用程序中。