How to Build an AI Chatbot in PHP

A PHP AI chatbot uses server-side cURL to call a model API, a session or database to store the message history, and explicit controls on any tools the model can request. Here is how to build each part.

Updated 4 min read

A PHP AI chatbot sends POST requests to a model API using cURL, keeps a conversation history in a PHP session or a database, and handles any tool calls the model returns. The core pattern is simple. What makes it reliable is managing the message history correctly, controlling what tools the model can use, and handling the errors that come from any external HTTP dependency. If the chatbot is part of a project your team works on, a tool like fenbs can provide shared context — decisions, tasks, and progress — through an MCP client.

What you need before starting

You need PHP 8.1 or later with the cURL extension enabled (it is on by default in most hosts), an API key from your model provider stored in an environment variable or a secrets file outside the web root, and a way to store session data between requests. PHP sessions work for a single-user prototype; a database or a cache like Redis works better when multiple users need separate conversation histories.

Structuring the conversation history

The model API expects the full conversation history in every request, as an array of messages. Each message is an associative array with role and content keys. The first message is the system instruction. Each user turn adds a user message, and each model response adds an assistant message.

Building the messages array in PHP
<?php
session_start();

if (!isset($_SESSION['messages'])) {
    $_SESSION['messages'] = [
        ['role' => 'system', 'content' => 'You are a helpful assistant.'],
    ];
}

$userInput = trim($_POST['message'] ?? '');
if ($userInput !== '') {
    $_SESSION['messages'][] = ['role' => 'user', 'content' => $userInput];
}

After each API call, append the assistant reply to $_SESSION['messages'] so the next request includes it. Limit the array length to stay within the model's context window. Keep the system message and truncate the oldest user and assistant messages when the count grows large.

Making the API call with cURL

Use curl_init, set CURLOPT_RETURNTRANSFER to true, and pass the JSON-encoded messages body with the correct Content-Type and Authorization headers. Decode the response with json_decode. Check for curl_error before reading the response body.

  • Set CURLOPT_TIMEOUT to a reasonable value (30 to 60 seconds) to avoid hanging requests.
  • Check the HTTP status code with curl_getinfo($ch, CURLINFO_HTTP_CODE) before parsing the body.
  • Handle a 429 status (rate limit) by returning a user-friendly message and logging the error.
  • Never log the full request body if it contains user input that could include personal data.

Handling tool calls

When the model wants to call a tool, the response body contains a tool_calls array instead of a plain content string. Your PHP code checks for that field, looks up the matching function, runs it, appends the result as a tool message, and calls the API again in the same request cycle.

Keep the list of tools short and their permissions narrow. A tool that reads from a database is safer than one that writes to it. A tool that looks up a product is safer than one that processes a payment. Define the minimum set of tools the chatbot needs to complete its task and document each one clearly.

Storing and loading history across sessions

PHP sessions are tied to a session cookie and expire when the browser closes or after the session.gc_maxlifetime limit. For a chatbot where users expect their history to persist across days, store the messages in a database table keyed on a user ID and a conversation ID. Load the history at the start of each request and save it after the response is appended.

Testing your PHP chatbot before deploying

Before connecting the chatbot to a frontend or any user-facing flow, test the API call and message history logic from the command line. Write a small CLI script that sends a fixed sequence of messages and prints the response each time. Check that the message history accumulates correctly, that the system message stays at index zero, and that the truncation logic removes complete pairs rather than cutting arbitrarily.

Test each tool function independently with known inputs before using it inside the chatbot loop. The model generates arguments in varied formats; your function should validate them before executing. A tool that returns a clear error string on bad input is far easier to debug than one that throws an exception mid-conversation. Log every tool call name and the arguments it received during development, and confirm the model is calling the right tool with reasonable values before you ship.

How fenbs helps

Supply project context to your PHP chatbot

If this chatbot is part of a larger project, add a fenbs project with the Decisions and rules that govern what the chatbot may do and the tasks you are working on. Connect a supported AI coding tool over MCP from Integrations. It reads the project context at the start of each coding session, so you do not have to restate the constraints in every conversation.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

  1. Create a free account and add a project for the chatbot product.
  2. Add Decisions and rules for the chatbot: which tools it may call, what topics it must avoid, the review requirement before deploying changes.
  3. Add tasks for each feature or conversation flow. Note the current status and any open questions.
  4. Connect a supported AI coding tool from Integrations. It reads the project context before each coding session.
  5. Ask the assistant to save its progress before finishing each session so the next one starts from Where we left off.

For the same pattern in other server-side languages, see how to build a JavaScript AI chatbot for Node.js and how to build a Java AI chatbot for Java. The API call structure and message format are the same; only the HTTP client syntax differs.

Questions people ask.

How do I call a model API from PHP?

Use the cURL extension to send a POST request with a JSON body containing your messages array. Set the Content-Type to application/json and the Authorization header to Bearer followed by your API key. Decode the JSON response with json_decode to read the reply.

How do I store conversation history in a PHP chatbot?

For a single-user prototype, store the messages array in a PHP session. For multiple users or persistence across browser sessions, save the messages to a database table keyed on a user and conversation ID, and load the history at the start of each request.

How do I prevent the message history from growing too long?

Count the messages before each API call. When the count exceeds your limit, remove the oldest user and assistant messages while keeping the system message at the start. A sliding window of the last 20 to 30 turns is enough for most conversations.

Are PHP sessions secure enough for storing chat history?

PHP sessions are adequate for development and low-risk conversations. For chatbots that handle personal data, use a server-side database instead of session storage, validate session tokens strictly, and consider encrypting stored messages at rest.

More in Agent harness (for developers)

All Agent harness (for developers) articles

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.