Главная > AGP Game Platform, Java - язык и технологии, Open Source, PHP, web2.0, веб-обзоры, Разное > Исследование совместимости Zend Framework и Quercus PHP

Исследование совместимости Zend Framework и Quercus PHP

28 декабря 2008

caucho-whiteПриветствуем наших читателей. Нас уже почти-почти настиг праздник, так что, вероятно, это последняя запись блога в этом году, далее я буду только обновлять наш Twitter (а он стал очень даже популярным и читаемым каналом, там уже 45 читателей! Присоединяйтесь и вы!). А тема последнего поста будет снова таки оригинальной и исследовательской. Если помните, я давно уже заинтересовался объединением мира Java и PHP, в частности, при помощи замечательного продукта Quercus PHP - порта PHP-интерпретатора вместе с библиотеками на Java. И вот, очередной раз просматривая уже почти готовый архитектурный макет своего движка для браузерных онлайн игр, я обратил внимание на ускользнувшую от меня деталь. Ведь я собирался использовать популярный и мощный фреймворк Zend Framework, запуская его, конечно же, поверх QuercusPHP (детальнее про архитектуру движка я начну рассказывать после нового года). А он, как известно, достаточно требователен к различным расширениям и модулям - в одном проекте, что я сейчас делаю, используя только Zend_Search_Lucene, я встретился с необходимостью подключения ранее не используемых расширений. А значит вполне может быть ситуация, что эта платформа не будет поддерживать все необходимые функции для работы Zend Framework-а. Просмотр Google по поводу совместимости ничего определенного не дал, так что было решено посвятить пару часов собственному исследованию.

Сначала о Zend Framework. В специальном разделе мануала перечислены все необходимые модули  и указаны конкретные зависимости между модулями и классами фреймворка. Существует два вида зависимостей - Hard, когда  некоторые классы или весь фреймворк жестко зависит от расширения и не будет работать без него, и Soft, когда расширение используется только для увеличения производительности, если же функции недоступны, она  эмулируются при помощи РНР-кода.

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

Да, для проверки на совместимость я решил использовать некоторый тестовый скрипт, который, будучи запущенным в окружении QuercusPHP, собирает всю информацию о доступных функциях и установленных модулях, и сравнивает ее с необходимым для ZF списком.

Используя PHP функцию get_defined_functions я получил сначала полный список реализованных функций PHP, которых в Quercus-е оказалось 1342, вместе с несколькими служебными и специфическими только для него, например, Java и несколькими с префиксом resin, а также модуль Quercus. Кстати, аналогично надо бы собрать РНР с теми же модулями и проверить полноту реализации всех функций, но это уже задача следующего теста.

Далее надо было получить список именно модулей (расширений) реализованных в среде, ведь вручную сопоставлять функции и модули это, скажем так, занятие ещё то. В мануале нашлась функция, get_loaded_extensions, которая аналогично описанной выше, выводит массив модулей, доступных скриптам. Оказалось, что список расширений в QuercusPHP достаточно большой  - 31 модуль. Поскольку в официальной документации о реализованных расширениях написано лишь в общих чертах, я приведу полный список (для последней версии, 3.2.1), возможно, пригодится:

mcrypt, SPL, curl, gd, mysqli, mhash, gettext, json, apc, mbstring, tokenizer, pgsql, memcache, zip, standard, hash, XMLWriter, ctype, xml, bcmath, postgres, PDO, pcre, zlib, session, SimpleXML, Reflection, ereg, iconv, oci8, mysql

Детально исследование по степени реализованности всех функций каждого модуля я ещё не проводил, наверное, это будет следующим тестом, однако на первый взгляд смутил только модуль SPL, для которого в списке функций есть только пять -  spl_autoload, spl_autoload_register, spl_autoload_unregister, spl_autoload_extensions, spl_autoload_functions. Так что вопрос о полной реализации этого модуля пока остается открытым (пока писал, решил исследовать исходный код, вопрос снят - вроде весь функционал там реализован). Приятно порадовало, что "с коробки" реализован кеш APC, впрочем это особо подчеркивалось и на сайте (размечтаюсь - вот бы туда внедрить поддержку серьезного кеша, да еще распределенного и персистентного, типа EHCache или JBoss cache). Присутствует модуль mb_string, хотя практическая ценность его, мне кажется, только в совместимости API, ведь в отличие от обычного РНР,  в QuercusPHP изначально полная поддержка UTF внутри есть уже сейчас, в данном случае там уже реализовано то, что ожидается в РНР 6. Но для включения необходимо установить опции в конфиге (а точнее - unicode.semantics и script-encoding). Порадовало, что в списке модулей есть Memcached расширение, однако при детальном просмотре не оказалось списка функций - возможно, странности работы именно самой функции получения списка реализованных методов, так как в исходном коде API присутствует.

Теперь осталось выяснить, что есть и чего не хватает по списку зависимостей для Zend Framework-а. В тестовом скрипте у меня есть два массива, в одном - список модулей, которые есть в QuercusPHP, в другом - список тех, что требуются для ZF. Сравнить их дело тривиальное, а на выходе получаем пять модулей, которые отсутствуют:

  • Модуль bitset, который предназначен для побитовых операций над двоичными данными. На самом деле потеря этого модуля не самое страшное, от него зависят только Zend_Search_Lucene, да и то Soft, то есть класс самостоятельно реализует функционал. Да и вообще - если у вас уже есть Java-платформа, используйте родной Java Lucene, в нем больше функционала, да и по скорости работы будет существенный выигрыш.
  • Модуль Dom, от которого уже зависит множество классов, в том числе и очень полезные, например, Zend_Feed, Zend_Rest_Server, Zend_XmlRpc и несколько модулей Zend_Service. Вот здесь первая сложность, так как все эти модули достаточно важны, без них привлекательность ZF вообще сильно снижается. Вместе с стем выход есть - судя по ссылке, где описание этого модуля, там всего лишь одна функция, dom_import_simplexml, которая получает Dom объект из SimpleXMLElement. А ведь модуль SimpleXML вполне реализован и поддерживается. Думаю, вручную написать эту функцию на РНР не составит особого труда, таким образом, избавившись от зависимости. А знающие Java могут пойти ещё дальше и добавить в сам движок этот модуль, благо и исходный текст есть и его структура достаточно проста и понятная.
  • Библиотека libxml - это уже сложнее, от нее зависит и ряд системных функций, тот же модуль Dom и SimpleXML, хотя как он реализован без этого модуля, это интересно. Но есть порт LibxmlJ, либо использовать другие парсеры, написав враппер для недостающих функций, тем более, что, судя по всему, все для работы с XML уже есть, разнича только в конкретных API. Уж с чем-чем, а с XML то в Java вроде никаких проблем нет. Но здесь уже требуется некоторая ручная работа и привлечение внешних библиотек. Так что первый модуль, который реально нужен для ZF, но отсутствует, обнаружен.
  • Модуль mime_magic для определения MIME-типа данных из HTTP-запроса, требуется только модулю Zend_Http_Client, который достаточно специфичный и, думаю, редко серьезно используется. Да и в модуле всего одна функция, думаю, написать враппер, используя исходники QuercusPHP будет несложно.
  • Модуль posix требуется для Zend_Mail и, наверное, единственное, что сложно перенести в java, однако... Если хорошо поискать, то есть несколько проектов, переносящих POSIX-API в Java (например, вот этот или Easy Posix Toolkit), тем более, что нам не надо все, а только то, что требует Zend_Mail. Хотя, наверное, лучшим вариантом будет переписать модуль Zend_Mail для того, чтобы избавиться от зависимости или даже просто не использовать его вовсе. И, кстати, переписать его не так и сложно - зависимость там только от функции posix_getpid, да и в коде есть обходной код, если такой функции нет.

И так, исходят из всего этого, можно сделать вывод, что из серьезных препятствий у нас только Dom/libxml, остальное либо автоматически обходится самим фреймворком или же просто можно заменить более продвинутыми аналогами, благо у нас есть возможность напрямую работать с Java классами. В первую очередь я рекомендую выбросить Zend_Search_Lucene и использовать напрямую API из Java Lucene, а еще лучше - написать компонент, реализующий интерфейс из ZF, а внутри использующий Java Lucene. Но это уже серьезная работа, иногда лучше использовать что-то на подобии Solr.

В принципе, ничего невозможного в запуске на QuercusPHP любых сторонних приложений и фреймворков, даже таких мощных и сложных, как Zend Framework, нет, однако требует взвешенного подхода и анализа зависимостей. Покопавшись в исходниках QuercusPHP, даже я, обладая посредственными знаниями в Java, сделал вывод, что в случае необходимости, расширить API достаточно просто, поэтому во многих случаях, если вам не хватает одно-двух, часто тривиальных функций, есть смысл написать их самостоятельно.

Думаю, в следующем исследовании я подробнее рассмотрю полноту реализации функций и сравню QuercusPHP и бинарную версию PHP 5.2.8 с тем же набором расширений.

Комментирование отключено.
Developers.org.ua