coduo/php-humanizer
Humanize and format values for people: turn field names into readable labels, truncate plain text or HTML safely to word boundaries, and handle common string transformations. Lightweight PHP utility with simple static APIs.
Installation:
composer require coduo/php-humanizer
No additional configuration is required—just autoload the package.
First Use Case: Humanize a database column name in a Laravel view:
use Coduo\PHPHumanizer\StringHumanizer;
$humanized = StringHumanizer::humanize('user_id'); // "User id"
return view('profile', ['fieldName' => $humanized]);
Key Classes to Know:
StringHumanizer (for text transformations)NumberHumanizer (for numeric formatting)DateTimeHumanizer (for time differences)CollectionHumanizer (for list formatting)Pattern: Automatically humanize database column names for API responses or admin panels.
use Coduo\PHPHumanizer\StringHumanizer;
class User extends Model
{
protected $hidden = ['password'];
public function getHumanizedAttributes(array $attributes)
{
return collect($attributes)
->mapWithKeys(fn ($value, $key) => [
StringHumanizer::humanize($key) => $value
]);
}
}
Usage:
$user = User::find(1);
return response()->json($user->getHumanizedAttributes($user->toArray()));
Pattern: Convert bytes to human-readable sizes (e.g., for file uploads).
use Coduo\PHPHumanizer\NumberHumanizer;
public function showFileSize(int $bytes)
{
return NumberHumanizer::binarySuffix($bytes); // "1.2 MB"
}
Integration with Laravel:
use Illuminate\Support\Facades\Response;
return Response::json([
'size' => NumberHumanizer::binarySuffix($file->size()),
'name' => $file->name
]);
Pattern: Display relative time (e.g., "2 hours ago") in notifications.
use Coduo\PHPHumanizer\DateTimeHumanizer;
public function toArray($notifiable)
{
return [
'message' => "Post updated " . DateTimeHumanizer::difference(
now(),
$this->created_at
),
];
}
Pattern: Format lists of items (e.g., tags, authors) with Oxford commas.
use Coduo\PHPHumanizer\CollectionHumanizer;
$authors = ['J.K. Rowling', 'George R.R. Martin', 'Tolkien'];
$formatted = CollectionHumanizer::oxford($authors);
// "J.K. Rowling, George R.R. Martin, and 1 other"
Use Case: Admin panel filters or user profiles.
return view('profile', [
'tags' => CollectionHumanizer::oxford($user->tags->pluck('name')->toArray())
]);
Pattern: Override translations for locale-specific formatting.
// config/humanizer.php (if using a config package wrapper)
'humanizer' => [
'locale' => app()->getLocale(),
'translations' => [
'difference' => [
'pl' => [
'seconds' => 'sekund',
'minute' => 'minut',
// ... custom translations
],
],
],
],
Dynamic Locale Switching:
use Coduo\PHPHumanizer\DateTimeHumanizer;
$locale = app()->getLocale();
$difference = DateTimeHumanizer::difference(
now(),
$event->created_at,
$locale
);
Pattern: Safely truncate HTML content (e.g., blog excerpts).
use Coduo\PHPHumanizer\StringHumanizer;
$excerpt = StringHumanizer::truncateHtml(
$post->content,
50,
'<strong><em><a>',
'...'
);
// "<strong>Lorem ipsum...</strong>"
binarySuffix() or metricSuffix() may use unexpected decimal separators (e.g., , vs .) in non-English locales.
Fix: Explicitly pass the locale:
NumberHumanizer::binarySuffix(1500, 'pl'); // "1,5 kB" (Polish)
truncateHtml() may break if the HTML tag is split mid-tag (e.g., truncating "<a href=").
Fix: Whitelist allowed tags:
StringHumanizer::truncateHtml($html, 100, '<a><strong>');
strip_tags() as a fallback for untrusted HTML.preciseDifference() can produce overly verbose output for small time gaps.
Fix: Combine with a threshold check:
$diff = DateTimeHumanizer::difference($past, $now);
$precise = strlen($diff) > 20
? DateTimeHumanizer::preciseDifference($past, $now)
: $diff;
DateTimeHumanizer::difference() for most cases; reserve preciseDifference() for detailed contexts.humanize() converts underscores to spaces but may not handle camelCase optimally.
Fix: Pre-process strings:
StringHumanizer::humanize(str_replace(' ', '_', 'user first name'));
// "User first name" (instead of "User_First_Name")
StringHumanizer::humanize(preg_replace('/([a-z])([A-Z])/', '$1 $2', 'userFirstName'));
oxford() or preciseDifference() in loops can slow down responses.
Fix: Cache results or limit precision:
// Cache the formatted collection
$cachedAuthors = Cache::remember("authors.{$user->id}", now()->addHours(1), function () use ($user) {
return CollectionHumanizer::oxford($user->authors->pluck('name')->toArray());
});
class AppHumanizer extends StringHumanizer
{
public static function humanizeWithTitle(string $text): string
{
return ucfirst(parent::humanize($text));
}
}
php artisan vendor:publish --tag=humanizer-translations
Then edit resources/lang/{locale}/humanizer.php.oxford()).
Debug:
dd(
StringHumanizer::humanize(''),
NumberHumanizer::binarySuffix(0),
CollectionHumanizer::oxford([])
);
htmlspecialchars() to verify tag integrity:
dd(htmlspecialchars(StringHumanizer::truncateHtml($html, 50)));
public function register()
{
$this->app->singleton('humanizer', function () {
return new AppHumanizer(); // Your extended class
});
}
use Coduo\PHPHumanizer\StringHumanizer;
public function rules()
{
return [
'file_name' => [
'required',
function ($attribute, $value, $fail) {
if (strlen(StringHumanizer::humanize($value)) > 50) {
$fail('The ' . StringHumanizer::humanize($attribute) . ' may not be greater than 50 characters.');
}
},
],
];
}
How can I help you explore Laravel packages today?