Skip to content

PHP ​

PHP applications interact with the local Riot Client session by executing the riotclient CLI as a child process with proc_open() and decoding the JSON output with json_decode(). The whole example lives in examples/php/main.php and passes php -l.

Setup ​

  1. Install the CLI globally:
bash
npm install -g @valoranchi/riot-client
  1. PHP 8.1 or later with the built-in json extension.

Read ​

Run whoami and owned-items with proc_open() and decode the output into associative arrays:

php
/** @return array{0:int,1:string,2:string} exit code, stdout, stderr */
function runCliCommand(array $args): array
{
    $descriptors = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
    $command = array_merge(['riotclient'], $args);
    $process = proc_open($command, $descriptors, $pipes);
    if (!is_resource($process)) {
        throw new RuntimeException('Failed to spawn riotclient');
    }
    $stdout = stream_get_contents($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    return [proc_close($process), (string) $stdout, (string) $stderr];
}

function readExample(): void
{
    [$code, $stdout] = runCliCommand(['whoami']);
    if ($code === 0) {
        $player = json_decode($stdout, true, 512, JSON_THROW_ON_ERROR);
        echo "Player: {$player['gameName']}#{$player['tagLine']} ({$player['region']})\n";
    }

    [$code, $stdout] = runCliCommand(['owned-items', '--language', 'en-US']);
    if ($code === 0) {
        $collection = json_decode($stdout, true, 512, JSON_THROW_ON_ERROR);
        echo "Collection generated at: {$collection['generatedAt']}\n";
        foreach ($collection['weapons'] as $weapon) {
            if (!empty($weapon['skins'])) {
                echo "- {$weapon['name']}: {$weapon['skins'][0]['name']}\n";
            }
        }
    }
}

Write with Validation ​

Every mutation command performs a dry run locally unless --yes is given. If validation fails, riotclient exits with code 6 and writes the details to stderr:

php
function equipCard(string $cardUuid, bool $execute = false): void
{
    $args = ['equip', '--card', $cardUuid];
    if ($execute) {
        $args[] = '--yes';
    }
    [$exitCode, $stdout, $stderr] = runCliCommand($args);

    if ($exitCode === 0) {
        $label = $execute ? 'Equipped card:' : 'Dry run passed:';
        echo "{$label} " . trim($stdout) . "\n";
    } elseif ($exitCode === 6) {
        $error = json_decode($stderr, true, 512, JSON_THROW_ON_ERROR)['error'];
        $reason = $error['reason'] ?? 'unknown';
        fwrite(STDERR, "Validation failed: {$reason} - {$error['message']}\n");
    } else {
        fwrite(STDERR, "Command failed [code {$exitCode}]: {$stderr}\n");
    }
}

Events ​

Stream real-time events line by line with popen():

php
function streamEvents(): void
{
    $handle = popen('riotclient watch --only friend:presence,message', 'r');
    if ($handle === false) {
        throw new RuntimeException('Failed to spawn riotclient watch');
    }

    echo "Listening for real-time events. Press Ctrl+C to terminate.\n";
    while (($line = fgets($handle)) !== false) {
        $line = trim($line);
        if ($line === '') {
            continue;
        }
        $event = json_decode($line, true, 512, JSON_THROW_ON_ERROR);
        $data = $event['data'] ?? [];
        if ($event['event'] === 'friend:presence') {
            $name = $data['friend']['gameName'] ?? '';
            $state = $data['friend']['presence']['state'] ?? '';
            echo "Friend {$name} is now {$data['change']} ({$state})\n";
        } elseif ($event['event'] === 'message') {
            echo "[{$data['from']['gameName']}]: {$data['body']}\n";
        }
    }
    pclose($handle);
}

Types ​

Generate typed PHP classes from the JSON Schemas with quicktype:

bash
npx quicktype schema/OwnedItems.json --src-lang schema -l php -o OwnedItems.php

A hand-written class of the same shape, for a single model:

php
/** Generated with: npx quicktype schema/OwnedItems.json --src-lang schema -l php -o OwnedItems.php */
final class OwnedSkin
{
    public function __construct(public readonly string $uuid, public readonly string $name)
    {
    }

    /** @param array<string,mixed> $data */
    public static function fromArray(array $data): self
    {
        return new self((string) $data['uuid'], (string) $data['name']);
    }
}

Not affiliated with Riot Games