Build an PHP AI Powered WebApp to Generate AI Images - PHP - Open Ai


In this article we will build a web app that generates images using Open AI API with PHP. This app will take user prompts as an input to generate images based on the prompts. Users can describe what to generate in the image and this AI will generate the images based on the users imagination. So follow below step by step guide to build your very first AI powered image generator using PHP.


1: Get OpenAi’s token

Head over to OpenAI(https://platform.openai.com/) or openai.com to create a new account you need to a signup page like this 

Open Ai Signup Page


After you successfully sign up it will redirect to you to the a dashboard(https://platform.openai.com/) and it should look like this 

Open Ai Dashboard



Now click on your profile image or name and in the drop down menu click on view API keys and from there you need to create a new project to generate the API key so click on Create new secret key and write a name for it and the it will display you the API key MAKE SURE TO COPY THE API KEY before you close the popup box, because you can’t copy the key again.


 

Api key page - open ai dasboard
generate api key

Get the api key and save somewhere save

Now you are good to go, Remember to always keep your API key secure and avoid sharing it publicly

 

2: Set The Basic HTML Template

First thing you need to do is create a folder for this app you can name it whatever you liked or name “ai-image-generator” now inside this create two more folders 1:backend for php files, 2:frontend for css,images.js files and also create another folder name it uploads in frontend folder for generated images

now your directory structure would look like this 

ai-image-generator/ ├── backend/ │ └── classes/ │ ├── frontend/ │ ├── css/ │ ├── images/ │ ├── js/ │ └── uploads/ │ └── index.php

Now download the basic html template from HERE, of course you can use any html template you like or create your own template. extract  the files somewhere and copy all the html from index.html and create a new index.php file in your app folder and place that html code. And also copy all other folders from that template and paste into your frontend folder

Now open your browser to access your web app page, if you see the app page like below you are good to go.

3: Validate The Main page

In our template we have the text input field for user prompt named prompt and and the submit button named generate. Now before starting html tag add this php code block 


<?php
    //Include the config file from backend folder to call other classes
    include 'backend/config.php';
    //Variable to store generated image from the AI
    $image = "";
	//check the post request method, make sure it's a post request
    if($_SERVER['REQUEST_METHOD'] === "POST"){
		//check if generate button pressed 
        if(isset($_POST['generate'])){
			//variable to store users prompt to generate image
            $prompt    = $_POST['prompt'];
			//check if provided prompt is not empty
			if(!empty($prompt)){
            	//remove white spaces from the string
				$prompt = trim($prompt);
				//set the prompt the ImageGenerator class property
                $genObj->prompt = $prompt;
				//call the generate method from the class to generate the image
                $image =  $genObj->generate();

			}else{
            	//if user prompt is empty display error
				$error = "Field are requried!.";
			}
		}
	} 
?>


So this code block first checks the post request method using the php $_SERVER which is a PHP super global variable used to get information about the HTTP header and other info.

After that we check if our submit button is pressed using $_POST['generate'] and then we created a $prompt variable to get user prompt from the prompt text field using the $_POST[‘prompt’]  

and after that we check if our prompt variable is not empty using the empty function if the prompt field is not empty then remove the white spaces from the user prompt using the trim function or else set an error variable to display error

And then set the prompt property in the ImageGenrator class to use in our API call, we’ll explain this in the below step. And finally we call our generate method which we will create to generate the image.


4:Create Our PHP Class to Handle the API Request

First thing you need to is create a new file in the backend folder, named config.php in this file we will include our Image Generator class that we will create in this step.

this will be our config.php

<?php   
    //Include classes
    require 'classes/ImageGenerator.php';
    //instantiate the class
    $genObj  = new ImageGenerator;

    //Create API_TOKEN constant to get acces to api key
    define('API_TOKEN', 'your-api-key-here');
?>

now you need to create a new php file in the classes folder it will be our php class so name it ImageGenerator.php

And this will be our ImageGenerator class

<?php 
    class ImageGenerator{
        //Properties
        //Store errors
        public $error;
        //Store User Prompt to generate the image
        public $prompt;
        //Store Api header to add api token to the api call
        public $headers;
        //This data will be attech to the api call to send the prompt
        public $data;

        //function to display errors
        public function errors(){
            return $this->error;
        }

        //function to set the api header to attech the API token
        public function setApiHeader(){
            $this->headers = 
            [
                'Authorization: Bearer ' . API_TOKEN,
                'Content-Type: application/json'
            ];
        }
        //function to set the prompt to the data property 
        public function setApiData(){
            $this->data = 
            [
                'prompt' => $this->prompt
            ];
        }
        //function to generate the image
        public function generate(){
            //set the api url for dall-e to generate the images
            $apiUrl = "https://api.openai.com/v1/images/generations";
            //call the function to set the header for api call
            $this->setApiHeader();
            //call the function to set the data to send
            $this->setApiData();
            //initializes a new cURL session. 
            $ch  = curl_init($apiUrl);
            //set options for cURL session to allow to post data
            curl_setopt($ch, CURLOPT_POST, true);
            //set the data to send via api call
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($this->data));
            //set the header(the token key)
            curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
            //set option to return the data
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            //send the request
            $response = curl_exec($ch);
            //close the cURL session
            curl_close($ch);
            //check if response return the api call
            if($response){
              //decode the json response returned from the api call 
              $responseData = json_decode($response, true);
              //now call the method to save the images to app
              $file = $this->saveImage($responseData['data'][0]['url']);
              //return file to use
              return $file;

            }else{
                //else set error to display
                $this->error = "API Request failed!";
                return false;
            }
        }

        //function to save the AI generated image to directory
        public function saveImage($response){
            //create variable to store image returned from the api call
            $imageUrl = $response;
            //set folder to save the image
            $uploadDir = 'frontend/uploads/';
            //Generate filename
            $filename = $uploadDir.md5(time()).'_.png';
            //create the image using the image
            file_put_contents($filename, file_get_contents($imageUrl));
            //return the image to display in main page
            return $filename;
        }
    }

Explanation:

First we start off with the config.php file we created in the backend folder, in this file we actually include ImageGenerator class we created in the classes folder then we created the $genObj object to we can acces the class methods and properties. 

After the we define the API_TOKEN constant to acess the openAi's api key just by call this constant in any where in our app. 


And in  our ImageGenerator class we created five different methods

  1. errors()  to display errors
  2. setApiHeader() to attech the api token using the API_TOKEN constant.
  3. setApiData() to set the prompt in data property to attech in API call
  4. generate() to generate the Images
  5. saveImage() to save the image return from the api call 

So for errors method we simply return the error property which will be the error to display in our app. and for setApiHeader method we created an array to store the api token key to send to api 

and for setApiData we created an array to store the prompt to send it to api, you can aslo add more options to the data to tell AI about the image.

and for generate method we start of with setting the api url to use the dall-e model to use, and then we call our methods to set headrs for api key and api data to set prompt data 

After that we use cURL to send the http request to api with data and cURL return the api data back so we decode the json data because the api returns the json data.

and then we call our saveImage method to store the image we get form the AI. And in ths saveImage method we first created the $imageUrl variable to store image from API and the created $uploadDir to set directory to store images in.  

Then we generated the image name using md5 function and current time then we use file_put_contents and file_get_contents to save the image

and finally return the image to display in a page.


And to display the generated image from the method or display the errors update the index.php file with this codes

index.php


<?php
    //Include the config file from backend folder to call other classes
    include 'backend/config.php';
    //Variable to store generated image from the AI
    $image = "";
	//check the post request method, make sure it's a post request
    if($_SERVER['REQUEST_METHOD'] === "POST"){
		//check if generate button pressed 
        if(isset($_POST['generate'])){
			//variable to store users prompt to generate image
            $prompt    = $_POST['prompt'];
			//check if provided prompt is not empty
			if(!empty($prompt)){
            	//remove white spaces from the string
				$prompt = trim($prompt);
				//set the prompt the ImageGenerator class property
                $genObj->prompt = $prompt;
				//call the generate method from the class to generate the image
                $image =  $genObj->generate();

			}else{
            	//if user prompt is empty display error
				$error = "Field are requried!.";
			}
		}
	} 
?>
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>MyAI</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <link rel="stylesheet" type="text/css" href="frontend/css/style.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700&display=swap" rel="stylesheet"> 
    <script src="https://code.jquery.com/jquery-3.7.0.slim.min.js" integrity="sha256-tG5mcZUtJsZvyKAxYLVXrmjKBVLd6VpVccqz/r4ypFE=" crossorigin="anonymous"></script>

	<link rel="apple-touch-icon" sizes="180x180" href="frontend/images/favicon/apple-touch-icon.png">
	<link rel="icon" type="image/png" sizes="32x32" href="frontend/images/favicon/favicon-32x32.png">
	<link rel="icon" type="image/png" sizes="16x16" href="frontend/images/favicon/favicon-16x16.png">
	<link rel="manifest" href="frontend/images/favicon/site.webmanifest">
	<link rel="mask-icon" href="frontend/images/favicon/safari-pinned-tab.svg" color="#5bbad5">
	<meta name="msapplication-TileColor" content="#da532c">
	<meta name="theme-color" content="#ffffff">


</head>
<body>
<form id="form" method="POST">
<div class="wrapper flex flex-1">
<div class="inner-wrapper flex flex-1 w-full h-screen">
	
	<!--CONTENT_WRAPPER-->
	<div class="flex flex-1 h-full items-start justify-center">
		<!--INNER_CONTENT_WRAPPER-->
		<div class="flex flex-1 w-full flex-col items-center justify-center">
			
			<!--LOGO_SECTION-->
			<div class="w-full flex flex-1 items-center justify-center flex-col">

				<!--LOGO_IMAGE_DIV-->
				<div class="w-96 overflow-hidden items-center sm:mt-0 md:mt-20 sm:mt-20 mb-6 flex justify-center flex-col text-center">
					<div id="loader" class="hidden w-40 h-40 overflow-hidden">
						<img src="frontend/images/loding.gif">
					</div>
					<!-- Check if Image is generated -->
                    <?php if(!empty($image)):?>
                        <img src="<?php echo $image;?>"/>
                        <span class="text-gray-800 text-sm">Image successfuly generated</span>
                    <?php else:?>
                    	<!-- else display the logo image -->
                        <img id="logo" src="frontend/images/mygpt.png"/>
						<span class="text-red-800 text-sm font-bold">
							<?php 
                                if(isset($error)){
                                    echo $error;
                                }
                            ?>
						</span>
					<?php endif;?>
				</div>
				<!--LOGO_IMAGE_DIV_ENDS-->

				<!--INPUT_SECTION-->
				<div class="2xl:w-1/3 md:w-2/3 sm:w-3/4 w-10/12">
					<label class="relative">
						<span class="absolute flex left-4 text-gray-300" style="top:3px;"><i class="fas fa-search"></i></span>
						<input class="pl-9 py-3 pr-3 border w-full text-gray-800" type="text" name="prompt" placeholder="Generate images by AI" />
					</label>
				</div>
				<!--INPUT_SECTION_ENDS-->

			</div><!--LOGO_SECTION_END-->

			<!--BOTTOM_SECTION-->
			<div>

				<!--BOTTON_WRAPPER-->
				<div class="pt-5 flex items-center justify-center flex-col">
					<div>
						<button class="bg-green-500 px-3 py-1 rounded text-white hover:shadow-md" name="generate">Generate Image</button>
					</div>
					
				</div>
				<!--BOTTON_WRAPPER_ENDS-->

			</div>
			<!--BOTTOM_SECTION_ENDS-->

		</div>
		<!--INNER_CONTENT_WRAPPER_ENDS-->
	</div>
	<!--CONTENT_WRAPPER_ENDS-->
</div>	
</div>
</form>
<script>
    //check if form is submit 
    $("#form").submit(function() { 
    	//hide logo image 
        $("#logo").hide();
        //display the loading image
        $("#loader").removeClass('hidden');
    });
</script>
</body>
</html>

At bottom of this index.php file we used a Jquery function to check if the form is submitted then hide the logo and display the loading gif image.

Download Full Source Codes HERE

Comments

  1. Anonymous11/05/2023

    Thank you for the example you gave. I wonder how we specify the image size when creating an image.
    Thanks

    ReplyDelete
    Replies
    1. Anonymous11/07/2023

      Hi there, Yes you can do that, by providing an image size to the data array, in the setApiData function, add this 'size': '1024x1024' below 'prompt' => $this->prompt

      Delete

Post a Comment