spatie/string
Fluent string wrapper for PHP. Wrap a value with string() and chain helpers like between(), toUpper()/toLower(), etc. Supports offset access and mutation via array syntax. Great for readable, composable string transformations.
Installation:
composer require spatie/string
No configuration is required—just use the facade or helper directly.
First Use Case: Convert a string to snake_case, camelCase, or kebab-case instantly:
use Spatie\String\String;
$string = String::of('HelloWorld')->snake(); // "hello_world"
$string = String::of('hello_world')->camel(); // "helloWorld"
$string = String::of('Hello World')->kebab(); // "hello-world"
Facade Alternative:
Use the String facade for cleaner syntax:
use Spatie\String\Facades\String;
String::of('TestString')->studly(); // "TestString"
Model Attribute Formatting: Dynamically format database fields before/after saving:
protected $casts = [
'title' => 'string:kebab', // Store as kebab-case
];
public function setTitleAttribute($value) {
$this->attributes['title'] = String::of($value)->kebab();
}
Request Validation & Sanitization: Clean user input before processing:
$cleaned = String::of(request('user_input'))
->trim()
->ascii()
->lower();
URL & Route Generation: Convert strings to URL-friendly formats:
$slug = String::of('Product Name')->slug(); // "product-name"
route('products.show', ['slug' => $slug]);
Dynamic Query Building: Safely construct query conditions:
$searchTerm = String::of(request('q'))
->trim()
->lower();
$results = Model::where('name', 'like', "%{$searchTerm}%")->get();
Laravel Service Providers:
Bind the String class to the container for dependency injection:
$this->app->bind('string', function () {
return new String();
});
Blade Directives: Create custom Blade helpers:
Blade::directive('titleCase', function ($expression) {
return "<?php echo \\Spatie\\String\\String::of({$expression})->title(); ?>";
});
Usage:
<h1>{{ titleCase('hello world') }}</h1> <!-- "Hello World" -->
API Responses: Standardize response formatting:
return response()->json([
'data' => String::of($model->name)->title()
]);
Locale Sensitivity:
title() or slug() may behave unexpectedly with non-Latin characters.locale() to specify language rules:
String::of('café')->slug('fr'); // "cafe" (French rules)
Edge Cases in Trimming:
trim() removes all whitespace (including newlines/tabs).trim() + replaceMatches('/\s+/', ' ') for controlled trimming.Case Conversion Quirks:
studly() converts underscores to camelCase but preserves existing camelCase:
String::of('hello_world')->studly(); // "HelloWorld"
String::of('helloWorld')->studly(); // "HelloWorld" (unchanged)
Slug Collisions:
slug() may generate duplicates (e.g., "hello-world" and "hello-world-1").spatie/laravel-sluggable.Inspect Intermediate Steps: Chain methods and log results to debug:
$steps = [
String::of(' Hello_World ')->trim(),
String::of('Hello_World')->ascii(),
String::of('Hello_World')->slug(),
];
Check for Hidden Characters:
Use String::of($str)->dump() to reveal non-printable characters (e.g., \u200B zero-width spaces).
Custom Rules:
Extend the String class to add domain-specific methods:
class CustomString extends String {
public function toAcronym(): string {
return strtoupper(substr($this->value, 0, 3));
}
}
Override Default Behavior:
Replace the slug() method in a service provider:
String::macro('slug', function () {
return parent::slug()->replace(['&', '?'], '');
});
Performance:
String instances for repeated operations:
$string = String::of($input);
$slug = $string->slug();
$title = $string->title();
String object in loops.Testing:
Mock the String facade for isolated tests:
$this->mock(Spatie\String\Facades\String::class)
->shouldReceive('of')
->andReturn(String::of('Mocked'));
How can I help you explore Laravel packages today?