msales/string-mapper-bundle
A Symfony bundle from Msales for mapping strings to objects or values, providing a configurable way to convert raw string data into typed structures. Useful for deserialization and transformation tasks in PHP applications.
Add the package from the repository directly, since it is not a first-class Laravel citizen:
composer require msales/string-mapper-bundle
It is a Symfony bundle, so there is no extra.laravel auto-discovery. Open vendor/msales/string-mapper-bundle/src/ first — that is where the mapper interface and concrete implementation live. Everything in DependencyInjection/ and Resources/config/ is Symfony glue you will mostly bypass; the core mapping classes are plain PHP and can be wired into Laravel's container without the bundle machinery.
A minimal first use case: a StringMapper service that takes a raw string (e.g., a CSV import value like "UK", "Great Britain", "united kingdom") and returns a canonical value ("GB"). Register it in App\Providers\AppServiceProvider:
$this->app->singleton(\Msales\StringMapperBundle\Mapper\StringMapper::class, function ($app) {
return new \Msales\StringMapperBundle\Mapper\StringMapper(config('string-mapper.map'));
});
Then resolve it anywhere via app(StringMapper::class) or a thin facade. For a one-off, just instantiate it in a command or job — the Symfony layer adds nothing for a Laravel app.
Config-driven mapping. Keep the map in config/string-mapper.php returning a flat associative array (['uk' => 'GB', 'great britain' => 'GB', ...]). This mirrors the bundle's Symfony/YAML config but lets you use Laravel's config() and env overrides. Load it once into a singleton — do not rebuild the map per call.
Normalization at the boundary. The highest-value use is at ingestion: form requests, CSV imports, API payloads. Build a small NormalizesStrings trait for FormRequests that runs the mapper in prepareForValidation() so downstream code only ever sees canonical values. This keeps mapping concerns out of controllers and models.
Pipeline / fallback chains. For fuzzy inputs, wrap the mapper with a chain: exact map → strtolower/trim normalized map → optional Str::slug() key. Return the original (or throw a domain exception) when nothing matches, and make that behavior configurable — silent no-match is a classic source of bad data.
Integration with enums and casts. Map incoming strings to PHP 8.1 backed enums or model casts in one place. For example, a Status cast that resolves display strings ("In Progress") via the mapper to enum cases. The mapper stays dumb; the cast owns the business rule.
Testing. Because the mapper is deterministic and dependency-free, test it with a simple PHPUnit data provider of [input, expected] pairs. Add one integration test that resolves the mapper from the container to catch config-wiring regressions.
composer.json for PHP/Symfony constraints — it predates PHP 8 and may not install cleanly. The mapping logic is trivial (array lookup + normalization), so forking or reimplementing in ~50 lines is usually safer than pulling this in.Extension/Configuration classes will not be invoked — you skip them entirely.config() array.mb_* handling for accented input is a common gap in 2017-era code.null, or throw. Document it, because silent pass-through makes bad data look valid.app/Support/ and drop the dependency.How can I help you explore Laravel packages today?