PHP code example of ez-php / ai

1. Go to this page and download the library: Download ez-php/ai library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ez-php / ai example snippets


// config/ai.php
return [
    'driver' => getenv('AI_DRIVER') ?: 'openai',

    // Seconds a streamed completion may send nothing before it fails (no total limit).
    'stream_idle_timeout' => (int) (getenv('AI_STREAM_IDLE_TIMEOUT') ?: 120),

    'openai' => [
        'api_key'  => getenv('OPENAI_API_KEY') ?: '',
        'model'    => getenv('OPENAI_MODEL') ?: 'gpt-4o-mini',
        'base_url' => getenv('OPENAI_BASE_URL') ?: 'https://api.openai.com',
    ],

    'anthropic' => [
        'api_key'     => getenv('ANTHROPIC_API_KEY') ?: '',
        'model'       => getenv('ANTHROPIC_MODEL') ?: 'claude-sonnet-4-6',
        'api_version' => getenv('ANTHROPIC_API_VERSION') ?: '2023-06-01',
    ],

    'gemini' => [
        'api_key' => getenv('GEMINI_API_KEY') ?: '',
        'model'   => getenv('GEMINI_MODEL') ?: 'gemini-2.0-flash',
    ],

    'mistral' => [
        'api_key'  => getenv('MISTRAL_API_KEY') ?: '',
        'model'    => getenv('MISTRAL_MODEL') ?: 'mistral-small-latest',
        'base_url' => getenv('MISTRAL_BASE_URL') ?: 'https://api.mistral.ai',
    ],

    'grok' => [
        'api_key'  => getenv('GROK_API_KEY') ?: '',
        'model'    => getenv('GROK_MODEL') ?: 'grok-3-mini',
        'base_url' => getenv('GROK_BASE_URL') ?: 'https://api.x.ai',
    ],

    'log' => [
        'inner_driver' => getenv('AI_LOG_INNER_DRIVER') ?: 'openai',
    ],
];

use EzPhp\Ai\Ai;
use EzPhp\Ai\Request\AiRequest;

$response = Ai::complete(AiRequest::make('What is the capital of France?'));

echo $response->content(); // "Paris"

use EzPhp\Ai\AiClientInterface;
use EzPhp\Ai\Request\AiRequest;

class MyService
{
    public function __construct(private AiClientInterface $ai) {}

    public function ask(string $question): string
    {
        $response = $this->ai->complete(AiRequest::make($question));
        return $response->content();
    }
}

use EzPhp\Ai\Request\AiRequest;
use EzPhp\Ai\Message\AiMessage;

// Single user message
$request = AiRequest::make('Hello');

// Explicit message list
$request = AiRequest::withMessages(
    AiMessage::system('You are a helpful assistant.'),
    AiMessage::user('What is 2 + 2?'),
);

// Chain withers
$request = AiRequest::make('Explain async/await')
    ->withModel('gpt-4o')
    ->withTemperature(0.7)
    ->withMaxTokens(500)
    ->withSystemPrompt('You are a concise technical writer.');

// Append a message
$request = $request->addMessage(AiMessage::user('Give an example in PHP.'));

use EzPhp\Ai\Message\AiMessage;
use EzPhp\Ai\Message\ContentPart;

// Plain text
AiMessage::user('Hello');
AiMessage::assistant('Hi there!');
AiMessage::system('You are a helpful assistant.');

// Multimodal (text + image URL)
AiMessage::userWithParts([
    ContentPart::text('What is in this image?'),
    ContentPart::imageUrl('https://example.com/image.png'),
]);

use EzPhp\Ai\Ai;
use EzPhp\Ai\Request\AiRequest;
use EzPhp\Ai\StreamingAiClientInterface;

$client = Ai::getClient();

if ($client instanceof StreamingAiClientInterface) {
    $stream = $client->stream(AiRequest::make('Tell me a story.'));

    foreach ($stream as $chunk) {
        echo $chunk->content();

        if ($chunk->isFinal()) {
            echo PHP_EOL;
            echo 'Finish reason: ' . $chunk->finishReason()?->value . PHP_EOL;
        }
    }
}

// Or collect the full text at once
$text = $stream->collect();

use EzPhp\Ai\AiStreamException;

try {
    $text = $stream->collect();
} catch (AiStreamException $e) {
    // partial output is not a complete answer
}

use EzPhp\Http\StreamedResponse;

// Make the call here, before returning, so provider errors still become a normal error response.
$stream = $client->stream(AiRequest::make('Tell me a story.'));

return StreamedResponse::sse(fn () => $stream->toSseEvents());

use EzPhp\Ai\Ai;
use EzPhp\Ai\Request\AiRequest;
use EzPhp\Ai\Message\AiMessage;
use EzPhp\Ai\Response\FinishReason;
use EzPhp\Ai\Tool\ToolDefinition;

$getWeather = new ToolDefinition(
    name: 'get_weather',
    description: 'Returns the current weather for a city.',
    parameters: [
        'type' => 'object',
        'properties' => [
            'city' => ['type' => 'string', 'description' => 'The city name'],
        ],
        'lt       => 'Unknown tool',
        };

        $toolMessages[] = AiMessage::tool($result, $call->id());
    }

    $request = $request
        ->addMessage(AiMessage::assistantWithToolCalls(...$response->toolCalls()))
        ->addMessage(...$toolMessages);  // may need multiple addMessage calls

    $response = Ai::complete($request);
}

echo $response->content();

// config/ai.php
return [
    'driver' => 'openai',                 // completion driver
    'embedding_driver' => 'openai',       // 'openai' | 'gemini' | 'null' (default)
    'openai' => ['api_key' => getenv('OPENAI_API_KEY') ?: null],
];

use EzPhp\Ai\Ai;

$vector = Ai::embed('The quick brown fox');                          // float[]
$vector = Ai::embed('Hello world', 'text-embedding-3-large');        // override model
$vectors = Ai::embedBatch(['The quick brown fox', 'jumps over the lazy dog']); // float[][]

use EzPhp\Ai\Driver\OpenAiConfig;
use EzPhp\Ai\Driver\OpenAiEmbeddingDriver;
use EzPhp\HttpClient\CurlTransport;
use EzPhp\HttpClient\HttpClient;

$driver = new OpenAiEmbeddingDriver(
    new HttpClient(new CurlTransport()),
    new OpenAiConfig(apiKey: $_ENV['OPENAI_API_KEY']),
);

// Returns float[]
$vector = $driver->embed('The quick brown fox');

// Override model
$vector = $driver->embed('Hello world', 'text-embedding-3-large');

// Batch: one request for multiple inputs — returns float[][], in input order
$vectors = $driver->embedBatch(['The quick brown fox', 'jumps over the lazy dog']);

use EzPhp\Ai\Driver\GeminiConfig;
use EzPhp\Ai\Driver\GeminiEmbeddingDriver;
use EzPhp\HttpClient\CurlTransport;
use EzPhp\HttpClient\HttpClient;

$driver = new GeminiEmbeddingDriver(
    new HttpClient(new CurlTransport()),
    new GeminiConfig(apiKey: $_ENV['GEMINI_API_KEY']),
);

// Default model: text-embedding-004
$vector = $driver->embed('The quick brown fox');

$response = Ai::complete($request);

$response->content();       // string — generated text
$response->finishReason();  // FinishReason enum: STOP, LENGTH, TOOL_CALL, CONTENT_FILTER, ERROR
$response->usage();         // TokenUsage
$response->toolCalls();     // list<ToolCall> — non-empty when finishReason === TOOL_CALL
$response->hasToolCalls();  // bool
$response->rawBody();       // string — raw JSON from the provider

$usage = $response->usage();
$usage->inputTokens();   // int
$usage->outputTokens();  // int
$usage->totalTokens();   // int

// config/ai.php
return [
    'driver' => 'log',
    'log'    => ['inner_driver' => 'openai'],
    'openai' => ['api_key' => getenv('OPENAI_API_KEY') ?: null],
];

use EzPhp\Ai\Driver\LogDriver;

$driver = new LogDriver(
    $innerDriver,
    function (string $level, string $message, array $context): void {
        $this->logger->log($level, $message, $context);
    },
);

use EzPhp\Ai\RetryAiClient;

$client = new RetryAiClient(
    inner: $innerClient,
    maxAttempts: 3,      // total attempts including the first; minimum 1
    baseDelayMs: 500,    // exponential backoff base
);

$response = $client->complete($request);

use EzPhp\Ai\AiVariantPool;

$pool = new AiVariantPool($client, $db, table: 'ai_variants');

// Returns a random stored variant; generates and persists one on a cache miss
$description = $pool->getVariant('sword_description', $request);

// Pre-generate more variants ahead of time (5 by default)
$pool->generateBatch('sword_description', $request, count: 10);

// Check how many variants exist for a key
$count = $pool->countVariants('sword_description');

// config/ai.php — Azure OpenAI
'openai' => [
    'api_key'  => getenv('AZURE_OPENAI_API_KEY') ?: null,
    'model'    => 'gpt-4o',
    'base_url' => getenv('AZURE_OPENAI_ENDPOINT') ?: null, // e.g. https://my-resource.openai.azure.com
],

use EzPhp\Ai\Driver\NullDriver;
use EzPhp\Ai\Request\AiRequest;

$driver = NullDriver::withContent('Paris');
$response = $driver->complete(AiRequest::make('What is the capital of France?'));

assertEquals('Paris', $response->content());

use EzPhp\Ai\Driver\OpenAiDriver;
use EzPhp\Ai\Driver\OpenAiConfig;
use EzPhp\Ai\Request\AiRequest;
use EzPhp\HttpClient\FakeTransport;
use EzPhp\HttpClient\HttpClient;

$fake = new FakeTransport();
$fake->queue(200, '{"choices":[{"message":{"role":"assistant","content":"Paris"},"finish_reason":"stop"}],"usage":{"prompt_tokens":10,"completion_tokens":5,"total_tokens":15}}');

$driver = new OpenAiDriver(
    new HttpClient($fake),
    new OpenAiConfig('test-key'),
);

$response = $driver->complete(AiRequest::make('Capital of France?'));
assertEquals('Paris', $response->content());
bash
composer