Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Case Helper Laravel Package

nabil1337/case-helper

case-helper is a Laravel/PHP utility package for converting strings between common case formats like camelCase, snake_case, kebab-case, and StudlyCase. It provides simple, reusable helpers to keep naming consistent across your application.

Deep Wiki
Context7

Getting Started

nabil1337/case-helper is a small, static utility class for converting strings between the seven common case conventions: camelCase, PascalCase, kebab-case, snake_case, SCREAMING_SNAKE_CASE, Train-Case, and raw spaced "string case."

Minimal steps:

  1. Install: composer require nabil1337/case-helper
  2. There is no Laravel service provider and no facade — it predates package auto-discovery (last release Dec 2014), and it's a plain PHP class. Just use it directly.
  3. Open vendor/nabil1337/case-helper/src/ first — it's a single class file. Read the public static method names before writing anything; the exact verb naming (toCamel(), camelCase(), convert()) is the one thing this package doesn't document well.
  4. First use case: take a human-entered label ("Blog Post Category") and produce the three or four forms you actually need at once — table name, route slug, model name, and enum key.
use Nabil1337\CaseHelper\CaseHelper; // confirm namespace from the src file

CaseHelper::snakeCase('Blog Post Category');      // blog_post_category
CaseHelper::kebabCase('Blog Post Category');      // blog-post-category
CaseHelper::pascalCase('blog post category');     // BlogPostCategory
CaseHelper::screamingSnakeCase('Blog Post');      // BLOG_POST
CaseHelper::trainCase('blog post');               // Blog-Post

If the static API is awkward for Laravel, wrap it once (see below) and never call the class directly again — that limits your exposure when the unmaintained package breaks.

Implementation Patterns

Wrap it behind a Laravel helper or Str macro. The package is a pure string transformer; the value in a Laravel app is in normalizing it into the framework's idioms. A macro makes it discoverable and swappable:

// AppServiceProvider::boot()
Str::macro('train', fn (string $s) => CaseHelper::trainCase($s));
Str::macro('screamingSnake', fn (string $s) => CaseHelper::screamingSnakeCase($s));

Then call sites read like native Laravel: Str::train($label).

Model-to-table / class-name conventions. Anywhere you generate artifacts from user input — migrations, models, enum keys, route names — compute all forms in one pass instead of chaining ad-hoc str_replace calls:

$forms = [
    'table'  => CaseHelper::snakeCase($label),
    'slug'   => CaseHelper::kebabCase($label),
    'class'  => CaseHelper::pascalCase($label),
    'enum'   => CaseHelper::screamingSnakeCase($label),
];

Form request normalization. Convert inbound JSON keys or form field labels to a canonical casing in prepareForValidation() or a middleware, so controllers always receive camelCase:

protected function prepareForValidation()
{
    $this->merge(collect($this->all())
        ->mapWithKeys(fn ($v, $k) => [CaseHelper::camelCase($k) => $v])
        ->all());
}

API resources / response shaping. Use kebab or snake case on the way out when integrating a third-party API that demands a specific convention, rather than hand-writing key maps in every resource.

Blade + config. Register a Blade directive (@train($label)) only if designers/templates genuinely need it; otherwise keep it server-side. For a repeated convention (e.g. "all slugs are kebab"), codify it in a small NamingService and inject that, so the package is one implementation detail rather than a hard dependency sprinkled across views.

Pair with Str::slug() for URLs. kebabCase() handles casing, not accent stripping or URL safety — run the result through Laravel's Str::slug() before using it in routes.

Gotchas and Tips

  • Overlap with native Laravel. Str::camel, Str::snake, Str::kebab, and Str::studly all exist in modern Laravel. The only two things this package adds are Train-Case and SCREAMING_SNAKE_CASE. If those are all you need, a 3-line macro on top of Str lets you drop the dependency entirely — strongly consider that first.
  • Unmaintained since 2014. No updates for PHP 8.x, no typed signatures, no tests you can rely on. Audit the source before shipping; it may use deprecated constructs or loose composer.json constraints that fail composer install on current PHP. Pin the version and expect to replace it within a year.
  • No service provider / facade / auto-discovery. Don't add it to config/app.php providers — there's nothing to register. If you see docs implying otherwise, they're generic boilerplate.
  • Acronym and number handling is the classic failure mode. Check what it does with HTMLParser, OAuth2Token, userID, and strings with consecutive capitals or digits before relying on round-tripping. Most 2014-era converters mangle acronyms and produce h_t_m_l_parser.
  • Round-tripping is lossy. camelCase → snake_case → camelCase is not guaranteed to return the original when the input had unusual capitalization. Treat conversions as one-directional and never use this for "decode what the user meant."
  • Multibyte / Unicode. Expect ASCII-only behavior. Accented or non-Latin input typically falls through unchanged or gets split incorrectly. Normalize with Str::ascii() or iconv first if your labels are internationalized.
  • Empty and numeric input. CaseHelper::camelCase('') and inputs starting with digits produce edge cases (leading underscores, empty strings). Guard with filled() / a null-coalescing wrapper at call sites.
  • Debugging tip: because everything is static and pure, write a quick Pest/PHPUnit data provider enumerating your seven target forms for a handful of representative inputs. That test becomes your contract and your migration checklist for when you swap in Str macros or spatie/string.
  • Extension point: there isn't one — no pluggable strategy, no config, no interfaces. If you need custom behavior (e.g. preserving acronyms), you'll be forking the class. Given the size, forking into app/Support/ is often cleaner than depending on an abandoned package.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package