nekland/tools
Small, dependency-free PHP utility library (semver) with high-quality helpers: StringTools (camelize, starts/endsWith, contains, multibyte ucfirst), ArrayTools, equality interface, DateTimeComparator, and temporary file/directory management.
Installation:
composer require nekland/tools
No additional configuration or service provider registration is required.
First Use Case:
Use StringTools::camelize() to convert snake_case or kebab-case strings to camelCase in Laravel models, controllers, or form requests:
use Nekland\Tools\StringTools;
$snakeCase = "user_profile_name";
$camelCase = StringTools::camelize($snakeCase); // "userProfileName"
Where to Look First:
StringTools for naming conventions (e.g., mb_ucfirst, startsWith).TemporaryFile/TemporaryDirectory for testing or file processing.DateTimeComparator for scheduling or analytics.String Normalization:
StringTools in Laravel’s FormRequest or ApiResource to standardize input/output names.
// In a FormRequest
protected function prepareForValidation(): void
{
$this->merge([
'user_profile_name' => StringTools::camelize($this->input('user_profile_name')),
]);
}
$cleaned = StringTools::removeStart($dirtyString, 'prefix_')
->removeEnd($dirtyString, '_suffix')
->camelize($dirtyString);
Temporary Resource Management:
TemporaryDirectory in Laravel’s tests/Feature for isolated file operations:
public function test_file_upload()
{
$tempDir = new TemporaryDirectory();
$tempFile = $tempDir->getTemporaryFile();
$tempFile->setContent('test content');
// Test logic using $tempFile->getPathname()
$tempDir->remove(); // Auto-cleanup
}
Storage facade for testing file uploads:
use Illuminate\Support\Facades\Storage;
$tempDir = new TemporaryDirectory();
Storage::fake('local');
Storage::disk('local')->put('test.txt', $tempDir->getTemporaryFile()->getContent());
Date Comparisons:
DateTimeComparator in Laravel’s Event listeners or Job classes:
use Nekland\Tools\DateTimeComparator;
$latest = DateTimeComparator::greatest(
now(),
Carbon::yesterday(),
Carbon::tomorrow()
);
Carbon for scheduling:
$deadline = DateTimeComparator::greatest(...$userSubmissions);
if ($deadline->isPast()) {
// Trigger notification
}
Array Operations:
ArrayTools::removeValue in Laravel’s ServiceProvider or Middleware:
$allowedRoles = ['admin', 'editor'];
ArrayTools::removeValue($allowedRoles, 'guest'); // Removes 'guest' in-place
Laravel Service Container: Bind utilities to the container for global access:
// In AppServiceProvider
$this->app->singleton('stringTools', function () {
return new StringTools();
});
Then inject via constructor:
public function __construct(private StringTools $stringTools) {}
Testing: Replace Laravel’s Storage::fake() with TemporaryDirectory for filesystem tests:
public function test_file_generation()
{
$tempDir = new TemporaryDirectory();
$this->app->instance('path.temporary', $tempDir->getPathname());
// Test logic
}
Domain-Specific Extensions: Extend EqualableInterface for Laravel models:
class User implements EqualableInterface
{
public function equals($other): bool
{
return $this->id === $other->id;
}
}
camelize Normalization:
normalize=true in StringTools::camelize() may strip unexpected characters (e.g., accents, symbols).
StringTools::camelize('café au lait'); // May return "cafeAuLait" (normalized)
$normalize=false for non-ASCII strings:
StringTools::camelize('café au lait', '_', 'UTF-8', false);
Temporary Resource Leaks:
remove() on TemporaryFile/TemporaryDirectory can fill /tmp.registering event to auto-cleanup:
// In AppServiceProvider
TemporaryDirectory::registering(function ($dir) {
app()->terminating(function () use ($dir) {
$dir->remove(true);
});
});
DateTimeComparator Edge Cases:
DateTimeInterface arguments are silently ignored. Explicit checks may be needed:
$latest = DateTimeComparator::greatest(
now(),
'invalid', // Ignored
Carbon::tomorrow()
);
$dates = array_filter(func_get_args(), fn ($arg) => $arg instanceof DateTimeInterface);
ArrayTools In-Place Modification:
ArrayTools::removeValue modifies the array by reference, which can cause unintended side effects.$filtered = array_values(array_filter($originalArray));
ArrayTools::removeValue($filtered, $value);
PHP 8.x Deprecations:
mb_* functions).$str = @StringTools::mb_ucfirst($str); // Use with caution
$tempFile = new TemporaryFile();
logger()->debug('Temp file path:', [$tempFile->getPathname()]);
$normalized = StringTools::camelize($str, '_', 'UTF-8', true);
logger()->debug('Normalized:', [$normalized]);
dd(get_debug_type($date), $date); // Check if DateTimeInterface
Custom String Tools:
Extend StringTools by creating a wrapper class:
class LaravelStringTools extends StringTools
{
public static function laravelSnakeCase(string $str): string
{
return strtolower(parent::camelize($str, '_', 'UTF-8', false));
}
}
Temporary Resource Hooks:
Override TemporaryDirectory to integrate with Laravel’s filesystem:
class LaravelTemporaryDirectory extends TemporaryDirectory
{
public function __construct()
{
parent::__construct(storage_path('app/temp'));
}
}
Equality Logic:
Implement EqualableInterface for Laravel models to enable custom equality checks in collections:
class Post implements EqualableInterface
{
public function equals($other): bool
{
return $this->slug === $other->slug;
}
}
DateTime Extensions: Add Laravel-specific comparisons:
class LaravelDateTimeComparator extends DateTimeComparator
{
public static function greatestByCarbon(...$dates): ?Carbon
{
return parent::greatest(...$dates);
}
}
No Configuration: The package has no config files, but ensure your Laravel environment supports:
TemporaryFile/TemporaryDirectory operations.mbstring for multi-byte string functions (e.g., mb_ucfirst).Encoding Defaults: Methods like camelize default to UTF-8. Explicitly specify encodings for non-ASCII strings to avoid corruption.
StringTools methods are lightweight but may not outperform native PHP functions (e.g., str_starts_with vs. StringTools::startsWith). Benchmark for critical pathsHow can I help you explore Laravel packages today?