Documentation Index
Fetch the complete documentation index at: https://mintlify.com/brimblehq/rexec/llms.txt
Use this file to discover all available pages before exploring further.
PHP SDK
The official PHP SDK for Rexec provides a modern, PSR-compatible interface for Terminal as a Service.
Requirements
- PHP 8.1 or later
- Composer
Installation
composer require pipeopshq/rexec
Quick Start
<?php
require 'vendor/autoload.php';
use Rexec\RexecClient;
// Create client
$client = new RexecClient('https://your-instance.com', 'your-api-token');
// Create a container
$container = $client->containers()->create('ubuntu:24.04');
echo "Created: {$container->id}\n";
// Start it
$client->containers()->start($container->id);
// Execute a command
$result = $client->containers()->exec($container->id, "echo 'Hello from PHP!'");
echo $result->stdout;
// Clean up
$client->containers()->delete($container->id);
Client Initialization
Basic Client
use Rexec\RexecClient;
$client = new RexecClient(
'https://your-instance.com',
'your-api-token'
);
The RexecClient class is defined at /home/daytona/workspace/source/sdk/php/src/RexecClient.php:18.
With Custom Options
$client = new RexecClient(
'https://your-instance.com',
'your-api-token',
[
'timeout' => 60,
'verify' => true,
]
);
See the constructor at /home/daytona/workspace/source/sdk/php/src/RexecClient.php:35.
Container Operations
The Container service provides methods for managing sandboxed environments.
List Containers
$containers = $client->containers()->list();
foreach ($containers as $c) {
echo "{$c->name}: {$c->status}\n";
}
Create Container
// Simple creation
$container = $client->containers()->create('ubuntu:24.04');
// With options
$container = $client->containers()->create('python:3.12', [
'name' => 'my-python-sandbox',
'environment' => ['PYTHONPATH' => '/app'],
'labels' => ['project' => 'demo'],
]);
echo "Created: {$container->id}\n";
Get Container
$container = $client->containers()->get($containerId);
echo "Container {$container->name} is {$container->status}\n";
Start Container
$client->containers()->start($containerId);
Stop Container
$client->containers()->stop($containerId);
Delete Container
$client->containers()->delete($containerId);
Execute Commands
// Execute a simple command
$result = $client->containers()->exec($containerId, 'python --version');
if ($result->isSuccess()) {
echo "Output: {$result->stdout}\n";
} else {
echo "Error: {$result->stderr}\n";
}
// Execute with array command
$result = $client->containers()->exec(
$containerId,
['python', '-c', 'print("Hello")']
);
File Operations
Manage files and directories within containers.
List Files
$files = $client->files()->list($containerId, '/app');
foreach ($files as $file) {
$type = $file->isDir ? 'DIR' : "{$file->size} bytes";
echo "{$file->name} - {$type}\n";
}
Read File
$content = $client->files()->read($containerId, '/etc/hostname');
echo "Hostname: {$content}\n";
Write File
$client->files()->write(
$containerId,
'/app/script.py',
"print('Hello!')"
);
Delete File
$client->files()->delete($containerId, '/tmp/scratch.txt');
Interactive Terminal
Connect to containers via WebSocket for real-time terminal access.
Basic Terminal Usage
use React\EventLoop\Loop;
$terminal = $client->terminal()->connect($containerId);
// Set up handlers
$terminal->onData(function ($data) {
echo $data;
});
$terminal->onClose(function () {
echo "Disconnected\n";
});
$terminal->onError(function ($e) {
echo "Error: {$e->getMessage()}\n";
});
// Open connection
$terminal->open();
// Send commands
$terminal->write("ls -la\n");
$terminal->write("cd /app && python main.py\n");
// Resize terminal
$terminal->resize(120, 40);
// Run the event loop
Loop::run();
// Clean up
$terminal->close();
Terminal with Custom Size
$terminal = $client->terminal()->connect($containerId, [
'cols' => 120,
'rows' => 40,
]);
Advanced Examples
Run Script and Capture Output
function runScript(
RexecClient $client,
string $containerId,
string $script
): string {
$output = '';
$terminal = $client->terminal()->connect($containerId);
$terminal->onData(function ($data) use (&$output) {
$output .= $data;
});
$terminal->open();
$terminal->write("{$script}\nexit\n");
Loop::run();
return $output;
}
// Usage
$result = runScript(
$client,
$container->id,
'apt update && apt install -y curl'
);
echo $result;
Batch Container Creation
use React\Promise\all;
function createBatch(
RexecClient $client,
int $count
): array {
$promises = [];
for ($i = 0; $i < $count; $i++) {
$promises[] = $client->containers()->createAsync('ubuntu:24.04', [
'name' => "worker-{$i}",
]);
}
return all($promises)->wait();
}
// Create 5 containers
$containers = createBatch($client, 5);
echo "Created " . count($containers) . " containers\n";
File Upload
function uploadFile(
RexecClient $client,
string $containerId,
string $localPath,
string $remotePath
): void {
$content = file_get_contents($localPath);
$client->files()->write($containerId, $remotePath, $content);
}
// Usage
uploadFile(
$client,
$container->id,
'./local-script.sh',
'/home/script.sh'
);
Directory Sync
function syncDirectory(
RexecClient $client,
string $containerId,
string $localDir,
string $remoteDir
): void {
$client->files()->mkdir($containerId, $remoteDir);
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($localDir)
);
foreach ($iterator as $file) {
if ($file->isFile()) {
$relativePath = substr($file->getPathname(), strlen($localDir));
$remotePath = $remoteDir . $relativePath;
$content = file_get_contents($file->getPathname());
$client->files()->write($containerId, $remotePath, $content);
echo "Uploaded: {$remotePath}\n";
}
}
}
Error Handling
use Rexec\RexecException;
try {
$container = $client->containers()->get('invalid-id');
} catch (RexecException $e) {
if ($e->isApiError()) {
echo "API error {$e->getStatusCode()}: {$e->getMessage()}\n";
} else {
echo "Network error: {$e->getMessage()}\n";
}
}
The RexecException class provides methods to distinguish between API and network errors.
Type Declarations
The SDK uses PHP 8.1+ type declarations:
// All methods have full type hints
public function create(
string $image,
array $options = []
): Container;
// Return types are declared
public function list(): array;
// Nullable types where appropriate
public function get(string $id): ?Container;
WebSocket Requirements
For terminal functionality, you’ll need:
composer require react/event-loop
composer require ratchet/pawl
Testing
cd sdk/php
composer install
composer test
Source Code
View the full source code on GitHub:
License
MIT License - see LICENSE for details.