Статьи

Некоторый PHP, созданный с помощью Python

Недавно мы рассматривали некоторый код, который предоставляет механизм локализации пользовательского интерфейса для разных человеческих языков. Механизм для этого выглядит примерно так (повторяется много раз);


:

Глобальная переменная $ lang является гигантским ассоциативным массивом и загружается перед вызовом этой функции, в зависимости от предпочтительного языка пользователя, возможно, что-то вроде этих файлов, в терминах массивов PHP;

'Имя',
'btn_ok' => 'ОК',

);

?>

«Номбр»,
'btn_ok' => 'AUTORIZACION',

);

Данный код не является исключением. Я видел, как многие PHP-приложения обрабатывают локализацию таким образом. В « Интернационализации и локализации с PHP », «наивный» читатель может прийти к выводу, что это лучшая практика по умолчанию. В статье нет ничего плохого, но необходимость простого примера / короткой прозы оставляет другие области для воображения читателей.

Большая проблема с локализацией таким образом состоит в том, что это происходит во время выполнения . Каждый запрос страницы приводил к динамической генерации локализованной версии страницы - см. Здесь примерное представление о том, почему это не так хорошо.

Теперь может быть возможно кэшировать выходной HTML и сохранить его как статический файл, но в реальном примере, скорее всего, мы будем иметь действительно динамические данные, смешанные там, например, что-то из базы данных, что усложняет кэширование. Без кэширования перевод добавляет значительную базовую нагрузку к генерации каждой страницы, которая будет увеличиваться по мере усложнения пользовательского интерфейса.

Между тем будет только конечное количество переводов пользовательского интерфейса, которые будут меняться только при изменении самого пользовательского интерфейса (редко - конечно, не по предварительному запросу). Так что не лучше ли иметь несколько версий функции drawNameForm (), по одной на язык, например;

Имя:

И...

Nombre:

Конечно, кто хочет вручную поддерживать несколько версий одного и того же кода?

Для этой конкретной проблемы решения уже разработаны, как правило, упакованы в качестве шаблонных движков. Реализация файловых схем Джеффа в WACT выполняет генерацию JIT на PHP-скриптах, как вы можете видеть здесь . Я считаю (не смотрел) Smarty имеет аналогичную функциональность. Хорошо, если вы довольны движком шаблонов .

Однако существуют и другие похожие категории проблем, которые еще не решены. Например, конфигурация приложения. Вот еще один наводящий фрагмент;

if ($ config ['allow_bbcode']) {

if ($ user_sig! = '' && $ user_sig_bbcode_uid! = '') {

$ user_sig = ($ config ['allow_bbcode'])?

bbencode_second_pass ($ user_sig, $ user_sig_bbcode_uid):

preg_replace ('/: [0-9a-z:] +] / si', ']', $ user_sig);

}

if ($ bbcode_uid! = '') {

$ message = ($ board_config ['allow_bbcode'])?

bbencode_second_pass ($ message, $ bbcode_uid):

preg_replace ('/: [0-9a-z:] +] / si', ']', $ message);

}

}

}

Ключевая линия;

if ($ config ['allow_bbcode']) {

При каждом запросе страницы это условие (как и многие другие) переоценивается. Не лучше ли просто удалить блок кода, если $ config ['allow_bbcode'] имеет значение false? Были попытки создать установщики PHP, некоторые из которых были очень успешными, предназначенными для одного приложения (например, eZ publish 3 ), причем наиболее зрелой, обобщенной попыткой была установка Zzoss от Sandro , о которой я упоминал ранее здесь .

Я думаю, что с точки зрения написания инсталляторов в PHP все начинает «разваливаться», в общем, потому что PHP был разработан специально для веб-сайтов - это не решение общего назначения. Это не означает «никогда», но, принимая во внимание другие технологии, можно ли сделать жизнь проще / PHP-приложения лучше?

Генерация кода уже упоминалась в этом блоге. Еще одна ссылка с http://www.codegeneration.net/ с тех пор здесь ;

PHP удивителен, потому что он так недорог в запуске. Все, что вам нужно, это Apache, MySQL и PHP, и вы можете запустить веб-сайт или сервис.

... и добавьте к этому, как легко развернуть скрипт - просто поместите его куда-нибудь на свой веб-сервер, и все готово - что-то, что открывает двери для генерации "точно в срок", например.

Генерация кода часто имеет тенденцию рассматриваться с точки зрения создания законченных приложений с помощью дружественного «перетаскивания», такого как CodeCharge Studio . Хотя это имеет свое место, оно имеет тенденцию быть «все или ничего».

Интересной и альтернативной формой генерации кода, с которой я столкнулся сегодня, является Aspect-Oriented PHP . Он использует Java для базового анализа PHP-скрипта и объединения со вторым «аспектным» скриптом (см. Здесь, чтобы понять, что такое AOP). Сейчас это, вероятно, нереалистичное предложение с точки зрения производительности, но это интересно, потому что, во-первых, они используют Java для выполнения работы, что дает им прочную основу для работы с такими вещами, как многобайтовые символы или более сложные операции синтаксического анализа и потому что они генерируют PHP на лету.

Возвращаясь к проблеме локализации, описанной выше, недавно я посмотрел на empy : «Мощная и надежная система шаблонов для Python». Некоторые вещи, которые делают empy привлекательным, на данный момент, это то, что он предназначен для шаблонов общего назначения (не для HTML), он зрелый, разметка очень отличается от PHP и HTML (единственное, что вам действительно нужно смотреть, это символ @) и это позволяет вам использовать сам Python в качестве языка шаблонов, когда это необходимо.

Шаблон empy для генерации PHP из drawNameForm () может выглядеть следующим образом;

function drawNameForm () {

?>

@(имя):

Разметка empy, которую я использовал: @ (name) и @ (btn_ok) ( empy имеет гораздо больше, но пока придерживается некоторых базовых ссылок на переменные).

Просмотр результатов этой функции в браузере приводит к следующему источнику HTML;

@(имя):

Другими словами, я все еще могу использовать его как рабочий скрипт PHP (по крайней мере, в этом примере).

Между тем, если я запускаю его через скрипт на python (который в свою очередь вызывает empy ), то вроде;


#!/usr/bin/python
# translate.py

# Загрузить empy
импортировать их

# Используйте словарь (например, ассоциированный массив PHP)
# ради примера. На практике используйте внешние файлы ...

langs = {}

langs ['en'] = {

'name': 'Name',
'btn_ok': 'ОК',

}

langs ['es'] = {

'name': 'Nombre',
'btn_ok': 'AUTORIZACION',

}

# Создать переводчик empy

интерпретатор = em.Interpreter ()

# Загрузить шаблон PHP-скрипта
tpl = open ('ui.tpl.php'). read ()

# Цикл доступных переводов

для lang в langs:

# Дайте интерпретатору новый файл для записи вывода в
interpreter.output = open ('ui.' + lang + '. php', 'w')

# Сброс для нового разбора (чтобы он использовал выходной файл)
interpreter.reset ()

# Заполните пространство данных переводчиков списком слов
# записать в шаблон
interpreter.globals = langs [lang]

# (Повторно) Разобрать шаблон
interpreter.string (TPL)

interpreter.shutdown ()

Он выплевывает локализованные сценарии PHP с именами файлов, идентифицирующих язык, например


Nombre:

Теперь я могу использовать его как часть процесса сборки для моего приложения, так как оно готовится к выпуску. Во время выполнения код (кодированный вручную), который использует этот скрипт, может выглядеть следующим образом;


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

Некоторые конкретные моменты о Python. Используя преимущества таких вещей, как py2exe или py2app, вы можете распределять исполняемые установщики. Добавьте немного wxPython, и вы получите кроссплатформенный графический интерфейс (который выглядит как настоящий - использует нативные виджеты) для установки.

Какие-нибудь истории?