# How to Translate PHP Files and Keep the Code Working | Vitra.ai

> 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.

**Canonical URL**: https://www.vitra.ai/general/translate-php-files
**Source**: This is the Markdown rendering of https://www.vitra.ai/general/translate-php-files, generated at build time from that page.

---

4 min read

# 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.

[Samhitha J Bhatt](https://www.vitra.ai/author/samhitha)
Senior Product Manager , Vitra.ai
Updated Aug 17, 2026

![How to Translate PHP Files and Keep the Code Working](https://www.vitra.ai/static/images/blog/translate-php-files.jpg)

Table of contents

[Three conventions, often in one codebase](#three-conventions-often-in-one-codebase)

[Extraction is the actual project](#extraction-is-the-actual-project)

[What must never be translated](#what-must-never-be-translated)

[Templates versus logic](#templates-versus-logic)

[Escaping and output context](#escaping-and-output-context)

[Making it repeatable](#making-it-repeatable)

[Pluralisation without a framework](#pluralisation-without-a-framework)

[Date and number formatting](#date-and-number-formatting)

[Where to start](#where-to-start)

[FAQ](#faq)

Contributors

[Samhitha J Bhatt](https://www.vitra.ai/author/samhitha)
Senior Product Manager

Subscribe to our newsletter

Subscribe

> **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](https://www.vitra.ai/features/translation-memory) returns everything unchanged so only new strings cost anything, and [quality control](https://www.vitra.ai/features/quality-control) verifies placeholders survived.

Supported patterns are on the [PHP translation integration](https://www.vitra.ai/integration/php-translation) 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](https://www.vitra.ai/automotive/automotive-brochure-localization)
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.

[Samhitha J Bhatt](https://www.vitra.ai/author/samhitha)
Aug 18, 2026

Automotive

[Automotive Campaign Localization Across Markets](https://www.vitra.ai/automotive/automotive-campaign-localization)
Campaigns run through national companies and dealer networks, so one master becomes hundreds of files. Where the offer text and the disclaimers actually break.

[Samhitha J Bhatt](https://www.vitra.ai/author/samhitha)
Aug 18, 2026

Automotive

[Car Service Manual Translation for Technicians](https://www.vitra.ai/automotive/automotive-service-manual-translation)
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.

[Samhitha J Bhatt](https://www.vitra.ai/author/samhitha)
Aug 18, 2026

[View all posts](https://www.vitra.ai/blog/page/1)

---

## Structured data

```json
{
  "@context": "https://schema.org",
  "@type": "Article",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://www.vitra.ai/general/translate-php-files"
  },
  "headline": "How to Translate PHP Files and Keep the Code Working",
  "image": [
    {
      "@type": "ImageObject",
      "url": "https://www.vitra.ai/static/images/blog/translate-php-files.jpg"
    }
  ],
  "datePublished": "2026-08-17T00:00:00.000Z",
  "dateModified": "2026-08-17T00:00:00.000Z",
  "author": [
    {
      "@type": "Person",
      "name": "Samhitha J Bhatt"
    }
  ],
  "publisher": {
    "@type": "Organization",
    "name": "Vitra.ai",
    "logo": {
      "@type": "ImageObject",
      "url": "https://www.vitra.ai/static/images/vitra-v-logo.png"
    }
  },
  "description": "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."
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://www.vitra.ai"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "General",
      "item": "https://www.vitra.ai/general"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "How to Translate PHP Files and Keep the Code Working",
      "item": "https://www.vitra.ai/general/translate-php-files"
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "How are strings translated in PHP?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    },
    {
      "@type": "Question",
      "name": "What is the hardest part of translating a PHP project?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    },
    {
      "@type": "Question",
      "name": "What must never be translated in PHP?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    },
    {
      "@type": "Question",
      "name": "Should HTML escaping happen in the catalogue?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "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."
      }
    }
  ]
}
```
