phpmyadmin/motranslator
A PHP library for translating strings using Gettext MO files, with fast in-memory lookup, a Gettext-compatible API, and support for plural forms and contexts. No eval required.
.mo files are compiled artifacts, so each locale becomes a discrete, testable release candidate. That turns "launch locale #4 in Q3" from an engineering project into a content-and-ops task with a clear definition of done.eval(), context-aware lookups — are already solved. This lets us decide not to build a translation runtime and redirect that capacity to product surfaces.gettext extension as a hard dependency. That is a product decision when shipping to minimal containers, managed PHP runtimes, or environments where enabling an extension is a support ticket. It also sidesteps the long-standing MO-file-caching segfault, which unlocks "update translations without a restart" — a real operational capability for urgent copy fixes.ngettext/npgettext support means the roadmap can credibly target locales with 3–6 plural forms (pl, ru, ar) and can disambiguate short UI strings ("Post" as noun vs. verb). If those markets are in scope, a naive key→string JSON store with {count} interpolation is not equivalent, and this becomes a differentiator rather than a detail.setTranslation/setTranslations allows correcting copy, supporting white-label/tenant-specific terminology, or letting admins edit strings without a deploy. Whether we want that feature is a product call; this package makes it cheap.gettext performance. That is the input for deciding whether i18n is a meaningful line item in our memory/instance budget at scale.Consider it when:
.mo catalogs — from a TMS, an existing non-Laravel PHP app, or a translation vendor export.gettext extension being present or configurable, or you deploy to ephemeral/containerized infrastructure.pgettext) and true multi-form plurals are requirements, not edge cases.Look elsewhere when:
lang/JSON translator instead.__() out of the box.xgettext), no compilation (msgfmt), and no workflow.Executives: This is a small, free, already-battle-tested translation component (it powers phpMyAdmin) that lets us add languages as content rather than as engineering projects. It also removes a server-configuration dependency that has historically blocked deploys, and it lets us correct copy in production without a release. No license cost. Two flags for the decision: it carries a GPL-2.0 license that needs a one-time legal check against our distribution model, and its maintainer base is small, so we should treat it as a pinned dependency with a fallback plan.
Engineering: composer require phpmyadmin/motranslator, PHP 8.2+, no gettext extension required, no eval() for plural equations (it depends on symfony/expression-language). It offers a low-level MoParser plus CacheInterface for custom caching, an object-oriented Translator, and an optional global-function shim for drop-in Gettext compatibility. ApcuCache is the production path for shared caching, with TTL and reload-on-miss controls. What we still own: wiring xgettext/msgfmt into CI, cache sizing and monitoring, and a fork contingency. GPL-2.0 and a small upstream mean we should not expect feature requests to land on our schedule.
One-line recommendation: Adopt for the narrow job it does — reading MO catalogs without the native extension — contingent on legal clearing GPL-2.0 and on a deliberate decision that Gettext-compatible translator workflows are the right long-term bet.
How can I help you explore Laravel packages today?