PHP code example of webrek / supabase-php

1. Go to this page and download the library: Download webrek/supabase-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/ */

    

webrek / supabase-php example snippets


use Supabase\Client;

$supabase = new Client('https://YOUR-PROJECT.supabase.co', 'YOUR-ANON-KEY');

$result = $supabase->functions()->invoke('hello', [
    'body' => ['name' => 'world'],
]);

// Select with filters and ordering
$rows = $supabase->from('users')
    ->select('id, email')
    ->eq('active', true)
    ->order('created_at', ascending: false)
    ->limit(10)
    ->execute();

// Select a single row
$user = $supabase->from('users')->select('*')->eq('id', 1)->single()->execute();

// maybeSingle(): returns the first matching row, or null if there are none.
// Note: unlike supabase-js it does NOT error when several rows match — it returns the first.
$maybe = $supabase->from('users')->select('*')->eq('email', '[email protected]')->maybeSingle()->execute();

// Insert (returns rows when you chain ->select())
$created = $supabase->from('users')->insert(['email' => '[email protected]'])->select()->execute();

// Update
$supabase->from('users')->update(['active' => false])->eq('id', 5)->execute();

// Delete
$supabase->from('users')->delete()->eq('id', 5)->execute();

// Upsert
$supabase->from('users')
    ->upsert(['id' => 1, 'email' => '[email protected]'])
    ->execute();

// Count rows
$total = $supabase->from('users')->select('*')->eq('active', true)->count();

// RPC (remote procedure call)
$sum  = $supabase->rpc('add', ['a' => 1, 'b' => 2])->scalar();           // a function returning one value
$rows = $supabase->rpc('search_posts', ['q' => 'php'])->select('id')->execute(); // a set-returning function

// Advanced filters: in(), or(), full-text search, ranges
$posts = $supabase->from('posts')
    ->select('id, title')
    ->in('status', ['published', 'featured'])
    ->or('author_id.eq.1,author_id.eq.2')
    ->textSearch('body', 'php & sdk')
    ->range(0, 19)
    ->execute();

// Buckets
$supabase->storage()->createBucket('avatars', ['public' => true]);
$bucket  = $supabase->storage()->getBucket('avatars');   // Bucket
$buckets = $supabase->storage()->listBuckets();          // Bucket[]

// Objects
$files = $supabase->storage();
$files->from('avatars')->upload('me.png', $bytesOrStream, ['contentType' => 'image/png', 'upsert' => true]);
$data  = $files->from('avatars')->download('me.png');    // raw bytes (capped at 50 MiB by default)
$items = $files->from('avatars')->list('folder');
$files->from('avatars')->move('me.png', 'old/me.png');
$files->from('avatars')->copy('me.png', 'copy.png');
$files->from('avatars')->remove(['old/me.png']);

// URLs
$signed = $files->from('avatars')->createSignedUrl('me.png', 60); // expires in 60s
$public = $files->from('avatars')->getPublicUrl('me.png');        // for public buckets

use Supabase\Client;
use Supabase\ClientOptions;
use Supabase\Realtime\WebSocketConnection;
use Supabase\Realtime\WebSocketConnectionFactory;

$client = new Client('https://YOUR-PROJECT.supabase.co', 'YOUR-ANON-KEY', new ClientOptions(
    webSocketFactory: new MyWebSocketConnectionFactory(),
));

$realtime = $client->realtime();

$realtime->connect();

$realtime->channel('room-1')
    ->onPostgresChanges('*', 'public', 'messages', null, function (array $change): void {
        // $change['eventType'], $change['new'], $change['old']
    })
    ->onBroadcast('cursor', function (array $message): void {
        // $message['payload']
    })
    ->subscribe();
$realtime->channel('room-1')->send('cursor', ['x' => 10, 'y' => 20]); // broadcast
$realtime->run(30.0); // blocking loop: dispatches messages and sends heartbeats for 30s
$realtime->disconnect();

$supabase->realtime()->broadcast('room-1', 'order-updated', ['id' => 42]);
$supabase->realtime()->broadcast('room-1', 'order-updated', ['id' => 42], private: true);

$realtime = $supabase->withAccessToken($jwt)->realtime();
$realtime->connect();
$realtime->channel('room-1', ['private' => true])
    ->onBroadcast('*', function (array $message): void { /* ... */ })
    ->subscribe();

// Long-running worker: rotate the token without reconnecting. Joined channels
// receive an access_token event; later joins carry the new token.
$realtime->setAuth($freshJwt);

$channel = $realtime->channel('room-1')
    ->onPresenceSync(function (): void {
        // Fired every time the full presence state is (re)synced — on join and
        // after every diff. Read the current snapshot with presenceState().
    })
    ->onPresenceJoin(function (string $key, array $currentPresences, array $newPresences): void {
        // A client started tracking; $newPresences lists their state payloads.
    })
    ->onPresenceLeave(function (string $key, array $currentPresences, array $leftPresences): void {
        // A client stopped tracking.
    })
    ->subscribe();

// Announce your own state (any serialisable array):
$channel->track(['user_id' => 42, 'online_at' => time()]);

// Read the current snapshot:
// array<string, list<array<string, mixed>>> — keyed by presence key; each
// presence carries a `presence_ref` field plus your tracked payload.
$state = $channel->presenceState();

// Stop broadcasting (leaves the channel's presence):
$channel->untrack();

$client = new Client('https://YOUR-PROJECT.supabase.co', 'YOUR-ANON-KEY', new ClientOptions(
    webSocketFactory: new MyWebSocketConnectionFactory(),
    realtimeAutoReconnect: true,
    realtimeReconnectBaseDelay: 1.0,  // initial retry delay in seconds (default)
    realtimeReconnectMaxDelay: 30.0,  // cap on retry delay in seconds (default)
));

$realtime = $client->realtime();
$realtime->connect();
// ... subscribe channels ...
$realtime->run(); // loops forever; reconnects + re-subscribes if the socket drops

use Supabase\Realtime\WebSocketConnection;
use Supabase\Realtime\WebSocketConnectionFactory;

final class MyWebSocketConnection implements WebSocketConnection
{
    private $client; // your WebSocket client of choice

    public function connect(string $url, array $headers = []): void
    {
        // open the connection to $url with $headers
    }

    public function send(string $data): void
    {
        // send a text frame
    }

    public function receive(float $timeoutSeconds): ?string
    {
        // return the next text frame, or null if $timeoutSeconds elapsed
    }

    public function close(int $code = 1000, string $reason = ''): void
    {
        // close the connection
    }

    public function isConnected(): bool
    {
        // report connection state
    }
}

final class MyWebSocketConnectionFactory implements WebSocketConnectionFactory
{
    public function create(): WebSocketConnection
    {
        return new MyWebSocketConnection();
    }
}

use Supabase\Client;
use Supabase\ClientOptions;
use Supabase\Realtime\PhrityWebSocketConnectionFactory;

$client = new Client('https://YOUR-PROJECT.supabase.co', 'YOUR-ANON-KEY', new ClientOptions(
    webSocketFactory: new PhrityWebSocketConnectionFactory(),
));

// Sign up (returns null if the project @b.com', 'password');

// Sign in
$session = $supabase->auth()->signInWithPassword('[email protected]', 'password');
$session->accessToken;   // string (redacted in dumps; never logged)
$session->user->id;      // string

// Get / update the user behind a JWT
$user = $supabase->auth()->getUser($session->accessToken);
$user = $supabase->auth()->updateUser($session->accessToken, ['data' => ['name' => 'Ada']]);

// Refresh and sign out
$session = $supabase->auth()->refreshSession($session->refreshToken);
$supabase->auth()->signOut($session->accessToken);

// OTP, password reset, OAuth URL
$supabase->auth()->signInWithOtp(['email' => '[email protected]']);
$supabase->auth()->resetPasswordForEmail('[email protected]');
$url = $supabase->auth()->getOAuthSignInUrl('github', ['redirect_to' => 'https://app.test/cb']);

use Supabase\Auth\Pkce;

// 1. Before redirecting
$pkce = Pkce::generate();
$_SESSION['pkce_verifier'] = $pkce->verifier;
header('Location: ' . $supabase->auth()->getOAuthSignInUrl('github', [
    'redirect_to' => 'https://app.test/auth/callback',
], $pkce));

// 2. In the callback (?code=...)
$session = $supabase->auth()->exchangeCodeForSession($_GET['code'], $_SESSION['pkce_verifier']);

$session = $supabase->auth()->signInWithIdToken('google', $idToken, ['nonce' => $nonce]);

use Supabase\Auth\Session;

// From a JWT you already hold (cookie, Authorization header, ...)
$asUser = $supabase->withAccessToken($jwt);
$todos  = $asUser->from('todos')->select()->execute();   // RLS applies as that user

// From a Session — refreshed first if it is expired or expires within 30s
$asUser = $supabase->withSession($session, onTokenRefreshed: function (Session $fresh): void {
    // persist $fresh->accessToken / $fresh->refreshToken (cookie, cache, ...)
});

use Supabase\ClientOptions;

$supabase = new Client($url, $anonKey, new ClientOptions(
    jwksCache: $psr16Cache,   // any PSR-16 store: APCu, Redis, filesystem, ...
    jwksCacheTtl: 600,        // seconds (default)
));

$claims = $supabase->auth()->getClaims($jwt);   // AuthException if invalid, expired or not yet valid
$claims->sub;          // user id
$claims->role;         // 'authenticated'
$claims->email;
$claims->raw['aal'];   // any other claim

$admin = (new Client('https://YOUR-PROJECT.supabase.co', 'YOUR-SERVICE-ROLE-KEY'))->auth()->admin();

$user  = $admin->createUser(['email' => '[email protected]', 'password' => 'pw']);
$user  = $admin->getUserById($user->id);
$user  = $admin->updateUserById($user->id, ['user_metadata' => ['role' => 'member']]);
$users = $admin->listUsers(page: 1, perPage: 50);   // User[]
$admin->inviteUserByEmail('[email protected]');
$link  = $admin->generateLink(['type' => 'magiclink', 'email' => '[email protected]']);
$admin->deleteUser($user->id);

use Supabase\Client;
use Supabase\ClientOptions;

$supabase = new Client('https://YOUR-PROJECT.supabase.co', 'YOUR-ANON-KEY', new ClientOptions(
    httpClient: $myPsr18Client,
    requestFactory: $myPsr17Factory,
    streamFactory: $myPsr17Factory,
));

use Supabase\Exception\SupabaseException;

try {
    $supabase->functions()->invoke('broken');
} catch (SupabaseException $e) {
    $e->getStatusCode();   // HTTP status
    $e->getErrorCode();    // Supabase error code, if any
    $e->getResponseBody(); // raw response body
}

  $httpClient = new \GuzzleHttp\Client([
      'allow_redirects' => false,
      'timeout'         => 10,
      'verify'          => true,
  ]);
  new Client($url, $key, new ClientOptions(httpClient: $httpClient));
  
bash
composer