symfony/polyfill-ctype
Provides ctype_* functions (ctype_alpha, ctype_digit, ctype_alnum, and more) for PHP installations missing the ctype extension, ensuring portable character-type checks across environments. Part of the Symfony Polyfill family.
ctype_* question — "do we hand-roll an alphabet/digit/numeric guard, or take a dependency?" — is already answered. This is a 4,000-star, MIT-licensed, Symfony-maintained shim with zero configuration. Building in-house is not rational; the only real decision is whether to declare it explicitly or inherit it transitively.ctype is present on every target host. Adopting (or pinning) this converts that from an assumed property of the image into a declared line in composer.lock — a durable reduction in "works on my machine" surface area.mb_* / Str initiative and this package explicitly does not solve it. If no, this package lets you write ctype_alnum() without a function_exists guard ever again.ctype_*, declaring this dependency is a small, correct product decision that protects downstream consumers who prune dependencies.ctype_* in a hot loop — treat as a code-review concern rather than a reason to adopt or reject.Consider it when:
ctype extension on all of them (customer-managed deployments, BYO-infrastructure, shared hosting, minimal container images).ctype_* directly in validation rules, middleware, or slug pipelines — and you want to drop function_exists() guards permanently.ctype_* deprecation noise; bumping the pin to ≥1.34.0 is a legitimate reason to touch it.Look elsewhere when:
composer.lock. Run composer show symfony/polyfill-ctype and composer why symfony/polyfill-ctype first. In most Laravel apps this arrives via symfony/validator or symfony/http-foundation. The work is "confirm and pin," not "adopt."ctype_alnum('café') returns false with or without the polyfill. Reach for Str::isAlphanumeric(), mb_*, or a regex instead. Adopting this package will not fix international input, and positioning it as a fix is the single most common mistake.ctype_* sits in a hot path — bulk CSV ingestion, log parsing, rate limiters. Enable the native extension on hosts you control instead; it's on by default on Forge, Vapor, and standard Docker PHP images.To executives (30 seconds): This is a small, free, MIT-licensed utility maintained by Symfony that removes a class of "works in staging, fails on the customer's server" bugs from our string validation. It is almost certainly already installed as a side effect of Laravel's dependency tree. The action is to make it explicit and keep it version-pinned — roughly an hour of work, no code changes, no licensing or procurement review. Frame it as portability insurance, not a feature: it doesn't ship anything users see, it eliminates an environmental assumption from our support matrix. Do not oversell it — it does not solve multilingual input, and it does not make anything faster.
To engineering (the honest version):
composer require, or just an explicit composer.json entry if it's already transitive. No service provider, no config, no migrations, no test rewrites.ctype_* functions, registered via Composer files autoload, that define themselves only when the native extension is absent. On healthy hosts it is silently dormant — a no-op.E_DEPRECATED for non-string arguments — fix the call sites with explicit casts rather than suppressing the error class globally, since other Symfony components emit useful deprecations we want to keep.ctype_* deprecation warnings in error tracking after the 8.1+ migration; a clean composer why showing an intentional parent.How can I help you explore Laravel packages today?