laravel-str maintained by coyote6
Laravel Str
Extends Laravel's Str facade with a handful of extra macros: case converters (dot, pureKebab, pureSnake, strictKebab, strictSnake) and a set of is* checks for detecting what case a string is already in.
Requirements
- PHP >= 7.0
illuminate/support^5.4 - ^13.0
CI actively tests PHP 8.3 and 8.4 (the range pestphp/pest itself supports) against both the lowest and latest resolvable dependency versions. Nothing in this package uses syntax newer than PHP 7.0, so earlier PHP/Laravel combinations are expected to work but aren't run in CI.
Installation
composer require coyote6/laravel-str
The package registers Coyote6\LaravelStr\Providers\StrServiceProvider automatically via Laravel's package discovery — no manual provider registration needed.
Available Methods
- Str::dot()
- Str::isCamel()
- Str::isDot()
- Str::isKebab()
- Str::isLower()
- Str::isPureKebab()
- Str::isPureSnake()
- Str::isSlug()
- Str::isSnake()
- Str::isStrictKebab()
- Str::isStrictSnake()
- Str::isStudly()
- Str::isTitle()
- Str::isUpper()
- Str::pureKebab()
- Str::pureSnake()
- Str::strictKebab()
- Str::strictSnake()
Methods
Str::dot()
The dot method converts the given string to dot.case. Any run of characters that isn't a letter or number (spaces, punctuation, dashes, underscores, etc.) is collapsed into a single dot, and any leading or trailing dots are trimmed.
use Illuminate\Support\Str;
$converted = Str::dot('User - View All');
// user.view.all
This is commonly useful for turning human-readable permission or ability names into machine keys:
Str::dot('Posts - Create Draft');
// posts.create.draft
Str::isCamel()
The isCamel method determines if the given string is already in camelCase.
use Illuminate\Support\Str;
Str::isCamel('aCamelLikeString');
// true
Str::isCamel('A Camel-like String');
// false
Str::isDot()
The isDot method determines if the given string is already in dot.case. It checks the string against the output of Str::dot().
use Illuminate\Support\Str;
Str::isDot('user.view.all');
// true
Str::isDot('User - View All');
// false
Str::isKebab()
The isKebab method determines if the given string is already in kebab-case.
use Illuminate\Support\Str;
Str::isKebab('a-kebab-like-string');
// true
Str::isKebab('A Kebab-like String');
// false
Note:
Str::kebab()only inserts a dash at case-boundary transitions — it never validates or collapses the separators already in the string. That meansStr::isKebab('a_kebab_like_string')andStr::isKebab('a--kebab--like--string')both returntrue, even though neither looks like clean kebab-case. If you do not want to allow underscores in the output and want them to be converted as a separator, useStr::isPureKebab(). If you want to require exactly one canonical spelling, useStr::isStrictKebab().
Str::isLower()
The isLower method determines if the given string is entirely lowercase.
use Illuminate\Support\Str;
Str::isLower('a lowercased string');
// true
Str::isLower('A Lowercased String');
// false
Str::isPureKebab()
The isPureKebab method determines if the given string is already in kebab-case, using Str::pureKebab() instead of Str::kebab(). Unlike Str::isKebab(), it rejects the wrong separator character (e.g. underscores). Repeated dashes are accepted by default; pass a $consecutiveDashes limit to cap how many are allowed.
use Illuminate\Support\Str;
Str::isPureKebab('a-kebab-like-string');
// true
Str::isPureKebab('a_kebab_like_string');
// false
Str::isPureKebab('a--kebab--like--string');
// true - repeated dashes are fine by default
Str::isPureKebab('a--kebab--like--string', 1);
// false - exceeds the 1-consecutive-dash limit
Str::isPureSnake()
The isPureSnake method determines if the given string is already in snake_case, using Str::pureSnake() instead of Str::snake(). Unlike Str::isSnake(), it rejects the wrong separator character (e.g. dashes). Repeated underscores are accepted by default; pass a $consecutiveUnderscores limit to cap how many are allowed.
use Illuminate\Support\Str;
Str::isPureSnake('a_snakelike_string');
// true
Str::isPureSnake('a-snakelike-string');
// false
Str::isPureSnake('a__snakelike__string');
// true - repeated underscores are fine by default
Str::isPureSnake('a__snakelike__string', 1);
// false - exceeds the 1-consecutive-underscore limit
Str::isSlug()
The isSlug method determines if the given string is already a valid slug. It mirrors Str::slug()'s full signature — $charReplacement (separator), $language, and $dictionary — so a check can be run under the same options you'd slugify with.
use Illuminate\Support\Str;
Str::isSlug('a-url-slug');
// true
Str::isSlug('A Url Slug');
// false
Str::isSlug('a_url_slug', '_');
// true
$language can meaningfully flip the result, since it controls whether accented letters get transliterated to ASCII before the slug check runs:
Str::isSlug('café');
// false - 'en' (the default) transliterates é to e, so 'café' no longer matches itself
Str::isSlug('café', '-', null);
// true - transliteration disabled, so the accented letter passes through unchanged
Note:
$dictionaryis accepted and forwarded for signature completeness, but it can't change the boolean result in practice — its keys (like@) never surviveStr::slug()either way, whether expanded via the dictionary or simply stripped by an empty one, so no input is a valid slug under one dictionary but not another.
Str::isSnake()
The isSnake method determines if the given string is already in snake_case.
use Illuminate\Support\Str;
Str::isSnake('a_snakelike_string');
// true
Str::isSnake('A Snake-like String');
// false
Note:
Str::snake()only inserts an underscore at case-boundary transitions — it never validates or collapses the separators already in the string. That meansStr::isSnake('a-snakelike-string')andStr::isSnake('a__snakelike__string')both returntrue, even though neither looks like clean snake_case. If you do not want to allow dashes in the output and want them to be converted as a separator, useStr::isPureSnake(). If you want to require exactly one canonical spelling, useStr::isStrictSnake().
isSnake also accepts a second $delimiter argument, mirroring Str::snake()'s own $delimiter argument:
Str::isSnake('a-snake-case', '-');
// true
Note: unlike
$languageonisSlug,$delimiteris accepted for signature completeness but can't change the boolean result —Str::snake()only ever inserts a delimiter at a case boundary, so a string with no case boundary at all is a fixed point for every delimiter, and a string that does have a case boundary can never match itself for any delimiter (the result is always lowercased and always has something inserted). It's forwarded purely so the two signatures stay in sync.
Str::isStrictKebab()
The isStrictKebab method determines if the given string is already in kebab-case, using Str::strictKebab() instead of Str::kebab(). Unlike Str::isKebab() and Str::isPureKebab(), it always collapses repeated separators, so there's exactly one valid spelling for a given name — useful when generating a canonical machine key.
use Illuminate\Support\Str;
Str::isStrictKebab('a-kebab-like-string');
// true
Str::isStrictKebab('a--kebab--like--string');
// false
Str::isStrictSnake()
The isStrictSnake method determines if the given string is already in snake_case, using Str::strictSnake() instead of Str::snake(). Unlike Str::isSnake() and Str::isPureSnake(), it always collapses repeated separators, so there's exactly one valid spelling for a given name — useful when generating a canonical machine key.
use Illuminate\Support\Str;
Str::isStrictSnake('a_snakelike_string');
// true
Str::isStrictSnake('a__snakelike__string');
// false
Str::isStudly()
The isStudly method determines if the given string is already in StudlyCase.
use Illuminate\Support\Str;
Str::isStudly('AStudlyLikeString');
// true
Str::isStudly('A Studly-like String');
// false
isStudly also accepts a second $normalize argument, mirroring Str::studly()'s own $normalize argument. When enabled, a standalone all-caps "word" (an acronym) is lowercased before comparing, so 'CBOR' no longer matches itself — only its normalized form, 'Cbor', does:
Str::isStudly('CBOR');
// true - acronyms are left alone by default
Str::isStudly('CBOR', true);
// false - normalize would rewrite it to 'Cbor' first
Str::isStudly('Cbor', true);
// true - already in the normalized shape
Str::isTitle()
The isTitle method determines if the given string is already in Title Case.
use Illuminate\Support\Str;
Str::isTitle('A Title For Your Article');
// true
Str::isTitle('A-Title-for-Your-Article');
// false
Str::isUpper()
The isUpper method determines if the given string is entirely uppercase.
use Illuminate\Support\Str;
Str::isUpper('AN UPPERCASED STRING');
// true
Str::isUpper('An uppercased string');
// false
Str::pureKebab()
The pureKebab method converts the given string to kebab-case, accepting dashes and underscores as valid input separators. Unlike Str::kebab(), it converts underscores (not just case-boundary transitions), and it groups consecutive uppercase letters (acronyms) into a single word instead of splitting every capital letter — see laravel/framework#47005.
Every individual non-alphanumeric character becomes its own dash, so repeated separators are preserved by default:
use Illuminate\Support\Str;
Str::pureKebab('my_example_text');
// my-example-text
Str::pureKebab('my_exampleCombined_text');
// my-example-combined-text
Str::pureKebab('A - Kebab');
// a---kebab - each of the 3 separator characters (space, dash, space) converts on its own
Str::kebab('my_example_text'); // for comparison
// my_example_text (Str::kebab() leaves this untouched)
Pass $consecutiveDashes to cap how many consecutive dashes are allowed in the result (default 0 is unlimited):
Str::pureKebab('A - Kebab', 2);
// a--kebab
If you want exactly one dash between words regardless of input, use Str::strictKebab() instead.
Str::pureSnake()
The pureSnake method converts the given string to snake_case, accepting underscores and dashes as valid input separators. Unlike Str::snake(), it converts dashes (not just case-boundary transitions), and it groups consecutive uppercase letters (acronyms) into a single word instead of splitting every capital letter — see laravel/framework#47005.
Every individual non-alphanumeric character becomes its own underscore, so repeated separators are preserved by default:
use Illuminate\Support\Str;
Str::pureSnake('my-example-text');
// my_example_text
Str::pureSnake('LARAVELFramework');
// laravel_framework
Str::pureSnake('a - snake');
// a___snake - each of the 3 separator characters (space, dash, space) converts on its own
Str::snake('LARAVELFramework'); // for comparison
// l_a_r_a_v_e_l_framework (Str::snake() splits every capital letter)
Pass $consecutiveUnderscores to cap how many consecutive underscores are allowed in the result (default 0 is unlimited):
Str::pureSnake('a - snake', 2);
// a__snake
If you want exactly one underscore between words regardless of input, use Str::strictSnake() instead.
Str::strictKebab()
The strictKebab method converts the given string to kebab-case with exactly one canonical spelling for a given name — it's a thin wrapper around Str::pureKebab() with $consecutiveDashes locked to 1, so every run of separator characters always collapses down to a single dash. Useful for generating machine keys, where 'a-kebab' and 'a--kebab' should resolve to the same value.
use Illuminate\Support\Str;
Str::strictKebab('my_example_text');
// my-example-text
Str::strictKebab('A - Kebab');
// a-kebab
Str::pureKebab('A - Kebab'); // for comparison
// a---kebab (pureKebab() preserves each separator character)
Str::strictSnake()
The strictSnake method converts the given string to snake_case with exactly one canonical spelling for a given name — it's a thin wrapper around Str::pureSnake() with $consecutiveUnderscores locked to 1, so every run of separator characters always collapses down to a single underscore. Useful for generating machine keys, where 'a_snake' and 'a__snake' should resolve to the same value.
use Illuminate\Support\Str;
Str::strictSnake('my-example-text');
// my_example_text
Str::strictSnake('a - snake');
// a_snake
Str::pureSnake('a - snake'); // for comparison
// a___snake (pureSnake() preserves each separator character)