使用PHP常驻内存框架webman本地部署chatgpt

  • A+
所属分类:PHP

项目效果图:

使用PHP常驻内存框架webman本地部署chatgpt

1.基于webman,所以需要先安装webman框架,若不会使用webman我已将完整项目放置文末,windows下双击.bat文件就能运行。

2.然后安装 OpenAI 的官方php库

composer require openai-php/client

3.安装guzzlehttp扩展

composer require guzzlehttp/guzzle

4.需要准备一个本地代理,作为请求api的代理

5.将代码放到控制器目录下即可,运行方式然后访问http://域名/chatgpt,如果有模块则访问http://域名/模块/chatgpt

完整代码:

<?php
namespace app\controller;
use support\Request;
use OpenAI;

// openai 的 key
// 全局代理后,在这里注册登录 https://platform.openai.com/signup
define('OPENAI_KEY', '');//你的key

class ChatgptController{
    // 初始化获取全部已回答
    public function all(Request $request){
        $messages = $request->session()->get('messages', []);

        return json([
            "code"=>0,
            "msg"=>"ok",
            "data"=>$messages
        ]);
    }
    // 单次查询
    public function query(Request $request){
        
        $messages = $request->session()->get('messages', []);
        $messages[] = ['role' => 'user', 'content' => $request->input('message')];
        $current=[];
        try {
            $response = OpenAI::factory()
                ->withApiKey(OPENAI_KEY)
                ->withHttpClient(new \GuzzleHttp\Client([
                    "proxy"=>""//代理地址例如 127.0.0.1:7890
                ]))->make()->chat()->create([
                'model' => 'gpt-3.5-turbo',
                'messages' => $messages
            ]);
            $current = ['role' => 'assistant', 'content' => nl2br($response->choices[0]->message->content)];
        } catch (\Exception $e) {
            $current = ['role' => 'assistant', 'content' => $e->getMessage()];
        }
        $messages[]=$current;
        $request->session()->put('messages', $messages);
        return json([
            "code"=>0,
            "msg"=>"ok",
            "data"=>$current['content']
        ]);
    }
    // 清除
    public function clear(Request $request){
        $request->session()->delete("messages");
        return redirect("/Chatgpt/index");
    }

    public function index(Request $request){
    
        $ip=$request->getRealIp($safe_mode=true);
        file_put_contents("user_ip.txt",$ip.PHP_EOL,FILE_APPEND);
        $html=<<<'EOF'
        <!DOCTYPE html>
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>ChatGPT</title>
            <link href="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/tailwindcss/2.2.19/tailwind.min.css" type="text/css" rel="stylesheet" />
        </head>
        <body class="antialiased mx-auto" style="max-width:1000px">
            <div class="flex flex-col space-y-4 py-4 overflow-auto" id="body"></div>
            <div class="text-center text-red-400" id="loading"></div>
            <div class="py-4 flex flex-col space-x-1 justify-center items-center">
                <textarea required onkeypress="submit(this)" placeholder="输入后 ctrl+回车 或点击右侧 发送 按钮" name="message" class="border   p-2 flex-1 w-full" id="message"></textarea>
                <div class="flex justify-center items-center mt-2">
                    <input type="button" onclick="submit(this,'click')" class="cursor-pointer bg-green-500 text-white p-2  mx-1" value="发送请求" />
                    <a class="bg-gray-200 text-white p-2  mx-1" href="./clear" title="出现错误时,可尝试清除提问记录">清除记录</a>
                </div>
            </div>
            <script>
            // 名称
            window.chatgptConfig = {
                "assistant": "ChatGPT",
                "user": "我"
            };
            window.onload = function() {
                fetch("./all", {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-Requested-With': 'XMLHttpRequest'
                        },
                        body: ''
                    })
                    .then(response => response.json()) 
                    .then(json => {
                        if (json.data) {
                            json.data.forEach(it => {
                                append(it['content'], window.chatgptConfig[it.role]);
                            });
                        }
                    })
                    .catch(error => {
                        console.error(error);
                    });
            };
            function submit(el, type) {
                if (type === 'click' || (event.ctrlKey && event.keyCode === 10)) {
                    if (el.getAttribute('disabled')) {
                        alert("正在等待上次提问的回复,请稍等");
                        return;
                    }
                    var msg = document.getElementById('message').value.trim();
                    if (!msg) {
                        alert("必须输入问题");
                        return;
                    }
                    el.setAttribute('disabled', 'disabled');
                    append(msg, window.chatgptConfig['user']);
                    document.getElementById('loading').innerHTML = "努力思考中,稍等哦...";
                    document.documentElement.scrollTop+=50;
                    fetch("./query", {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'X-Requested-With': 'XMLHttpRequest'
                            },
                            body: JSON.stringify({ message: msg})
                        })
                        .then(response => response.json())
                        .then(json => {
                            append(json.data, window.chatgptConfig["assistant"]);
                            document.getElementById('loading').innerHTML = '';
                            document.getElementById('message').value = '';
                            el.removeAttribute('disabled', 'disabled');
                        })
                        .catch(error => {
                            console.error(error);
                            el.removeAttribute('disabled', 'disabled');
                        });
                }
            }
            function append(msg, name) {
                var html = `
                    <div class="ml-4">
                        <div class="text-lg">
                            <a href="#" class="font-medium ${name==window.chatgptConfig['assistant']?'text-green-400':'text-gray-900'}">${name}:</a>
                        </div>
                        <div class="mt-1">
                            <p class="text-gray-800">
                                ${msg}
                            </p>
                        </div>
                    </div>
                `;
                const newDiv = document.createElement("div");
                newDiv.className=`overflow-auto flex p-4 ${name==window.chatgptConfig['assistant']?'bg-gray-100 border flex-reverse':""}`;
                newDiv.innerHTML = html;
                const bodyDiv = document.getElementById("body");
                bodyDiv.appendChild(newDiv);
            }
            </script>
        </body>
        </html>
EOF;
        return $html;
    }
}

原文章地址:分享一个单文件的 ChatGPT api接口实现-workerman社区

项目源码:下载

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: