PHP SDK
PHP SDK
Section titled “PHP SDK”A comprehensive PHP client library for the Splinterpic API. Works with PHP 7.4+ and supports both modern frameworks and vanilla PHP.
Installation
Section titled “Installation”Using Composer (Recommended)
Section titled “Using Composer (Recommended)”# If you have a composer package (future)composer require splinterpic/php-sdkManual Installation
Section titled “Manual Installation”Copy the SDK class into your project:
<?php
class SplinterpicClient { private $baseUrl; private $defaultModel;
public function __construct($config) { $this->baseUrl = $config['baseUrl']; $this->defaultModel = $config['defaultModel'] ?? '@cf/black-forest-labs/flux-1-schnell'; }
public function generate($options) { $url = $this->baseUrl . '/api/generate';
$data = [ 'prompt' => $options['prompt'], 'model' => $options['model'] ?? $this->defaultModel ];
if (isset($options['template_id'])) { $data['template_id'] = $options['template_id']; }
if (isset($options['collection_id'])) { $data['collection_id'] = $options['collection_id']; }
return $this->request('POST', $url, $data); }
public function getImages($filters = []) { $url = $this->baseUrl . '/api/images';
if (!empty($filters)) { $url .= '?' . http_build_query($filters); }
return $this->request('GET', $url); }
public function getImage($imageId) { $url = $this->baseUrl . '/api/images/' . $imageId; return $this->request('GET', $url); }
public function deleteImage($imageId) { $url = $this->baseUrl . '/api/images/' . $imageId; return $this->request('DELETE', $url); }
public function getModels() { $url = $this->baseUrl . '/api/models'; return $this->request('GET', $url); }
public function createCollection($name, $description = null) { $url = $this->baseUrl . '/api/collections';
$data = ['name' => $name]; if ($description) { $data['description'] = $description; }
return $this->request('POST', $url, $data); }
public function getCollections() { $url = $this->baseUrl . '/api/collections'; return $this->request('GET', $url); }
private function request($method, $url, $data = null) { $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
if ($data !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Content-Length: ' . strlen(json_encode($data)) ]); } else { curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json' ]); }
$response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) { throw new Exception('Request failed: ' . curl_error($ch)); }
curl_close($ch);
$decoded = json_decode($response, true);
if ($httpCode >= 400) { throw new Exception( 'API error: ' . ($decoded['error'] ?? 'Unknown error'), $httpCode ); }
return $decoded; }}Quick Start
Section titled “Quick Start”<?php
require_once 'SplinterpicClient.php';
// Initialize the client$client = new SplinterpicClient([ 'baseUrl' => 'https://splinterpic-worker.your-name.workers.dev', 'defaultModel' => '@cf/black-forest-labs/flux-1-schnell']);
// Generate an imagetry { $image = $client->generate([ 'prompt' => 'A serene mountain landscape at sunset', 'model' => '@cf/black-forest-labs/flux-1-schnell' ]);
echo "Image generated successfully!\n"; echo "ID: " . $image['id'] . "\n"; echo "URL: " . $image['r2_url'] . "\n";
} catch (Exception $e) { echo "Error: " . $e->getMessage() . "\n";}Laravel Integration
Section titled “Laravel Integration”Service Provider Setup
Section titled “Service Provider Setup”Create a service provider for easy integration:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class SplinterpicServiceProvider extends ServiceProvider{ public function register() { $this->app->singleton(SplinterpicClient::class, function ($app) { return new SplinterpicClient([ 'baseUrl' => config('services.splinterpic.base_url'), 'defaultModel' => config('services.splinterpic.default_model') ]); }); }}Configuration (config/services.php)
Section titled “Configuration (config/services.php)”return [ // ... other services
'splinterpic' => [ 'base_url' => env('SPLINTERPIC_BASE_URL'), 'default_model' => env('SPLINTERPIC_DEFAULT_MODEL', '@cf/black-forest-labs/flux-1-schnell'), ],];Environment Variables (.env)
Section titled “Environment Variables (.env)”SPLINTERPIC_BASE_URL=https://splinterpic-worker.your-name.workers.devSPLINTERPIC_DEFAULT_MODEL=@cf/black-forest-labs/flux-1-schnellController Usage
Section titled “Controller Usage”<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ImageGenerationController extends Controller{ private $splinterpic;
public function __construct(SplinterpicClient $splinterpic) { $this->splinterpic = $splinterpic; }
public function generate(Request $request) { $validated = $request->validate([ 'prompt' => 'required|string|max:500', 'model' => 'nullable|string' ]);
try { $image = $this->splinterpic->generate([ 'prompt' => $validated['prompt'], 'model' => $validated['model'] ?? null ]);
return response()->json([ 'success' => true, 'image' => $image ]);
} catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage() ], 500); } }
public function index() { try { $images = $this->splinterpic->getImages([ 'limit' => 20, 'offset' => 0 ]);
return view('images.index', [ 'images' => $images['images'] ]);
} catch (\Exception $e) { return back()->with('error', $e->getMessage()); } }}WordPress Integration
Section titled “WordPress Integration”Plugin Setup
Section titled “Plugin Setup”<?php/** * Plugin Name: Splinterpic Integration * Description: AI image generation for WordPress * Version: 1.0.0 */
require_once plugin_dir_path(__FILE__) . 'SplinterpicClient.php';
class WP_Splinterpic { private $client;
public function __construct() { $this->client = new SplinterpicClient([ 'baseUrl' => get_option('splinterpic_base_url'), 'defaultModel' => get_option('splinterpic_default_model', '@cf/black-forest-labs/flux-1-schnell') ]);
add_action('admin_menu', [$this, 'add_admin_menu']); add_action('wp_ajax_splinterpic_generate', [$this, 'ajax_generate']); }
public function add_admin_menu() { add_menu_page( 'Splinterpic', 'AI Images', 'manage_options', 'splinterpic', [$this, 'admin_page'], 'dashicons-camera' ); }
public function admin_page() { include plugin_dir_path(__FILE__) . 'templates/admin-page.php'; }
public function ajax_generate() { check_ajax_referer('splinterpic_nonce');
if (!current_user_can('manage_options')) { wp_send_json_error('Unauthorized'); return; }
$prompt = sanitize_text_field($_POST['prompt']);
try { $image = $this->client->generate(['prompt' => $prompt]);
// Optionally import to media library $attachment_id = $this->import_to_media_library($image);
wp_send_json_success([ 'image' => $image, 'attachment_id' => $attachment_id ]);
} catch (Exception $e) { wp_send_json_error($e->getMessage()); } }
private function import_to_media_library($image) { require_once(ABSPATH . 'wp-admin/includes/media.php'); require_once(ABSPATH . 'wp-admin/includes/file.php'); require_once(ABSPATH . 'wp-admin/includes/image.php');
$tmp = download_url($image['r2_url']);
if (is_wp_error($tmp)) { return false; }
$file_array = [ 'name' => $image['id'] . '.png', 'tmp_name' => $tmp ];
$id = media_handle_sideload($file_array, 0);
if (is_wp_error($id)) { @unlink($file_array['tmp_name']); return false; }
return $id; }}
new WP_Splinterpic();Symfony Integration
Section titled “Symfony Integration”Service Configuration (services.yaml)
Section titled “Service Configuration (services.yaml)”services: SplinterpicClient: arguments: $config: baseUrl: '%env(SPLINTERPIC_BASE_URL)%' defaultModel: '%env(SPLINTERPIC_DEFAULT_MODEL)%'Controller
Section titled “Controller”<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\JsonResponse;use Symfony\Component\Routing\Annotation\Route;
class ImageController extends AbstractController{ private $splinterpic;
public function __construct(SplinterpicClient $splinterpic) { $this->splinterpic = $splinterpic; }
#[Route('/api/generate', name: 'generate_image', methods: ['POST'])] public function generate(Request $request): JsonResponse { $data = json_decode($request->getContent(), true);
try { $image = $this->splinterpic->generate([ 'prompt' => $data['prompt'], 'model' => $data['model'] ?? null ]);
return $this->json($image);
} catch (\Exception $e) { return $this->json([ 'error' => $e->getMessage() ], 500); } }}Advanced Usage
Section titled “Advanced Usage”Batch Generation
Section titled “Batch Generation”<?php
function batchGenerate($prompts) { $client = new SplinterpicClient([ 'baseUrl' => 'https://splinterpic-worker.your-name.workers.dev' ]);
$results = [];
foreach ($prompts as $prompt) { try { $image = $client->generate(['prompt' => $prompt]); $results[] = [ 'success' => true, 'image' => $image ];
// Rate limiting - wait 1 second between requests sleep(1);
} catch (Exception $e) { $results[] = [ 'success' => false, 'error' => $e->getMessage(), 'prompt' => $prompt ]; } }
return $results;}
// Usage$prompts = [ 'A sunset over mountains', 'Ocean waves on a beach', 'City skyline at night'];
$results = batchGenerate($prompts);
foreach ($results as $result) { if ($result['success']) { echo "Generated: " . $result['image']['id'] . "\n"; } else { echo "Failed: " . $result['error'] . "\n"; }}Async Generation with Guzzle
Section titled “Async Generation with Guzzle”<?php
use GuzzleHttp\Client;use GuzzleHttp\Promise;
function asyncBatchGenerate($prompts) { $httpClient = new Client([ 'base_uri' => 'https://splinterpic-worker.your-name.workers.dev' ]);
$promises = [];
foreach ($prompts as $prompt) { $promises[] = $httpClient->postAsync('/api/generate', [ 'json' => [ 'prompt' => $prompt, 'model' => '@cf/black-forest-labs/flux-1-schnell' ] ]); }
// Wait for all requests to complete $results = Promise\Utils::settle($promises)->wait();
$images = [];
foreach ($results as $result) { if ($result['state'] === 'fulfilled') { $images[] = json_decode($result['value']->getBody(), true); } }
return $images;}Collection Management
Section titled “Collection Management”<?php
class ImageManager { private $client;
public function __construct($baseUrl) { $this->client = new SplinterpicClient(['baseUrl' => $baseUrl]); }
public function createCampaign($name, $prompts) { // Create collection for campaign $collection = $this->client->createCollection( $name, "Marketing campaign images" );
$collectionId = $collection['id'];
// Generate images in collection $images = []; foreach ($prompts as $prompt) { $image = $this->client->generate([ 'prompt' => $prompt, 'collection_id' => $collectionId ]); $images[] = $image; }
return [ 'collection' => $collection, 'images' => $images ]; }}
// Usage$manager = new ImageManager('https://splinterpic-worker.your-name.workers.dev');
$campaign = $manager->createCampaign('Q1 Social Media', [ 'Product showcase on white background', 'Lifestyle shot with product in use', 'Close-up detail shot']);
echo "Created campaign with " . count($campaign['images']) . " images\n";Error Handling
Section titled “Error Handling”<?php
class SplinterpicException extends Exception {}
class RateLimitException extends SplinterpicException {}class InvalidPromptException extends SplinterpicException {}class QuotaExceededException extends SplinterpicException {}
// Enhanced error handling in clientpublic function generate($options) { try { $result = $this->request('POST', $this->baseUrl . '/api/generate', $options); return $result;
} catch (Exception $e) { // Map HTTP status codes to specific exceptions $code = $e->getCode(); $message = $e->getMessage();
if ($code === 429) { throw new RateLimitException($message, $code); } elseif ($code === 400) { throw new InvalidPromptException($message, $code); } elseif ($code === 402) { throw new QuotaExceededException($message, $code); } else { throw new SplinterpicException($message, $code); } }}
// Usage with specific error handlingtry { $image = $client->generate(['prompt' => 'Test']);
} catch (RateLimitException $e) { echo "Rate limited. Please wait and try again.\n";
} catch (QuotaExceededException $e) { echo "Quota exceeded. Please upgrade your plan.\n";
} catch (InvalidPromptException $e) { echo "Invalid prompt: " . $e->getMessage() . "\n";
} catch (SplinterpicException $e) { echo "API error: " . $e->getMessage() . "\n";}Testing
Section titled “Testing”PHPUnit Test Example
Section titled “PHPUnit Test Example”<?php
use PHPUnit\Framework\TestCase;
class SplinterpicClientTest extends TestCase{ private $client;
protected function setUp(): void { $this->client = new SplinterpicClient([ 'baseUrl' => 'https://splinterpic-worker.your-name.workers.dev' ]); }
public function testGenerate() { $result = $this->client->generate([ 'prompt' => 'Test image generation' ]);
$this->assertArrayHasKey('id', $result); $this->assertArrayHasKey('r2_url', $result); $this->assertArrayHasKey('prompt', $result); }
public function testGetModels() { $result = $this->client->getModels();
$this->assertArrayHasKey('models', $result); $this->assertIsArray($result['models']); $this->assertGreaterThan(0, count($result['models'])); }}Best Practices
Section titled “Best Practices”1. Use Environment Variables
Section titled “1. Use Environment Variables”// Never hardcode API URLs$client = new SplinterpicClient([ 'baseUrl' => getenv('SPLINTERPIC_BASE_URL')]);2. Implement Caching
Section titled “2. Implement Caching”function getCachedModels() { $cacheKey = 'splinterpic_models'; $cached = apcu_fetch($cacheKey);
if ($cached !== false) { return $cached; }
$client = new SplinterpicClient([...]); $models = $client->getModels();
apcu_store($cacheKey, $models, 3600); // Cache for 1 hour
return $models;}3. Log All Requests
Section titled “3. Log All Requests”private function request($method, $url, $data = null) { error_log("Splinterpic API: $method $url");
// ... existing request code ...
if ($httpCode >= 400) { error_log("Splinterpic API error: $httpCode - " . $response); }
return $decoded;}Support
Section titled “Support”- Documentation: API Reference
- Email: support@splinterpic.com