Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Middle: питання на співбесіді з теми «Локалізація»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

2 питання

Файли в lang/ перекладають інтерфейс - кнопки, підписи, помилки. Для контенту з бази - назв категорій, описів товарів - потрібен інший підхід, і вибір між трьома.

1. Колонки на кожну мову - найпростіше:

Schema::table('categories', function (Blueprint $table) {
    $table->string('name_uk');
    $table->string('name_en');
});

Працює, поки мов дві. Кожна нова - міграція й правка всіх запитів.

2. JSON-колонка:

$table->json('name');   // {"uk": "Вакансії", "en": "Jobs"}

protected function casts(): array
{
    return ['name' => 'array'];
}

Нова мова не потребує міграції. Мінус - пошук і сортування за перекладом стають незручними, хоча PostgreSQL і MySQL уміють індексувати JSON-шляхи.

3. Окрема таблиця перекладів - рядок на пару «запис + мова». Найгнучкіше: пошук і сортування звичайні, мов скільки завгодно. Ціна - join у кожному запиті.

Що врахувати незалежно від вибору:

  • Запасний варіант. Якщо перекладу немає, показувати мову за замовчуванням, а не порожнє місце.
  • URL. Мову зазвичай виносять у шлях (/en/jobs), бо це дає окремі адреси для індексації - на відміну від зберігання вибору лише в сесії.
  • hreflang у розмітці, щоб пошук розумів звʼязок між версіями.
  • Не лише текст. Формати дат, чисел і валют теж локальні; Carbon::setLocale() і Number::format() це враховують.

Докладніше в документації: Локалізація

Каталог lang у новому Laravel-застосунку відсутній - переклади фреймворку (повідомлення валідації, пагінації, автентифікації) живуть у самому пакеті. Щоб їх змінити чи додати свої:

php artisan lang:publish

Команда створює lang/en/ з файлами auth.php, pagination.php, passwords.php, validation.php. Для української переклади фреймворку зазвичай беруть з пакета спільноти (наприклад, laravel-lang/lang), а не перекладають вручну.

Два формати перекладів.

1. PHP-файли з короткими ключами:

// lang/uk/orders.php
return [
    'status' => [
        'paid' => 'Оплачено',
        'shipped' => 'Відправлено',
    ],
    'empty' => 'Замовлень поки немає',
];
__('orders.status.paid');
  • ключі групуються за файлами й вкладеністю;
  • зручно для системних рядків: статуси, повідомлення валідації, тексти листів;
  • ключ не змінюється, коли змінюється текст.

2. JSON-файли, де ключ - сам текст:

// lang/uk.json
{
    "Save changes": "Зберегти зміни",
    "Welcome back, :name!": "З поверненням, :name!"
}
__('Save changes');
  • у шаблонах видно справжній текст, а не orders.empty;
  • якщо перекладу немає, показується сам ключ - англійський текст, а не технічний ідентифікатор;
  • зручно для великого інтерфейсу, де вигадувати ключ для кожної кнопки обтяжливо.

Порівняння:

PHP-файли JSON
ключ orders.status.paid Save changes
вкладеність так ні
без перекладу показується ключ англійський текст
зміна вихідного тексту ключ лишається ключ змінюється, переклади треба переносити

Пастки:

  • конфлікт імен: рядок __('Orders') за наявності файлу lang/uk/orders.php і відсутності ключа в JSON поверне весь масив файлу;
  • запасна мова (APP_FALLBACK_LOCALE) використовується, коли рядка немає в поточній локалі - зручно, але приховує неперекладені рядки. Знаходити їх допомагає Lang::handleMissingKeysUsing() для логування;
  • переклади пакетів перевизначаються у lang/vendor/{пакет}/{локаль}/.

На практиці часто поєднують: PHP-файли - для системних рядків і повідомлень валідації, JSON - для текстів інтерфейсу.

Докладніше в документації: Локалізація: рядки перекладу як ключі