|
This is a PHP example that uses the OpenAI Chat API.
There are third party PHP libraries to access the OpenAI API via PHP. Instead of the third party PHP libraries, you also can use cURL in PHP. cURL is a library that lets you make HTTP requests in PHP
This is a demo example using HTML, CSS, Javascript, JQuery, AJAX, PHP and cURL.
You need to obtain an OpenAI API key. You can get an account at OpenAI. It is free.
You need to use the OpenAI API key in the code. Embedding the OpenAI API key in the code is not a best practice. Some alternatives to embedding in code is putting it the system environmental file, you can create a hidden file or you can store it in a database. This example uses a name=value pair key in a hidden file. As a result the code has overhead for reading that file and parsing out the OpenAI API key.
// Load the OpenAI API key
$env_file = file_get_contents('.example-curl-01-env');
$env_nvps = explode("\n", $env_file);
$envs = array();
foreach($env_nvps as $env_nvp){
//error_log($env_nvp . PHP_EOL);
$env = explode('=', $env_nvp);
$envs[trim($env[0])] = trim($env[1]);
}
$api_key = $envs['OPENAI_API_KEY'];
$data = array(
"model" => $model,
"temperature" => 0.5,
"max_tokens" => 500,
'messages' => [
[
'role' => 'user',
'content' => $_POST['prompt']
],
],
);
You need to create that hidden file and replace PUT_YOUR_OPEN_AI_KEY_HERE with your OpenAI API key. Also be sure to include your file name on line 18.
OPENAI_API_KEY = PUT_YOUR_OPEN_AI_KEY_HERE
An alternative is have only your API key in the file and on line 18 load the file into the $api_key variable and eliminate the code lines 19- 26.
This example does not have an elaborate data validation for the prompt text coming from the frontend. We can assume the OpenAI API does that. However if you plan to use it or store it, then you need to consider any other validation you require.
// Request validity status
$request_valid = false;
// Validate POST data
if (isset($_POST['prompt'])){
$request_valid = true;
}
// Process request
if($request_valid){
Once the prompt is valid and the OpenAPI key is in hand, you then create the data needed to make the OpenAI API call.
We are calling the chat completions request. This request “creates a completion for the chat message.”
At this point in time I only had access to the OpenAI gpt-3.5-turbo model. The gpt-4 model was released but I was still on the wait list to use it via the API.
In the PHP code the model is on line 16. If you get access to gpt-4 model , you can substitute it or other models the API chat completion request we are using. Check model compatibility for a list of models.
$model = 'gpt-3.5-turbo';
The request require various data values. One is the model id. The temperature for adjusting the sampling.
The max_tokens determine amount of usage. Lower you will get less and higher more. It impacts the utilization of token which are purchased. You can experiment on the tokenizer page. Set to 500 will generate a decent paragraph.
The messages array for the purpose of this demo is the user prompt. The user role is treating the request as you might expect in ChatGPT. The content is the prompt coming from the frontend.
$data = array(
"model" => $model,
"temperature" => 0.5,
"max_tokens" => 500,
'messages' => [
[
'role' => 'user',
'content' => $_POST['prompt']
],
],
);
URL is used to make the request. The details of using cURL are beyond the scope of this demo. However the code is a good template.
Line 40 provides the OpenAI API chat completions URL.
Line 43 encodes the data into JSON format and packages it as POST data.
Line 46 passes the OpenAI API key.
Line 48 executes the request and returns the results.
// cURL processing
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/chat/completions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Bearer ' . $api_key;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response_raw = curl_exec($ch);
$rtn_val
VariableThe remaining code packages the return data to send back to the client. The $rtn_val
array contains the data the client side expects. The $rtn_val array success
key is true if all went well and false otherwise. False is the default.
The $rtn_val
array content
key has the response from the OpenAI API if it succeeded.
The $rtn_val
array error
key is an array with information for perhaps messaging on the client side if the success
key has a false value. The information in this example is scant and probably the best practice. The error
key has a message
key containing something identifying the reason for failure. As you will see it is not much.
Line 49 detects if there was some failure with the request. In that case the cURL error information is logged and the return message is set.
Lines 53-58 handles the success of the API request. For development learning only, the raw response is logged on line 53.
The raw response is encoded into JSON format on line 55 and logged for development learning only.
You can study those in your log file.
Line 57 is were the response content is extracted from the response. Line 58 sets the $rtn_val success
key to true.
if (curl_errno($ch)) {
$rtn_val['error']['message'] = 'cannot-process-request';
error_log 'Error:' . curl_error($ch);
}else{
error_log('$response_raw: ' . print_r($response_raw,true));
// Convert response to JSON.
$response = json_decode($response_raw);
error_log('$response: ' . print_r($response_raw,true));
$rtn_val['content'] = trim($response->choices[0]->message->content);
$rtn_val['success'] = true;
}
Finally the return data is packaged to return to the client in JSON format.
//Respond with JSON content
header('Content-Type: application/json');
echo json_encode( $rtn_val );
try catch
block.A catch try
block is also in place to catch any unexpected failures. It logs the error information and populates the error
key message
key.
<?php
// Return values
$rtn_val = array();
$rtn_val['success'] = false;
// Request validity status
$request_valid = false;
// Validate POST data
if (isset($_POST['prompt'])){
$request_valid = true;
}
// Process request
if($request_valid){
try{
// Create OpenAI API data
//$model = 'text-davinci-003';
$model = 'gpt-3.5-turbo';
// Load the OpenAI API key
$env_file = file_get_contents('.example-curl-01-env');
$env_nvps = explode("\n", $env_file);
$envs = array();
foreach($env_nvps as $env_nvp){
//error_log($env_nvp . PHP_EOL);
$env = explode('=', $env_nvp);
$envs[trim($env[0])] = trim($env[1]);
}
$api_key = $envs['OPENAI_API_KEY'];
$data = array(
"model" => $model,
"temperature" => 0.5,
"max_tokens" => 500,
'messages' => [
[
'role' => 'user',
'content' => $_POST['prompt']
],
],
);
// cURL processing
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/chat/completions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Bearer ' . $api_key;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response_raw = curl_exec($ch);
if (curl_errno($ch)) {
$rtn_val['error']['message'] = 'cannot-process-request';
error_log 'Error:' . curl_error($ch);
}else{
error_log('$response_raw: ' . print_r($response_raw,true));
// Convert json response to PHP object.
$response = json_decode($response_raw);
error_log('$response: ' . print_r($response_raw,true));
//$rtn_val['content'] = trim($response);
$rtn_val['content'] = trim($response->choices[0]->message->content);
$rtn_val['success'] = true;
}
}catch(\Tectalic\OpenAi\ClientException $e){
$rtn_val['error']['message'] = 'cannot-process-request';
error_log('error: ' . $rtn_val['error']['message'] );
error_log('$e: ' . print_r($e,true));
}
}
//Respond with JSON content
header('Content-Type: application/json');
echo json_encode( $rtn_val );
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>01 - OpenAI | Basic AJAX/PHP/cURL Test | Lon Hosford</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet" href="example-curl-01.css">
<title>Basic test of OpenAI with cURL and AJAX| Lon Hosford</title>
<meta name="description" content="Basic test of OpenAI with HTML, CSS, Javascript, JQuery, AJAX, cURL and PHP ">
<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
</head>
<body>
<div class="center-block text-align-center">
<h1>OpenAI</h1>
<h2>Basic test using cURL and AJAX</h2>
<h5 class="center">Folder: openai/example-curl-01</h5>
<p><a href="https://www.codesiri.com/2023/02/php-access-chatgpt-api-using-curl.html" target="_blank">PHP - Access ChatGPT API using cURL</a></p>
<p><a href="https://platform.openai.com/docs/guides/completion/text-completion" target="_blank">OpenAI Text Completions Doc</a></p>
</div>
<div class="entry-form-container center-block text-align-center">
<div><p class="text-align-left"><input id="prompt" type="text" placeholder="Enter a prompt" ><br>Ex: Describe the alkaline elements<br>What are the hardest rocks in the universe.</p></div>
<div><p><button id="send">Send</button></p></div>
<div><textarea id="results"></textarea></div>
</div>
<script src="example-curl-01.js"></script>
</body>
</html>
.center-block{
width: 100%;
margin: auto;
}
.text-align-center{
text-align: center;
}
.text-align-left{
text-align: left;
}
#results{
min-height: 100px;
width: 100%;
}
.entry-form-container{
width:500px;
}
#prompt{
width: 100%;
}
There are many console.log
method calls in the code. This is for development learning. You can explore their output in the console of the web browser for study.
"use strict";
(function($){
/*
* Handle #send button click event
*
* Responds to #send button click event.
*
*/
$('#send').on('click', function(e){
e.preventDefault();
console.log('CLICK!');
sendPromptAjax();
});
/*
* Handle request to process a user prompt/
*
* Sends prompt and update the UI with results.
*
* @param int lessonId The lesson id
*/
function sendPromptAjax(){
console.log('sendPromptAjax');
$('#results').val('...processing...');
let dataSend = {};
dataSend['prompt'] = $('#prompt').val();
console.log("sendPromptAjax| dataSend", dataSend);
$.ajax(
{
type:"post",
url:"example-curl-01.php",
data:dataSend,
dataType:'json',
}
)
.done(
function(data, status){
console.log("sendPromptAjax | done");
console.log("sendPromptAjax | data", data);
console.log("sendPromptAjax | status", status);
if (data.success){
console.log("sendPromptAjax | Success true");
$('#results').val(data.content);
}else{
$('#results').val('Request failed.');
}
}
)
.fail(
function(data, status, error){
console.log("sendPromptAjax | fail");
console.log("sendPromptAjax | data", data);
console.log("sendPromptAjax | error", error);
$('#results').val('Something in cyberspace went horribly wrong!');
}
);
}
})(jQuery);