PHP code example of trehinos / thor-common

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

    

trehinos / thor-common example snippets


use Thor\Common\Types\Strings;
use Thor\Common\Types\PlaceholderFormat;

$template = 'Hello {name}, today is {day}!';
$out = Strings::interpolate($template, [
    'name' => 'Ada',
    'day'  => 'Thursday',
]);
// "Hello Ada, today is Thursday!"

// Different placeholder styles
Strings::interpolate('Hello $name', ['name' => 'Ada'], PlaceholderFormat::SIGIL);    // Hello Ada
Strings::interpolate('Hello ${name}', ['name' => 'Ada'], PlaceholderFormat::SHELL);  // Hello Ada

Strings::left('abcdef', 3);   // 'abc'
Strings::right('abcdef', 3);  // 'def'
Strings::prefix('ID-', '42'); // 'ID-42'
Strings::suffix('42', '-OK'); // '42-OK'
// Trim specific padding and pad/truncate to length
Strings::trimOrPad('  42  ', 5, ' ', STR_PAD_LEFT); // '   42'

use Thor\Common\Types\Arrays;

$input = [
    ['id' => 1, 'name' => 'Ada'],
    ['id' => 2, 'name' => 'Grace'],
];
$out = Arrays::turnOver($input);
// [ 'id' => [1,2], 'name' => ['Ada','Grace'] ]

use Thor\Common\Types\DateTimes;
use DateTimeImmutable;

DateTimes::translate('2025-10-09');              // '09/10/2025'

$now = new DateTimeImmutable('2025-10-09 18:25:00');
$yesterday = $now->modify('-1 day 14:10:00');
DateTimes::getRelativeDateTime($yesterday, 'Y-m-d', 'Yesterday', $now); // 'Yesterday 14:10'

// Generate a DatePeriod over a month by days
$start = new DateTimeImmutable('2025-10-01');
$period = DateTimes::period($start); // until last day of the month by 1 day

// ClockInterface: get "now" from the singleton DateTimes implementation
$clockNow = DateTimes::get()->now();

use Thor\Common\Types\Safe\Result;

function divide(int $a, int $b): Result {
    if ($b === 0) {
        return Result::error('Division by zero');
    }
    return Result::ok($a / $b);
}

$quotient = divide(10, 2)
    ->unwrapOr(-1); // 5

$message = divide(1, 0)
    ->match(
        fn($ok) => "ok=$ok",
        fn($err) => "error=$err",
    ); // 'error=Division by zero'

use Thor\Common\Types\Safe\Option;
use Thor\Common\Types\Safe\Maybe;

// Constructing
$opt1 = Option::some('value');        // Some('value')
$opt2 = Option::none();               // None
$opt3 = Option::from($_GET['q'] ?? null); // Some or None depending on null

// Inspecting
$opt1->isSome(); // true
$opt2->isNone(); // true
$opt1->is();     // Maybe::SOME
$opt2->is();     // Maybe::NONE
$opt1->isA(Maybe::SOME); // true

// Consuming
$name = $opt3->unwrapOr('guest'); // returns the inner value or 'guest'
$val  = $opt3->unwrapOrElse(fn() => computeDefault());

// Pattern matching style
$msg = $opt3->matches(
    fn($v) => "got=$v",
    fn()   => "none",
);

// Exceptions on None
try {
    $must = $opt2->unwrap(); // throws RuntimeException if None
} catch (\Throwable $e) {
    // handle
}

// Or throw custom exception
$must = $opt2->unwrapOrThrow(new \InvalidArgumentException('missing value'));

use Thor\Common\Validation\Filters\RegexFilter;

$filter = new RegexFilter('/^[a-z]+$/i');

$ok = $filter->filter('Foobar'); // 'Foobar'
$fail = $filter->filter('Foo 123'); // null (per filter_var behavior)

use Thor\Common\Configuration\ConfigurationFromFile;
use Thor\Common\Configuration\ConfigurationFolder;

// Load a single config from YAML (provide path without extension)
$app = ConfigurationFromFile::fromFile('/path/to/app');
$dsn = $app->database['dsn'] ?? null;

// Load multiple configs from a YAML list
$items = ConfigurationFromFile::multipleFromFile('/path/to/list', ConfigurationFromFile::class);

// Write configuration to a YAML file
$app->write('/path/to/out.yml');

// Interpolate paths from a context
$cfgFolder = new ConfigurationFolder(['env' => 'prod', 'name' => 'myapp']);
$resolved = $cfgFolder->getPath('/opt/{name}/{env}/config.yml'); // '/opt/myapp/prod/config.yml'

use Thor\Common\Debug\Logger;
use Thor\Common\Debug\LogLevel;

// Initialize a global logger (file will be created under base path)
Logger::set(LogLevel::DEBUG, __DIR__ . '/var/');

Logger::info('Server started');
Logger::error('Something went wrong', ['context' => 'value']);

try {
    throw new RuntimeException('Boom');
} catch (Throwable $e) {
    Logger::logThrowable($e); // writes ERROR + details at DEBUG level
}

use Thor\Common\FileSystem\Folders;
use Thor\Common\FileSystem\FileSystem;

Folders::createIfNotExists(__DIR__ . '/cache');
FileSystem::write(__DIR__ . '/cache/app.log', "Started\n");
FileSystem::appendIfExists(__DIR__ . '/cache/app.log', "Tick\n");

// Recursively copy/remove
Folders::copyTree(__DIR__ . '/assets', __DIR__ . '/public');
$deleted = Folders::removeTree(__DIR__ . '/public', mask: '.*\\.(tmp|bak)$');

use Thor\Common\Encryption\Guid;

$g = new Guid(16);
(string)$g;       // Uppercase hex grouped like a GUID
$g->getHex();     // Lowercase hex
$g->getBase64();  // Base64
Guid::hex();      // Fresh lowercase hex string

use Thor\Common\Types\Collection\Collection;

$users = new Collection([
    ['id' => 1, 'name' => 'Ada'],
    ['id' => 2, 'name' => 'Grace'],
]);

$names = $users->column('name')->values()->toArray(); // ['Ada','Grace']