A PHP library for quick and dirty, single-file web development.
- RT: URL routing with support for different HTTP methods
- SQ: SQLite interface with magic schema handling
- JBS: Job scheduler to run tasks at specific intervals
- AI: LLM interface and prompt builder
- CH: File-based cache handler
- GR: Generate SVG charts
- JS: Simple JSON store
- LG: Logger with colored output and file logging
- VLD: Validation library with built-in and custom rules
- ENV: Get/Set environment variables
- FS: Interact with the file system
- S3: Interact with Amazon S3
- CON: Interact with remote servers
- THR: Execute tasks in parallel
composer require janoelze/utils
View on Packagist
<?php
require_once __DIR__ . '/vendor/autoload.php';
use JanOelze\Utils\RT;
use JanOelze\Utils\SQ;
$sq = new SQ([
'db' => __DIR__ . '/todo.sqlite',
]);
$rt = new RT([
'base_url' => 'http://localhost:8001',
'page_param' => 'action',
'default_page' => 'home',
]);
$rt->addPage('GET', 'home', function () use ($sq) {
return [
'title' => 'Todo List',
'todos' => $sq->find('todo'),
];
});
$rt->addPage('POST', 'add-todo', function ($req) use ($rt, $sq) {
$title = $req->getPost('title');
if (!$title) $rt->redirect($rt->getUrl('home'));
$todo = $sq->dispense('todo');
$todo->title = $title;
$todo->completed = false;
$todo->save();
$rt->redirect($rt->getUrl('home'));
});
$rt->addPage('POST', 'toggle-todo', function ($req) use ($rt, $sq) {
$todo = $sq->findOne('todo', [
'uuid' => $req->getPost('uuid') ?? null,
]);
if ($todo) {
$todo->completed = !$todo->completed;
$todo->save();
}
$rt->redirect($rt->getUrl('home'));
});
$data = $rt->run();
?>
<!DOCTYPE html>
<html>
<head>
<title><?= $data['title'] ?></title>
</head>
<body>
<h1><?= $data['title'] ?></h1>
<?php if (isset($data['todos'])): ?>
<ul>
<?php foreach ($data['todos'] as $todo): ?>
<li>
<form method="post" action="<?= $rt->getUrl('toggle-todo') ?>">
<input type="hidden" name="uuid" value="<?= $todo->uuid ?>">
<label>
<input type="checkbox" name="completed"
<?= $todo->completed ? 'checked' : '' ?>
onchange="this.form.submit()">
<?= $todo->title ?>
</label>
</form>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<form method="post" action="<?= $rt->getUrl('add-todo') ?>">
<input type="text" name="title" placeholder="Enter a new todo">
<button type="submit">Add Todo</button>
</form>
</body>
</html>
RT
is a simple router, allowing you to define URL handlers for different HTTP methods.
__construct(array $config = [])
:
Initializes the RT instance with configuration options.addMiddleware(callable $middleware)
:
Registers a middleware to process requests.sendJson($data)
:
Sends a JSON response to the client.setHeader(string $name, string $value)
:
Sets an HTTP header.addPage(string $method, string $page, callable $handler)
:
Registers a page handler for a given HTTP method and page.getUrl(string $page, array $params = [])
:
Generates a URL based on the provided page and parameters.run()
:
Processes the current request, executes middlewares and page handlers, and returns the page data.getCurrentPage()
:
Returns the name of the current page.redirect(string $url)
:
Redirects the request to a specified URL.json($data)
:
Alias for sendJson().
use JanOelze\Utils\RT;
// Example usage of RT:
$rt = new RT([
'base_url' => 'http://localhost:8000',
'page_param' => 'action',
'default_page'=> 'home',
]);
$rt->addPage('GET', 'home', function() {
return ['title' => 'Welcome', 'content' => 'Hello World!'];
});
$data = $rt->run();
echo $data['title'];
SQ is a lightweight SQLite ORM that simplifies database interactions. It automatically creates tables, manages columns, and provides simple CRUD operations.
__construct(string $path):
:
Initializes the SQLite connection with the specified file.dispense(string $type):
:
Returns a new SQRecord instance for the given table type.find(string $type, array $criteria = []):
:
Retrieves records matching criteria; returns an array of SQRecord objects.findOne(string $type, array $criteria = []):
:
Retrieves the first matching record.execute(string $sql, array $params = []):
:
Executes a raw SQL statement.query(string $table):
:
Returns a query builder for constructing custom queries.beginTransaction(), commit(), rollBack():
:
Manage transactions.getPDO():
:
Returns the underlying PDO instance.ensureTableExists(string $table, SQRecord $record):
:
Ensures the table exists (creates it if needed) and caches its schema.addColumn(string $table, string $column, string $type):
:
Adds a new column to an existing table.getTableSchema(string $table):
:
Returns the cached schema for the table.
When you save a record using an SQRecord instance:
- SQ verifies if the table exists; if not, it creates one.
- It inspects the fields of the SQRecord and automatically adds any missing columns, inferring the data type (INTEGER, REAL, TEXT).
- Depending on whether the record is new, SQ either inserts a new record or updates an existing one.
Creating and saving a record:
use JanOelze\Utils\SQ;
$sq = new SQ(['db' => './my_database.sqlite']); // Changed initialization
$user = $sq->dispense('user');
$user->name = 'Alice';
$user->email = '[email protected]';
$user->save();
Fetching records:
// Find all users with the name 'Alice'
$users = $sq->find('user', ['name' => 'Alice']);
// Find a single user by email
$user = $sq->findOne('user', ['email' => '[email protected]']);
Building a custom query:
$results = $sq->query('user')
->where('email', 'LIKE', '%@example.com')
->orderBy('id', 'DESC')
->limit(5)
->get();
Using transactions:
try {
$sq->beginTransaction();
$user = $sq->dispense('user');
$user->name = 'Bob';
$user->email = '[email protected]';
$user->save();
// ... other operations ...
$sq->commit();
} catch (\Exception $e) {
$sq->rollBack();
// Handle exception as needed.
}
JBS
allows you to schedule and run jobs at specific intervals. It uses SQLite to store job information and run history.
__construct(array $options = [])
:
Initializes the JBS instance. Options include:db
: the SQLite database file path (default:./jobs.sqlite
)retention
: the number of seconds to keep run records (default: 1 week)
schedule(string|false $interval, string $jobId, callable $callback)
:
Registers a job. Use a human‑readable interval (e.g., "30s", "1m") orfalse
for manual execution.onFailure(callable $callback)
:
Sets a callback that is called after a job has failed 3 times. The callback receives the job ID and the output from the final attempt.run()
:
Executes all scheduled jobs with a valid interval. Typically triggered by a cron job.runJob(string $jobId)
:
Manually executes a job by its identifier.clear()
:
Clears all registered jobs.
use JanOelze\Utils\JBS;
$jbs = new JBS(['db' => './jobs.sqlite']);
// Schedule a job to run every 30 seconds.
$jbs->schedule('30s', 'fetch-news', function () {
echo "Fetching news updates...\n";
});
// Run scheduled jobs, trigger this from a cron job, for example.
$jbs->run();
// Manually run a job.
$jbs->runJob('fetch-news');
AI
is a class that interfaces with various LLM providers (currently only OpenAI) to generate responses based on prompts.
__construct(array $config = [])
:
Initializes the AI instance using a provider based on the given configuration.generate($prompt, array $params = [])
:
Generates a response. The method formats the prompt as follows:- A single message is treated as a user message.
- Two messages with the first being a system message and the second a user message.
prompt()
:
Returns a new prompt builder instance.
use JanOelze\Utils\AI;
// Create a new instance of AI, using the OpenAI endpoint.
$ai = new AI([
'platform' => [
'name' => 'openai',
'api_key' => $api_key,
'model' => 'gpt-4o-mini'
]
]);
// Query the AI with a simple prompt.
$res = $ai->generate(['What is the meaning of life?']);
// Check for errors and output the response.
if (!isset($res['error'])) {
echo $res['response'];
} else {
echo 'An error occurred: ' . $res['error'];
}
// Query the AI with a user and system message.
$res = $ai->generate(["You're a chatbot.", "What is the meaning of life?"]);
print_r($res);
// Params can be passed to the prompt.
$res = $ai->generate(['What is the meaning of life?'], ['temperature' => 0.5, 'model' => 'gpt-4o']);
print_r($res);
The prompt builder simplifies the creation of multi-message prompts. It handles replacing placeholders in messages and provides a convenient way to construct prompts.
addSystemMessage(string $message, array $params = [])
:
Adds a system message, replacing placeholders with provided parameters.addUserMessage(string $message, array $params = [])
:
Adds a user message with placeholder replacements.get()
:
Returns the constructed prompt as an array.__toString()
:
Provides a string representation for debugging.
// Create a new prompt
$prompt = $ai->prompt();
// Add a system message line
$prompt->addSystemMessage("Today's secret code is :code", ['code' => rand(1000, 9999)]);
// Add a user message
$prompt->addUserMessage("What is the secret code?");
// Get the prompt as an array
print_r($prompt->get());
// [
// "Today's secret code is 7878."
// "What is the secret code?"
// ]
// Generate the response
$res = $ai->generate($prompt->get());
if (!isset($res['error'])) {
echo $res['response'];
} else {
echo 'An error occurred: ' . $res['error'];
}
CH
is a cache handler that stores data in files.
Constructor:
- __construct(array $config)
- Requires a 'dir' option for the cache directory.
- Creates the cache directory if it does not exist.
Methods:
set(string $key, mixed $value, int|string $expiration)
:
Stores a value with a specified expiration time (numeric seconds or human-readable string like "1d").get(string $key)
:
Retrieves the value associated with the given key, or returns null if the cache entry is missing or expired.clear(string|null $key = null)
:
Clears a specific cache entry if a key is provided, otherwise clears all cache files.getFilePath(string $key)
:
Generates and returns the file path for a given cache key.parseExpiration(int|string $expiration)
:
Converts an expiration time (numeric or human-readable) into a Unix timestamp.
use JanOelze\Utils\CH;
// Initialize the cache handler with a cache directory.
$ch = new CH(['dir' => __DIR__ . '/cache']);
// Store a value with a 1-hour expiration
$ch->set('key', 'value', 3600);
// Retrieve the value
echo $ch->get('key');
// You can also store arrays, or use human-readable expiration times
$ch->set('key2', ['a' => 1, 'b' => 2], '1d');
// Retrieve the array item `a`, it will be restored as an array
echo $ch->get('key2')['a'];
GR
creates SVG charts.
plot(array $config)
:
Builds the SVG chart based on the provided configuration.output()
:
Returns the generated SVG as a string.save(string $filePath)
:
Saves the SVG output to the specified file.
use JanOelze\Utils\GR;
// Initialize the GR library
$gr = new GR();
$data = [];
for ($i = 0; $i < 100; $i++) {
$data[] = [$i, rand(0, 100)];
}
// Create a simple sparkline chart
$gr->plot([
'type' => 'line',
'animate' => 1000, // Animate the line drawing (in ms, optional)
'style' => [
'container' => [
'width' => 300,
'height' => 50,
],
],
'datasets' => [
[
'values' => $data
]
],
]);
// Save the generated SVG to a file
$gr->save('./static/sparkline.svg');
JS
is a thread-safe (finger's crossed) JSON store. It provides simple methods to retrieve, modify, and clear JSON data.
Methods:
getAll(): array
:
Returns the entire data store.getKeys(): array
:
Returns all keys in the store.get(string $key)
:
Retrieves the value for a specific key.set(string $key, mixed $value): void
:
Sets or updates a key with a value.delete(string $key): void
:
Deletes a key from the store.clear(): void
:
Clears the entire store.
use JanOelze\Utils\JS;
$js = new JS('/path/to/store.json');
// Set a value
$js->set('name', 'John Doe');
// Get a value
echo $js->get('name');
// Get all keys
print_r($js->getKeys());
// Get all data
print_r($js->getAll());
// Delete a key
$js->delete('name');
// Clear the store
$js->clear();
LG is a logger that directs output to the console or files. It supports log levels and ANSI colors for console output.
-
__construct(array $config = [])
:
Initializes the logger with options:
• date_format: PHP date() format for timestamps.
• colors: Enable/disable ANSI colors for console output.
• destinations: An array specifying "console" or file paths for logging. -
log(...$messages)
:
Logs a message at the "LOG" level. Accepts multiple arguments that are concatenated and pretty-prints arrays/objects. -
print(...$messages)
:
Alias for log(...$messages). -
write(...$messages)
:
Alias for log(...$messages). -
warn(...$messages)
:
Logs a warning message at the "WRN" level. -
error(...$messages)
:
Logs an error message at the "ERR" level. -
success(...$messages)
:
Logs a success message at the "SCS" level. -
debug(...$messages)
:
Logs a debug message at the "DBG" level.
use JanOelze\Utils\LG;
// Initialize the logger with console and file destinations.
$lg = new LG([
'date_format' => 'd-m-Y H:i:s',
'colors' => true,
'destinations'=> ['console', '/path/to/logfile.log']
]);
// Logs a message at the "LOG" level.
$lg->log('A simple log message');
// Arguments are concatenated and arrays/objects are pretty-printed.
$lg->warn('Retried', 3, 'times');
$lg->error('An error occurred:', $error);
VLD
is a simple validation library. It comes with many built-in validation rules, but is easily extendable with custom rules.
__construct()
: Initializes the VLD instance with built-in validation rules.addRule(string $ruleName, callable $callable)
: Adds a custom validation rule.isValid(string $ruleName, $value)
: Validates a value against a specified rule.
use JanOelze\Utils\VLD;
// Initialize the VLD instance.
$vld = new VLD();
// Validate an email address.
if ($vld->isValid('email', '[email protected]')) {
echo "Valid email!";
} else {
echo "Invalid email!";
}
email, url, ip, ipv4, ipv6, domain, hostname, alpha, alphaNumeric, numeric, integer, float, boolean, hex, base64, json, date, time, dateTime, creditCard, uuid, macAddress, md5, sha1, sha256, sha512, isbn, issn
To add a custom rule, use the addRule
method. For example, to validate license plates:
use JanOelze\Utils\VLD;
// Register a custom rule for license plates.
$vld->addRule('licensePlate', function ($value) {
return preg_match('/^[A-Z]{1,3}-[0-9]{1,4}$/', $value);
});
// Validate a license plate.
if ($vld->isValid('licensePlate', 'ABC-1234')) {
echo "Valid license plate!";
} else {
echo "Invalid license plate!";
}
ENV
manages environment variables. It loads global environment variables and merges them with values from a provided .env file if it exists.
__construct(?string $envFilePath = null)
:
Initializes the ENV instance by loading global environment variables and merging them with values from a provided .env file if it exists.get(?string $key = null)
:
Retrieves a specific environment variable when a key is provided, or returns all environment variables otherwise.set(string $key, $value)
:
Sets an environment variable in the internal storage and updates the system environment.
use JanOelze\Utils\ENV;
// Initialize the ENV instance with a .env file.
$env = new ENV(__DIR__ . '/.env');
// Get all environment variables.
print_r($env->get());
// Get the value of a specific environment variable.
echo $env->get('APP_ENV');
// Set a new environment variable.
$env->set('DEBUG', true);
FS
is a utility class for file system operations.
-
listFiles(string $pattern): array
:
Lists files matching a given glob pattern. -
copy(string $source, string $destination): bool
:
Copies a file or directory. If copying a directory, the operation is recursive. -
createDirectory(string $directory, int $permissions = 0777): bool
:
Recursively creates a directory with specified permissions. -
remove(string $path): bool
:
Removes a file or directory. If a directory, removal is recursive. -
write(string $path, string $content): bool
:
Writes content to a file, overwriting any existing content. -
append(string $path, string $content): bool
:
Appends content to an existing file. -
read(string $path): string
:
Reads and returns the content of a file. -
zip(string $source, string $destination): bool
:
Zips a directory into a zip file. -
info(string $path): array
:
Returns rich information about a file.
use JanOelze\Utils\FS;
$fs = new FS();
// List all PHP files in the current directory.
$files = $fs->listFiles('*.php');
// Copy a file.
$fs->copy('source.txt', 'destination.txt');
// Create a new directory.
$fs->createDirectory('new_directory');
// Remove a file.
$fs->remove('file.txt');
// Write content to a file.
$fs->write('file.txt', 'Hello, world!');
// Append content to a file.
$fs->append('file.txt', 'Goodbye, world!');
// Remove a directory.
$fs->remove('directory');
// Or file…
$fs->remove('file.txt');
// Read the content of a file.
echo $fs->read('file.txt');
// Zip the directory '/path/to/dir' into 'archive.zip'
if ($fs->zip('/path/to/dir', 'archive.zip')) {
echo "Directory zipped successfully!";
}
use JanOelze\Utils\FS;
$fs = new FS();
// Get rich information about a file.
$info = $fs->info('/tmp/hello.txt');
// => Array (
// [path] => /tmp/hello.txt
// [basename] => hello.txt
// [exists] => 1
// [realpath] => /private/tmp/hello.txt
// [filename] => hello
// [extension] => txt
// [type] => file
// [size] => 13
// [inode] => 141667381
// [device] => 16777234
// [link_count] => 1
// [block_size] => 4096
// [blocks] => 8
// [atime] => 1738757881
// [mtime] => 1738758051
// [ctime] => 1738758051
// [creation_time] =>
// [permissions] => 33188
// [owner] => janoelze
// [group] => wheel
// [readable] => 1
// [writable] => 1
// [mime_type] => text/plain
// [hash_sha256] => 315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3
// )
S3 is a simple class for working with Amazon S3 buckets.
__construct(array $config)
:
Initializes the S3 instance with configuration options including bucket name, region, access key, and secret key.upload(string $sourceFile, string $targetName)
:
Uploads a local file to the S3 bucket.download(string $sourceName, string $destinationFile)
:
Downloads a file from the S3 bucket to a local destination.read(string $targetName)
:
Reads and returns the contents of a file from the bucket.remove(string $targetName)
:
Deletes a file from the bucket.listFiles(string $pattern = null)
:
Retrieves a list of file keys in the bucket, optionally filtering with a glob pattern.getUrl(string $targetName)
:
Returns the public URL for the specified file.
use JanOelze\Utils\S3;
use JanOelze\Utils\ENV;
$env = new ENV(__DIR__ . '/.env');
// Initialize the S3 instance.
$s3 = new S3([
'bucket' => $env->get('AWS_BUCKET'),
'region' => $env->get('AWS_REGION'),
'access_key' => $env->get('AWS_ACCESS_KEY_ID'),
'secret_key' => $env->get('AWS_SECRET_ACCESS_KEY')
]);
// Upload a file
$s3->upload('/tmp/diagnostics.log', 'logs/diagnostics.log');
// List all log files
foreach ($s3->listFiles('logs/*.log') as $file) {
echo $file . "\n";
}
// Download a file
$s3->download('logs/diagnostics.log', '/tmp/diagnostics.log');
// Read a file
echo $s3->read('logs/diagnostics.log');
// Remove a file
$s3->remove('logs/diagnostics.log');
// Get the public URL for a file
echo $s3->getUrl('logs/diagnostics.log');
CON
is a simple SSH and SFTP wrapper that facilitates executing remote commands and transferring files.
-
__construct(array $options)
:
Establishes an SSH connection using options such as host, port, username, password or key. Throws an exception if the connection or authentication fails. -
exec(string $command)
:
Executes a remote command and returns an associative array with keys:stdout
,stderr
, andexit_code
. -
download(string $remoteFile, string $localFile)
:
Uses SCP to download a file from the remote server. -
upload(string $local, string $remote)
:
Uploads a local file or directory (recursively) to the remote server. Returns status based on success or failure. -
close()
:
Closes the SSH session by sending an "exit" command and clearing connection resources.
use JanOelze\Utils\CON;
$con = new CON([
'host' => 'example.com',
'port' => 22,
'username' => 'user',
'password' => 'password'
]);
// Execute a remote command
$res = $con->exec('ls -la');
// Check for errors
if ($res['exit_code'] !== 0) {
print_r($res['stderr']);
exit;
}
// Output the result
echo $res['stdout'];
// Download a file
$con->download('/remote/file.txt', '/local/file.txt');
// Upload a file
$con->upload('/local/file.txt', '/remote/file.txt');
// Close the connection
$con->close();
THR
allows you to execute tasks in parallel using forking and socket-based IPC.
__construct(array $config)
:
Sets the maximum number of workers (default: 4).submit(callable $task, mixed $input)
:
Forks a child process to execute a task.wait()
:
Waits for all tasks to finish and collects their results.
use JanOelze\Utils\THR;
// Initialize the pool with a maximum of 3 workers.
$pool = new THR(['max_workers' => 3]);
// Define a task that takes an input and returns a result.
$task = function ($input) {
sleep(1);
return $input * 2;
};
// Submit tasks to the pool.
foreach (range(1, 5) as $i) {
$pool->submit($task, $i);
}
// Wait for all tasks to finish and collect the results.
$results = $pool->wait();
// => [2, 4, 6, 8, 10]