PHP code example of marceloeatworld / runpod-serverless-php

1. Go to this page and download the library: Download marceloeatworld/runpod-serverless-php 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/ */

    

marceloeatworld / runpod-serverless-php example snippets


use MarceloEatWorld\RunPod\RunPod;

// 1. Create the client with your API key
$runpod = new RunPod('your-api-key');

// 2. Target a specific endpoint
$endpoint = $runpod->endpoint('your-endpoint-id');

// 3. Submit a job
$result = $endpoint->run(['prompt' => 'A beautiful landscape']);

echo "Job submitted: " . $result->id; // e.g. "cb68890e-436f-4234-..."
echo "Status: " . $result->status;     // "IN_QUEUE"

$result = $endpoint->run(['prompt' => 'A futuristic city']);

echo $result->id;     // "cb68890e-436f-4234-..."
echo $result->status; // "IN_QUEUE"

$result = $endpoint->runSync(['prompt' => 'Hello world']);

if ($result->isCompleted()) {
    $output = $result->getOutput();
}

$result = $endpoint->run(['prompt' => 'Generate something']);

// Poll until terminal state
while ($result->isInQueue() || $result->isInProgress()) {
    sleep(2); // Wait 2 seconds between polls
    $result = $endpoint->status($result->id);
}

// Handle terminal states
if ($result->isCompleted()) {
    $output = $result->getOutput();
    echo "Done! Worker: " . $result->getWorkerId();
    echo "Execution time: " . $result->getExecutionTime() . " ms";
    echo "Queue delay: " . $result->getDelayTime() . " ms";
} elseif ($result->isFailed()) {
    echo "Error: " . $result->getError();
} elseif ($result->isTimedOut()) {
    echo "Timed out, retrying...";
    $result = $endpoint->retry($result->id);
} elseif ($result->isCancelled()) {
    echo "Job was cancelled";
}

$status = $endpoint->status('cb68890e-436f-4234-...');

echo $status->status;            // "COMPLETED"
echo $status->getOutput();       // The worker's output
echo $status->getExecutionTime(); // 2297 (ms)
echo $status->getDelayTime();    // 2188 (ms)
echo $status->getWorkerId();     // "smjcwth8e5sqvv"

$result = $endpoint->run(['prompt' => 'Write a story']);

// Wait a bit for the worker to start producing chunks
sleep(5);

$stream = $endpoint->stream($result->id);
$chunks = $stream->getStream(); // Array of stream chunks

foreach ($chunks as $chunk) {
    echo $chunk['output'];
}

$result = $endpoint->run(['prompt' => 'Something expensive']);

// Changed my mind
$cancelled = $endpoint->cancel($result->id);

$status = $endpoint->status($jobId);

if ($status->isFailed() || $status->isTimedOut()) {
    $retry = $endpoint->retry($jobId);
    echo "Retrying: " . $retry->id;     // Same job ID
    echo "Status: " . $retry->status;   // "IN_QUEUE"
}

$health = $endpoint->health();

// The raw data contains:
// {
//   "jobs": { "completed": 367, "failed": 6, "inProgress": 0, "inQueue": 0, "retried": 0 },
//   "workers": { "idle": 1, "initializing": 0, "ready": 1, "running": 0, "throttled": 0, "unhealthy": 0 }
// }

$data = $health->data;
echo "Workers ready: " . $data['workers']['ready'];
echo "Jobs in queue: " . $data['jobs']['inQueue'];
echo "Jobs failed: " . $data['jobs']['failed'];

$endpoint->purgeQueue();

$response->isCompleted();  // COMPLETED
$response->isInQueue();    // IN_QUEUE
$response->isInProgress(); // IN_PROGRESS
$response->isFailed();     // FAILED
$response->isCancelled();  // CANCELLED
$response->isTimedOut();   // TIMED_OUT

// Plain PHP
echo json_encode($response);

// Laravel
return response()->json($response);

$result = $endpoint
    ->withWebhook('https://your-site.com/api/runpod/callback')
    ->run(['prompt' => 'Your prompt']);

// No need to poll - RunPod will call your webhook
echo "Job submitted: " . $result->id;

$result = $endpoint
    ->withPolicy([
        'executionTimeout' => 900000,  // 15 min - max active runtime (ms)
        'lowPriority' => false,        // true = won't trigger worker autoscaling
        'ttl' => 3600000,              // 1 hour - total job lifespan from submission (ms)
    ])
    ->run(['prompt' => 'Your prompt']);

$result = $endpoint
    ->withS3Config([
        'accessId' => 'your-access-key-id',
        'accessSecret' => 'your-secret-access-key',
        'bucketName' => 'your-bucket-name',
        'endpointUrl' => 'https://your-s3-endpoint.com',
    ])
    ->run(['prompt' => 'Your prompt']);

$result = $endpoint
    ->withWebhook('https://your-site.com/callback')
    ->withPolicy(['executionTimeout' => 120000, 'ttl' => 600000])
    ->withS3Config(['accessId' => '...', 'accessSecret' => '...', 'bucketName' => '...', 'endpointUrl' => '...'])
    ->run(['prompt' => 'Your prompt']);

use Saloon\Exceptions\Request\RequestException;
use Saloon\Exceptions\Request\FatalRequestException;
use Saloon\Exceptions\Request\ClientException;
use Saloon\Exceptions\Request\ServerException;

try {
    $result = $endpoint->run(['prompt' => 'test']);
} catch (FatalRequestException $e) {
    // Connection-level errors: DNS failure, TLS error, timeout
    echo "Connection failed: " . $e->getMessage();
} catch (ClientException $e) {
    // 4xx errors
    $status = $e->getResponse()->status();
    match ($status) {
        401 => 'Invalid API key',
        404 => 'Endpoint not found or job TTL expired',
        429 => 'Rate limit exceeded - implement backoff',
        default => 'Client error: ' . $status,
    };
} catch (ServerException $e) {
    // 5xx errors
    echo "RunPod server error: " . $e->getResponse()->status();
} catch (RequestException $e) {
    // Catch-all for any other HTTP error
    echo "Request failed: " . $e->getResponse()->status();
}

'runpod' => [
    'api_key' => env('RUNPOD_API_KEY'),
],

use MarceloEatWorld\RunPod\RunPod;

public function register(): void
{
    $this->app->singleton(RunPod::class, function () {
        return new RunPod(config('services.runpod.api_key'));
    });
}

use MarceloEatWorld\RunPod\RunPod;
use Illuminate\Http\Request;

class AIController extends Controller
{
    public function generate(RunPod $runpod, Request $request)
    {
        $endpoint = $runpod->endpoint('your-endpoint-id');
        $result = $endpoint->run($request->validated());

        return response()->json([
            'job_id' => $result->id,
            'status' => $result->status,
        ]);
    }

    public function status(RunPod $runpod, string $jobId)
    {
        $endpoint = $runpod->endpoint('your-endpoint-id');
        $status = $endpoint->status($jobId);

        return response()->json($status); // Uses JsonSerializable
    }
}

use MarceloEatWorld\RunPod\RunPod;

class ProcessAITask implements ShouldQueue
{
    public function __construct(
        private string $endpointId,
        private array $input,
    ) {}

    public function handle(RunPod $runpod): void
    {
        $endpoint = $runpod->endpoint($this->endpointId);
        $result = $endpoint->runSync($this->input);

        if ($result->isCompleted()) {
            // Store output...
        }
    }
}
bash
composer