A PHP AI integration needs three checks: did the connection succeed, did the server return a successful HTTP status, and does the JSON contain the field your program expects?

What you will build

Create a command-line PHP client that sends a prompt, checks transport and HTTP errors, and validates the generated-text field.

Before you start

PHP 8.1 or later with the cURL extension. For a real response, install Ollama and pull llama3.2 on your own machine.

1. Create local_ai.php

<?php
declare(strict_types=1);
$endpoint = $argv[1] ?? 'http://127.0.0.1:11434/api/generate';
$ch = curl_init($endpoint);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 60,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS => json_encode([
        'model' => 'llama3.2',
        'prompt' => 'Explain a PHP associative array in two sentences.',
        'stream' => false,
    ], JSON_THROW_ON_ERROR),
]);
$body = curl_exec($ch);
if ($body === false) {
    throw new RuntimeException('Transport error: ' . curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status < 200 || $status >= 300) {
    throw new RuntimeException('AI server HTTP ' . $status);
}
$value = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($value) || !isset($value['response']) || !is_string($value['response'])) {
    throw new RuntimeException('Missing generated-text field');
}
echo $value['response'], PHP_EOL;

2. Run the example

php local_ai.php

Expected result

The generated explanation is printed as text. Wording varies with the installed model.

How it works

json_encode escapes values correctly, so the payload remains valid if the prompt later includes quotes or non-ASCII characters. JSON_THROW_ON_ERROR makes encoding failures visible.

curl_exec returning a string is not proof of HTTP success. Error pages can also be strings. The separate status check prevents your code from treating a server error response as a normal generation result.

This is a local command-line example. If you wrap it in a public route, keep the upstream endpoint fixed in trusted configuration, cap prompt size, and add authentication and usage limits. Do not expose the local model port directly to the internet.

When showing the returned text in HTML, escape it with htmlspecialchars. Text generated by a model is still untrusted input. This example does not install or run a model on the shared Java Samples web server.

Test the edge cases

  • Stop the local server and confirm the transport exception.
  • Use an unavailable model and confirm HTTP failure is reported.
  • Test a fixture with response set to a number and confirm it is rejected.

Keep learning

Browse related tutorials. Reference: official documentation.

Reviewed 7 November 2026. AI-dependent examples require your own local model; generated text varies.