joachim-n/case-converter
A Laravel/PHP package for converting strings between naming conventions such as camelCase, snake_case, kebab-case and PascalCase, making it easy to transform identifiers and text consistently across your application.
composer require joachim-n/case-converter
vendor/joachim-n/case-converter/src), so open the main class and confirm the exact public method names, accepted case identifiers, and whether conversion is static or instance-based before building around it.php artisan tinker
use JoachimN\CaseConverter\CaseConverter; // confirm namespace in source
CaseConverter::toSnakeCase('HelloWorld'); // hello_world
CaseConverter::toCamelCase('hello world'); // helloWorld
CaseConverter::toKebabCase('HelloWorld'); // hello-world
If the method names differ, wrap them immediately in your own helper (see below) so the rest of the codebase never depends on the vendor API.
Wrap it once. Create a small application service so you can swap the library later without touching call sites:
namespace App\Support;
use JoachimN\CaseConverter\CaseConverter;
final class Str
{
public static function snake(string $value): string
{
return CaseConverter::toSnakeCase($value);
}
public static function camel(string $value): string
{
return CaseConverter::toCamelCase($value);
}
}
Normalise external JSON keys in an HTTP client or middleware:
$payload = collect($response->json())
->mapWithKeys(fn ($v, $k) => [Str::snake($k) => $v])
->all();
UserData::from($payload);
DTO / model hydration. When accepting camelCase JSON but storing snake_case columns, convert at the boundary, not inside models:
foreach ($request->validated() as $key => $value) {
$attributes[Str::snake($key)] = $value;
}
Code generation and Artisan commands. Case conversion is most valuable for generators: turning a table name (order_items) into a model (OrderItem), a route name (order-items.index), a policy, a factory, etc.
$model = Str::pascal(Str::singular($table)); // OrderItem
Route and view naming conventions. Keep resource routes and view paths consistent by deriving them from a single resource name rather than hand-typing variants.
Form Request / middleware key canonicalisation. If you accept both camelCase and snake_case from different clients, normalise incoming keys once in middleware and keep your validation rules in one convention.
Test with a data provider. Case converters fail on edge inputs; lock behaviour in:
#[DataProvider('cases')]
public function test_conversion(string $in, string $out): void
{
$this->assertSame($out, Str::snake($in));
}
public static function cases(): array
{
return [
['HelloWorld', 'hello_world'],
['hello world', 'hello_world'],
['hello-world', 'hello_world'],
['HTTPResponse', 'http_response'], // verify actual behaviour
['foo2Bar', 'foo2_bar'],
];
}
HTTPResponse, userID, v2Endpoint, or iPhone may not round-trip the way you expect. Assert your specific cases in tests rather than assuming.helloworld) cannot be reliably split. Prefer converting from a known convention (e.g. you know input is camelCase) rather than a magic auto-detect.user__id, user-id → user_id) are common when the same value passes through multiple layers. Normalise at exactly one boundary.mb_* functions. If you handle non-ASCII names, add tests; regex-based converters sometimes break on accented characters.composer.json, keep your wrapper thin, and be prepared to replace it. Because it is small, forking or reimplementing a few regexes is realistic if it is abandoned.vendor/; subclass or wrap the converter in your own class if you need acronym dictionaries or custom handling. If you fork, remember the GPL-3.0 obligations carry over.bin2hex) to catch trailing whitespace, non-breaking spaces, or CRLF introduced upstream — the converter itself is rarely the culprit.How can I help you explore Laravel packages today?