How to Translate PHP Files and Keep the Code Working
In PHP, strings live in code. The job is separating what a user reads from what the interpreter runs, and most projects have never done it as well.

Quick answer — PHP has no single localization standard, so strings live in arrays, gettext calls, templates or hard-coded in the middle of logic. The first task is usually extraction, not translation.
Three conventions, often in one codebase
gettext. __() or _() wrapping strings, catalogues in .po files. The most portable option and the one with the best tooling. Array-based language files. $lang['welcome'] = 'Welcome'; returned from a per-language file. Simple, common in older frameworks, and entirely convention-based.
Framework helpers. Laravel's __('messages.welcome'), Symfony's translator service. Structured, and specific to that framework.
Legacy codebases frequently contain all three plus a fourth category: strings written directly into the middle of a function.
Extraction is the actual project
A string sitting inside echo "Order confirmed"; cannot be translated by any tool, because nothing marks it as text rather than code. It has to be pulled out into a catalogue first.
That is a refactor, and it is the honest scope of most PHP localization work. Estimating the translation without estimating the extraction is why these projects overrun.
What must never be translated
Variable names. Array keys used as lookups. SQL. Function calls. HTML attribute names. Anything inside a string that is a format specifier — %s, %d, {$var}, :placeholder.
Interpolated variables are the specific PHP hazard: "Hello $name" puts a variable inside a translatable string, and a translation that renames or reorders it produces either a literal $name on screen or a notice in the log.
Templates versus logic
Text inside a Blade, Twig or Smarty template is usually clean and easy to extract. Text inside a controller or a model is where the mess is.
Splitting the audit that way gives you a realistic sequence: templates first for quick coverage, then the logic layer.
Escaping and output context
The same string may be echoed into HTML, a JSON response and an email. Each needs different escaping, and a translation containing an ampersand or a quote behaves differently in each.
Escape at output, never in the catalogue. A catalogue containing HTML entities is a catalogue that renders wrongly somewhere.
Making it repeatable
Once strings are extracted, the ongoing job is small: each release adds a handful.
translation memory returns everything unchanged so only new strings cost anything, and quality control verifies placeholders survived.
Supported patterns are on the PHP translation integration page.
Pluralisation without a framework
Raw PHP has ngettext if gettext is available and nothing at all otherwise.
Array-based language files typically have no plural concept, so developers write if ($n == 1) inline and the string becomes untranslatable for languages with more than two forms.
If the codebase serves Polish, Russian or Arabic, this has to be solved before translating rather than after. Retrofitting plural support means touching every call site.
Date and number formatting
date() produces English month names regardless of locale. IntlDateFormatter and NumberFormatter exist and are the right answer, and a site that translates its strings while still printing "March" reads as half-finished.
Where to start
Grep for echo and print with a quoted string literal. The size of that result is the real size of the project, and it is usually larger than anyone expects.
FAQ
How are strings translated in PHP? Through gettext calls, array-based language files, or a framework's translator helper. Legacy codebases often contain all three plus strings written directly into the middle of functions.
What is the hardest part of translating a PHP project? Extraction. A string inside echo cannot be translated by any tool because nothing marks it as text, so it has to be refactored into a catalogue first. That refactor is the real scope of most PHP localization work.
What must never be translated in PHP? Variable names, array lookup keys, SQL, function calls and format specifiers like %s or :placeholder. Interpolated variables are the specific hazard, since renaming one prints the literal variable or throws a notice.
Should HTML escaping happen in the catalogue? No, escape at output. The same string may be echoed into HTML, JSON and email, each needing different escaping, so a catalogue containing HTML entities renders wrongly in at least one of them.
Our blog
Lastest blog posts
Tool and strategies modern teams need to help their companies grow.

Automotive
Automotive Brochure Localization by Market
A car brochure is a spec grid, a legal footer and a photo library, all market-specific. What actually has to change, and why the layout decides the schedule.

Automotive
Automotive Campaign Localization Across Markets
Campaigns run through national companies and dealer networks, so one master becomes hundreds of files. Where the offer text and the disclaimers actually break.

Automotive
Car Service Manual Translation for Technicians
A workshop manual is read mid-repair by someone with the car on a lift. What that demands of procedures, torque figures and fault codes, in every language.