respect/string-formatter
Flexible PHP string formatting library with chainable formatters and templated placeholders. Mask, pattern, date, number, and more to transform/format values (e.g., credit cards, phones, amounts) via FormatterBuilder or PlaceholderFormatter modifiers.
Installation:
composer require respect/string-formatter
Basic Usage:
use Respect\StringFormatter\FormatterBuilder as f;
// Mask a credit card number
echo f::create()->mask('1234567890123456')->format('1234567890123456');
// Output: 1234 56** **** 3456
// Format a phone number
echo f::create()->pattern('###-###-####')->format('1234567890');
// Output: 123-456-7890
PlaceholderFormatter for Templates:
use Respect\StringFormatter\PlaceholderFormatter;
$formatter = new PlaceholderFormatter([
'name' => 'John Doe',
'email' => 'john@example.com',
]);
echo $formatter->format('Hello {{name|uppercase}}, your email is {{email}}');
// Output: Hello JOHN DOE, your email is john@example.com
// In a Laravel controller or service
use Respect\StringFormatter\FormatterBuilder as f;
public function showUserProfile(User $user) {
$maskedPhone = f::create()->mask('###-###-####')->format($user->phone);
$maskedEmail = f::create()->mask('*@*')->format($user->email);
return view('profile', [
'phone' => $maskedPhone,
'email' => $maskedEmail,
]);
}
Leverage FormatterBuilder to chain multiple formatters for complex transformations:
// In a Laravel request handler
use Respect\StringFormatter\FormatterBuilder as f;
public function processInput(Request $request) {
$cleanedInput = f::create()
->trim()
->lowercase()
->pattern('###-###-####')
->format($request->input('phone'));
return response()->json(['phone' => $cleanedInput]);
}
Register formatters as Laravel services for dependency injection:
// In AppServiceProvider
public function register() {
$this->app->singleton(FormatterBuilder::class, function () {
return f::create();
});
}
// Usage in a controller
public function __construct(private FormatterBuilder $formatter) {}
public function updateProfile(Request $request) {
$formattedName = $this->formatter
->trim()
->uppercase()
->format($request->input('name'));
// ...
}
Create custom validation rules using formatters:
// app/Rules/MaskedCreditCard.php
use Respect\StringFormatter\CreditCardFormatter;
use Illuminate\Contracts\Validation\Rule;
class MaskedCreditCard implements Rule {
public function passes($attribute, $value) {
$formatter = new CreditCardFormatter();
return $formatter->format($value) !== $value;
}
public function message() {
return 'The :attribute must be a valid credit card number.';
}
}
// Usage in FormRequest
public function rules() {
return [
'credit_card' => ['required', new MaskedCreditCard],
];
}
Use PlaceholderFormatter for dynamic content in Blade templates:
// In a controller
public function generateInvoice(User $user, Order $order) {
$formatter = new PlaceholderFormatter([
'user' => $user,
'order' => $order,
'date' => now()->format('Y-m-d'),
]);
return view('invoice', [
'content' => $formatter->format(file_get_contents('invoice_template.txt')),
]);
}
// invoice_template.txt
Invoice Number: {{order->id|pattern:####-####}}
Date: {{date|date:Y/m/d}}
Customer: {{user->name|uppercase}}
Apply formatters in Laravel API resources:
// app/Http/Resources/UserResource.php
public function toArray($request) {
return [
'name' => $this->formatter
->trim()
->uppercase()
->format($this->name),
'phone' => $this->formatter
->pattern('(###) ###-####')
->format($this->phone),
'email' => $this->formatter
->mask('*@*')
->format($this->email),
];
}
Create middleware to format request/response data globally:
// app/Http/Middleware/FormatStrings.php
public function handle($request, Closure $next) {
$response = $next($request);
if ($response->isJson()) {
$data = $response->getData(true);
$formatter = f::create();
foreach ($data as &$value) {
if (is_string($value)) {
$value = $formatter->mask('*')->format($value);
}
}
$response->setData($data);
}
return $response;
}
PatternFormatter Regex Limitations:
// This may fail with Unicode or special characters
f::create()->pattern('/[^a-zA-Z0-9]/')->format('Hello! 世界');
PlaceholderFormatter Scope:
|lowercase to normalize case.{{user.address.city}}) require the full path to be defined in the formatter’s data.Credit Card Formatting Quirks:
CreditCardFormatter auto-detects card types but may misclassify some numbers. Validate with a dedicated library (e.g., bknock/luhn) if strict compliance is needed.SecureCreditCardFormatter for specific requirements.Unicode Handling:
TrimFormatter) may not handle Unicode whitespace correctly. Use mb_* functions explicitly if needed:
f::create()->trim()->format(' Hello ');
// May not trim all Unicode spaces. Use:
mb_trim($string, ' \t\n\r\0\x0B', 'UTF-8');
Modifier Order Matters:
PlaceholderFormatter templates affects the result:
// Different from:
{{value|uppercase|trim}} // Trims after uppercasing
{{value|trim|uppercase}} // Uppercases after trimming
Inspect Formatter Chains:
FormatterBuilder::getFormatters() to debug the chain:
$formatter = f::create()->trim()->uppercase();
dd($formatter->getFormatters()); // Array of applied formatters
PlaceholderFormatter Debugging:
$formatter = new PlaceholderFormatter([], [], true); // Third param: debug mode
echo $formatter->format('{{undefined}}'); // Outputs: {{undefined}}
PatternFormatter Validation:
preg_last_error() to catch regex issues:
$pattern = '/[invalid[regex/';
$formatter = f::create()->pattern($pattern);
try {
$formatter->format('test');
} catch (\Exception $e) {
dd(preg_last_error(), $pattern);
}
Performance Bottlenecks:
array_map():
$formatter = f::create()->trim();
$cleaned = array_map([$formatter, 'format'], $dirtyArray);
Custom Formatters:
Respect\StringFormatter\Formatter for domain-specific logic:
class CustomFormatter implements Formatter {
public function format(string $string): string {
// Custom logic
return strtoupper($string) . '!';
}
}
FormatterBuilder:
$builder = f::create();
$builder->addFormatter(new CustomFormatter());
Custom Modifiers:
Respect\StringFormatter\Modifier for PlaceholderFormatter:
class ReverseModifier implements Modifier {
public function modify(string $value):
How can I help you explore Laravel packages today?