Лучший способ сохранить зависящие от локали строковые ресурсы в PHP? - PullRequest
2 голосов
/ 30 октября 2010

Допустим, вы создаете многоязычное веб-приложение, в котором весь текст интерфейса должен быть перемещен на языковые ресурсы и загружен при необходимости.Ресурс строки может быть огромным: скажем, у вас есть несколько тысяч переведенных строк.В оконных средах (Windows, OS X, X11) у вас обычно есть механизм, предоставляемый ОС или некоторым API для этого, и они обычно называются строковыми ресурсами.Тогда как насчет PHP?

Помните, однако, что здесь нужно серьезно относиться к производительности, так как PHP компилирует и выполняет все ваши модули с каждым запросом пользователя.

Я могу придумать несколько возможных способов сделать это.Но прежде всего у меня будет глобальная переменная $ LANGUAGE, которая может быть установлена ​​в 'en', 'de', 'fr' и т. Д. Я буду использовать эту переменную для включения модуля, зависящего от языка, с каждым запросомas

require_once "lang-$LANGUAGE.inc.php"

Итак, некоторые из возможных решений включают:

(1) Определение всех строк как глобальных переменных в каждом языковом модуле, например,

$str_signin = 'Sign in';
$str_welcome_user = 'Welcome, %s'!;
...

Очень просто, легко читаемый и относительно легкий для работы нетехнических людей (то есть переводчиков).Однако существует некоторое глобальное загрязнение космоса, которое немного замедлит поиск в глобальной переменной.

(2) То же, но определено как один огромный массив, например

$str['signin'] = 'Sign in';
$str['welcome_user'] = 'Welcome, %s'!;
...

Менее читаемый, немногоменее пригодный для использования в вашем основном коде (больше задействовано при наборе текста) также немного загромождает ваш код.Это будет медленнее, потому что это не простые назначения, а ассоциированные.назначения массивов: здесь будет больше инструкций для виртуальной машины по сравнению с (1).

(3) PHP 5.3+: определить как константы, возможно, в классе или пространстве имен

class str {
    const signin = 'Sign in';
    const welcome_user = 'Welcome, %s'!;
    const signin_to_a = self::signin . ' to area A'; // can't do this!
    ...
}

... и использовать их как str :: signin и т. Д. Хорошо, мне это нравится больше всего, хотя есть и несколько небольших недостатков: только PHP 5.3+;не может использовать выражения, только отдельные значения (что может или не может быть хорошо в вашем случае);не может использоваться в $ -расширениях в строках в двойных кавычках (или нет?).

(4) База данных: поместить все в таблицу и извлечь по некоторому идентификатору, например, str_get (STR_SIGNIN).Ужасно, медленно, требуется синхронизация ваших идентификаторов в коде с идентификаторами БД, однако нет необходимости загружать все, когда все ваши страницы нуждаются в нескольких строках.Честно говоря, не могу сказать, является ли это хорошим решением или нет.

Есть еще предложения?Кроме того, мысли об этих?

И, пожалуйста, имейте в виду, простота, элегантность и производительность!

Ответы [ 4 ]

2 голосов
/ 30 октября 2010

Zend Framework имеет компонент под названием Zend_Translate, который действительно полезен, и на его справочной странице есть хорошая запись о различных способах хранения строк, даже если вы решили не использовать компонент ZF. 1003 *

PHP является наиболее эффективным и лучшим решением, если вы поддерживаете строки как разработчик. Если вы работаете с переводческой компанией, вполне вероятно, что они будут работать с CSV и отправлять их туда и обратно.

Из головы не знаю, лучше ли решение на основе массивов или констант, но мои деньги лежат на массивах. Быстрый тест скоро скажет вам.

1 голос
/ 31 октября 2010

Я использую таблицу mysql для хранения всех языковых строк.Таким образом, я могу легко создать пользовательский интерфейс для их редактирования.Я получаю все языковые строки, связанные с объектом, в виде ассоциативного массива (с функцией GetAssoc в ADODB).Я кеширую массив с помощью класса Pear :: Cache, поэтому в следующий раз я просто получу этот кешированный массив (без запросов к базе данных)Это было лучшее решение для меня до сих пор.Это можно оптимизировать, используя различные методы кэширования.

1 голос
/ 30 октября 2010

А как насчет gettext?В качестве альтернативы Zend Framework предоставляет действительно надежный интерфейс для работы с переводами.

0 голосов
/ 31 октября 2010

Я провел простые тесты производительности для первых трех методов. Я создал модули с 10 000 назначений строк и измерил отдельно время загрузки / компиляции, а также время доступа.

Что не удивительно, так это то, что константы загружались и компилировались намного быстрее по сравнению с глобальными и массивными методами. Что меня удивило, так это то, что доступ к константам был значительно медленнее! Возможно, потому что это новый механизм в PHP и еще не отточен.

Кроме того, оказывается, что огромный массив быстрее компилируется (на самом деле конструкция массива (...) даже быстрее), чем метод all-globals, но тогда доступ к массиву обходится дороже.

Учитывая, что вы обычно загружаете огромное количество локальных данных, а затем используете только небольшую их часть, я думаю, что наиболее разумным методом будут константы. Не удивительно, что статические константы класса работают лучше, чем глобальные.

Поэтому я бы выбрал метод 3. Я не тестировал метод базы данных, но что-то предполагает, что чтение всей таблицы базы данных будет примерно таким же или более дорогим, чем чтение источника PHP того же объема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...