Str::studly
Converts a delimited or spaced string to StudlyCase for use as a class name.
Str::studly(string $value): string- Added in Laravel 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$$value | string | The string to convert. Hyphens and underscores are treated as word separators along with any whitespace run. |
Return value
stringThe value with hyphens, underscores and whitespace removed and the first letter of each resulting word uppercased.
Changelog
- PHP 11.xStr::pascal was added as an alias of this method.
- PHP 12.xWord splitting moved from explode(' ') to mb_split('\s+'), so runs of whitespace no longer leave empty segments and multibyte first letters such as ü are now uppercased.
Str::studly turns foo_bar, foo-bar and foo bar into FooBar. It splits on hyphens, underscores and whitespace, uppercases each word's first character, and concatenates. Str::pascal is an alias for the same thing.
Its home is code generation and convention-based resolution: table name to model class, event name to listener class, command name to handler. Anywhere Laravel infers a class name from a string, this is the method doing it.
What trips people up
- It never lowercases anything. Only the first letter of each word is touched, so
HTTP_responsebecomesHTTPResponseandfooBARbecomesFooBAR. That is usually desirable for acronyms and surprising for everything else. - It is not the inverse of
Str::snake. Runningstudly()thensnake()onHTTP_responsegivesh_t_t_p_response. - It does not singularise.
Str::studly('blog_posts')isBlogPosts; callStr::singularfirst if you want a model name. - Digits, dots and other punctuation are left in place, so the output is not guaranteed to be a valid PHP identifier. Validate before using it to build a class name from untrusted input.
- Results are memoised in a static cache keyed by input, which never expires.
Example
When to use it
- Resolve a class name from a table or route segment, as in Str::studly(Str::singular($table)).
- Build a job or listener class name from a kebab-case queue or event identifier.
- Generate a Pascal-case DTO property name from an external system's snake_case field.
Frequently asked questions
What is the difference between Str::studly and Str::camel?
Both remove the separators, but studly uppercases the first letter of every word while camel leaves the first word lowercase. Use studly for class names and camel for variables, properties and methods.
Is Str::pascal the same as Str::studly?
Yes. Str::pascal was added in Laravel 11 and simply calls Str::studly, so the two are interchangeable and produce identical output.
Why does Str::studly leave my acronym in capitals?
Because it only uppercases the first character of each word and never lowercases anything else, so 'HTTP_response' becomes 'HTTPResponse'. Lowercase the input first if you want 'HttpResponse'.
More examples
Studly next to its neighbours
Prints BlogPost, blogPost and "Blog Post" — studly for class names, camel for variables and methods, headline for human-readable labels. The fourth line gives SendWelcomeEmailJob. The final dump is "ÜberTest", which only works because word splitting and ucfirst are multibyte aware from Laravel 12.
<?php
use Illuminate\Support\Str;
$value = 'blog_post';
echo 'studly: ', Str::studly($value), PHP_EOL;
echo 'camel: ', Str::camel($value), PHP_EOL;
echo 'headline: ', Str::headline($value), PHP_EOL;
// Class-name generation from a kebab-case identifier.
echo Str::studly('send-welcome-email').'Job', PHP_EOL;
// Multibyte first letters are uppercased correctly.
var_dump(Str::studly('über_test'));Convention-based class resolution
The singular() call before studly() is what turns 'stripe_payouts' into 'StripePayout' rather than 'StripePayouts'. The class_exists guard matters because $source may come from a config file or CLI argument, and studly() will happily produce a syntactically invalid class name from unexpected input. This needs a booted container, so it is displayed rather than executed.
<?php
namespace App\Support;
use Illuminate\Support\Str;
use InvalidArgumentException;
class ImporterFactory
{
public function make(string $source): object
{
// "stripe_payouts" -> App\Importers\StripePayoutImporter
$class = 'App\\Importers\\'.Str::studly(Str::singular($source)).'Importer';
if (! class_exists($class)) {
throw new InvalidArgumentException("No importer for [{$source}].");
}
return app($class);
}
}
Discussion