Android-приложения на JPHP

Люди которые пишут код на PHP сделают всё чтобы не переходить на другие языки. Да, я в курсе что раньше на Хабре уже был способ писать Android-приложения на PHP, но было принято решение адаптировать его под более быстрый и совместимый с Java JPHP.


logo


О языке JPHP


Я предполагаю, что у вас может возникнуть вопрос. А что за JPHP? Ответ есть тут-же, на Хабре:



Ну, а мы продолжим. За те 4 года которые прошли с момента написания этих постов о JPHP этот язык поменялся в лучшую сторону. К примеру появился собственный пакетный менеджер jppm про который нам тоже сегодня придётся поговорить.


Как всё началось


Всё началось с того, что моему другу пришла идея создавать приложения для Android на JPHP. Я дал почитать ему тот пост, про который мы говорили в начале, но ему этот способ не понравился так как там используется обычный PHP. Ну, а мы разработчики, которые пишут на никому не известном языке JPHP решили сделать всё сами.


Полистав интернет, мы тогда не нашли другого выхода, кроме как использовать JavaFXPorts. Да и сам создатель этого языка хотел использовать именно его в качестве GUI движка для JPHP за 2 года, так ничего и не сделав.


Как говорится — «Кто кроме тебя»?.. Я бросился глобально изучать работу языка JPHP.


Первые несколько недель были неудачными. Я уже написал автоматическую генерацию build скрипта для gradle и всё бы хорошо, apk собирался, но при запуске выдавалась неизвестная мне на то время ошибка. Я сразу понял что она из-за JPHP но не видел я прежде такую. Сейчас я могу сказать точно что эта ошибка была из за сгенерированного байт-кода. DalvikVM банально не мог запустить байт-код сгенерированный для JVM. Именно это стало огромным препятствием. Так как PHP файлы в JPHP приложениях не компилируются вовсе. Был вариант с файлами phb, но это не решало нашу задачу вовсе. Единственным способом стало написание собственного компилятора, что действительно сработало, но принесло ряд ограничений связанных с include и eval, спасибо, Dalvik.


После многих проб и ошибок я всё же сумел сделать самую первую версию. Её исходники находятся тут. Эта версия была не очень быстрая. Да и использовать JavaFX на Android это мазахизм.


По этому я принял решение переписать всё с чистого листа. Принял я это решение относительно недавно. По этому библиотека для JPHP немного сыровата. Но работает.


Как это работает


Всё начинается с того что jppm собирает все ваши исходники и зависимости в один jar файл. После чего компилируя в них все файлы php в class файлы. После чего полученный jar файл добавляется в зависимости к gradle. А он уже в свою очередь компилирует эти class файлы в dex. В этом весь секрет.


С запуском приложения всё сложней. В AndroidManifest.xml изначально всего один BootstrapActivity который загружает весь JPHP. После загрузки этот BootstrapActivity можно будет изменять из JPHP. Для Activity я создал одноимённые классы.


<?
use php\android\app\Application;

$bootstrapActivity = Application::getMainActivity();

С помощью этого кода можно получить тот самый BootstrapActivity из которого был загружен JPHP.


Я думаю вам уже стало понятно о работе загрузчика JPHP.


Небольшой пример


К примеру для того чтобы создать самый примитивный кликер нужно использовать вот этот код :


<?
use php\android\app\Application;
use php\android\widget\Button;

$activity = Application::getMainActivity(); // Получаем BootstrapActivity
$activity->setTitle("test"); // Добавляем заголовок  
$activity->setContentView($button = new Button($activity)); // Создаём и добавляем кнопку 
$button->text = "Hello from JPHP!"; // Ну тут всё понятно
$button->on("click", function () use ($button) { // При нажатии на кнопку ...
    $GLOBALS['clicks']++;
    $button->text = "Clicks: " . $GLOBALS['clicks'];
});

В итоге мы получили простое приложение с кнопкой:



Заключение


Я не думаю что мой проект кому либо будет интересен. Так как он не описывает пока что и 10% Android API. Да и написание приложений для Android на PHP не канон. Но думаю проект найдёт свою аудиторию.


Github проекта
Github JPHP
Группа в VK

Поделиться публикацией
Комментарии 48
    +1
    Я конечно люблю php и пишу на нем уже много лет, но даже у меня возникает вопрос «зачем?». На андроиде же есть Котлин. ТС присмотрись к нему, и я уверяю что после него тебе не захочется возвращаться к php.
      0
      Мне больше по душе java. А Котлин для меня слишком запутан.
      +4
      Самая важная часть у любого языка — это его экосистема, которая складывается из двух факторов:
      1) Количество разработчиков
      2) Количество написанных и готовых решений

      В первом случае у JPHP довольно посредственно, т.к. язык вроде тот, но АПИ несовместимое, а во втором — вообще пусто.

      Т.к. язык не совместим с Stdlib PHP, то потеря огромного пласта из Composer наработок — фатальна. Это одна из причин почему использование его в около-продакшн проектах не представляется возможным в настоящее время. Ну и в ближайшем будущем, т.к. сообщество не способно обеспечить качественную кодовую базу уровня современного PHP, а каждый раз велосипедить — так себе удовольствие.

      Учитывая всё это, я бы рекомендовал всё же брать Kotlin для этих целей или Java накрайняк. Изучить последний, после PHP — дело 5ти минут, т.к. языки почти что одинаковые по подходу к разработке. А JPHP… ну да, прикольно, но не более.
        –2
        я бы рекомендовал всё же брать Kotlin для этих целей или Java накрайняк.

        Пожалуйста, не давайте советов о том, в чём вы не разбираетесь. Java всё-таки пока еще официальный и основной язык разработки для OS Android, а Kotlin — уже поддерживаемая, но пока неосновная альтернатива.
        Да и честно говоря — альтернатива пока так себе, кроме nullsafety и возможности красиво в один лист описывать разметку.

        Изучить последний, после PHP — дело 5ти минут

        Нет. Кроме подхода к разработке есть стандартная библиотека, есть фреймворки, есть хорошие практики, и если говорить об уровне хотя бы middle java developer, то миграция с PHP займёт существенное время. Существенно больше 5 минут. Это мы еще не перешли к concurrency, collections, internals и прочему хардкору. А оно вам понадобится, когда вы будете оптимизировать и выжимать всё что можно из своей приложеньки.
          +3
          Пожалуйста, не давайте советов о том, в чём вы не разбираетесь. Java всё-таки пока еще официальный и основной язык разработки для OS Android, а Kotlin — уже поддерживаемая, но пока неосновная альтернатива.
          Да и честно говоря — альтернатива пока так себе, кроме nullsafety и возможности красиво в один лист описывать разметку.


          Я исходил из того, что АПИ полностью совместимое и при установке какой-нибудь библиотечки из мавена — оно полностью прокидывается и доступно из котлина. Отсюда и подобные рекомендации, т.к. у котлина из коробки доступно больше плюшек, нежели у джавы. Хотя, признаться, последнее время язык пополнился крутыми фичами, да и поддержка андроидом больше не внушает опасений (раньше была поддержка Java 6 (Android 4+), хотя на дворе 8ая актуальной была и 9ая готовилась). При этом Kotlin нормально собирается под эту самую 6ую джаву, если я ничего не перепутал (поправите?).

          Нет. Кроме подхода к разработке есть стандартная библиотека, есть фреймворки, есть хорошие практики, и если говорить об уровне хотя бы middle java developer, то миграция с PHP займёт существенное время.


          Не стоит выдирать утверждения из контекста. Я противопоставлял Java vs JPHP с точки зрения тех, кто знаком с синтаксисом второго. И в случае Java, и в случае JPHP у нас появляется требование к изучению окружения. При этом у второго его почти что нет. По крайней мере ни одного фреймворка, лишь биндинги на Java. Учитывая эти исходные позиции, т.е. игнорируя эту переменную остаётся синтаксис. И тут разницы почти что нет, 90% кейвордов пересекаются.

          UPD: Да и если говорить о фреймах и стандартной библиотеке, то имеем Spring vs Symfony, Doctrine vs Hibernate, Spl vs collections, Thread vs concurrency и прочее. Ну т.е. даже подходы перенимаются друг у друга. Тот же Stream API почти полностью взят из коллекций Laravel (хотя и брать-то нечего, всё довольно очевидно).

          collection.stream()
              .filter(o -> o % 2 != 0)
              .reduce((s1, s2) -> s1 + s2)
          

          collect($items)
              ->filter(function($o) { return $o % 2 !== 0; })
              ->reduce(function($s1, $s2) { return $s1 + $s2; });
          
            0
            Я исходил из того, что АПИ полностью совместимое и при установке какой-нибудь библиотечки из мавена — оно полностью прокидывается и доступно из котлина. Отсюда и подобные рекомендации, т.к. у котлина из коробки доступно больше плюшек

            Да, конечно, API видно в Kotlin, т.к. это JVM-язык. Но с плюшками в нем не так однозначно — например, с моей точки зрения вывод типов — ну, так себе «плюшка», файберы и корутины — тоже.

            И в случае Java, и в случае JPHP у нас появляется требование к изучению окружения. При этом у второго его почти что нет. По крайней мере ни одного фреймворка, лишь биндинги на Java.

            Что, простите? Фреймворков в Java нет?! Если мы говорим об Android-разработке на Java, то а) SDK уже сам по себе фреймворк, и б) для различных задач есть свои фреймворки (Retrofit, Picasso, EventBus, GreenORM, Vault) которые упрощают до двух строчек кода.

            В данном случае ситуация «можно прокинуть API в JVM-скриптинг».
            И даже со всем этим, «спрыгнуть» на Java человеку, который ранее плотно работал с PHP — тот еще квест. Шарписту попроще, да.
              0
              Да, конечно, API видно в Kotlin, т.к. это JVM-язык.


              А вот не совсем.
              1) Есть Ceylon, где Java API недоступно
              2) Есть JPHP, где Java API точно так же недоступно.

              Но с плюшками в нем не так однозначно — например, с моей точки зрения вывод типов — ну, так себе «плюшка», файберы и корутины — тоже.


              А это то, что и составляет язык в целом. Вот такие мелочи. Да и не только это. Аргументы у класса, вместо конструктора, а-ля Scala. Вроде мелочь, а сразу приятнее становится, лишний boilerplate исчезает. Да и вообще. Те же корутины — вообще меняют (могут поменять т.е.) подход к разработке и архитектуре в целом.

              Что, простите? Фреймворков в Java нет?!

              Я написал «у второго», у JPHP, читайте внимательнее, прошу.

              И в случае Java, и в случае JPHP… у второго его почти что нет
                –1
                А это то, что и составляет язык в целом.

                Нет. Фичи stdlib рантайма и фичи языка, строго говоря разные и несвязанные вещи.

                Аргументы у класса, вместо конструктора, а-ля Scala. Вроде мелочь, а сразу приятнее становится, лишний boilerplate исчезает

                Вкусовщина. Борьба с «бойлерплейтом» в виде оператора new… Ну такоэ.

                Те же корутины — вообще меняют (могут поменять т.е.) подход к разработке и архитектуре в целом

                А ради чего? С чем боремся? Есть ООП — он в подавляющем большинстве случаев стреляет хорошо. Вы можете возразить, что есть сложности в многопоточной среде, так опять же есть хорошо проработанные ООП шаблоны для многопоточных сред.
                Реактивный подход, например, лишь добавляет выразительности, а функциональный в подавляющем большинстве случаев эгоистичен и не привносит существенных бонусов. Так же и с Котлином.

                1) Есть Ceylon, где Java API недоступно
                2) Есть JPHP, где Java API точно так же недоступно.

                Ну, с Цейлоном то это более-менее понятно — там пытаются усидеть на двух стульях — JS и JVM, вот и городят изоляции и абстракции. В случае с JPHP вообще малопонятно его существование при таком подходе. Вон, Jython вполне себе реализует стандартную библиотеку, и на нем можно запустить то, что запускается на нативном Python
                  0
                  Нет. Фичи stdlib рантайма и фичи языка, строго говоря разные и несвязанные вещи.

                  Эм… Ну разговор об этом был в рамках Kotlin vs Java, а там stdlib почти идентичный. Рантайм почти нулевой (кастомные иммутабельные коллекции и пара классов не считаются). Учитывая это, очевидно, что рассматривается синтаксический сахар котлина.


                  Вкусовщина. Борьба с «бойлерплейтом» в виде оператора new… Ну такоэ.

                  Ну нет, ещё присваивание локальным полям, геттеры и сеттеры. Т.е. один аргумент в class Example constructor(firstName: String) { ... }
                  заменяет 7 строк кода на Java, два аргумента — 14 и т.д.


                  А ради чего? С чем боремся?

                  Ну, например, с излишней связанностью. В одной из тем я приводил пример препроцессора для бейсика, правда на PHP (ну т.е. наркота полная, с серьёзным лицом статью лучше не воспринимать). Там как раз используются корутины, вместо реализации визитора для AST + делегирования основного билдера внутрь каждого дочернего.


                  Ну и это стоит расценивать как "что получаем", а не "с чем боремся". Это просто новый функционал на основе которого можно реализовывать совершенно другие ООП паттерны.


                  Ну, с Цейлоном то это более-менее понятно — там пытаются усидеть на двух стульях — JS и JVM, вот и городят изоляции и абстракции. В случае с JPHP вообще малопонятно его существование при таком подходе.

                  Ну это лучше с dim_s побеседовать. Возможно что-то удастся выяснить. Мои споры с ним на тему "нужно использовать готовые вещи, где первоочередной должна быть поддержка стандартных и общепринятых вещей, а всякие плюшки вешать уже поверх позже" завершились тем, что я махнул рукой на проект и ушёл из core-team, хотя в целом всё было вполне норм. Это было года 3-4 назад, даже ещё раньше, так что я не знаю изменилась ли его позиция сейчас.

                    0
                    ещё присваивание локальным полям, геттеры и сеттеры

                    Lombok прекрасно справляется.

                    Это просто новый функционал на основе которого можно реализовывать совершенно другие ООП паттерны.

                    Как по мне отдает «Not invented here»
                    0
                    А ради чего? С чем боремся?

                    Задайте этот вопрос разработчикам Golang. Они, если сильно утрировать, ради горутин целый язык наворотили. Видать, ООП не так чтобы сильно помогал в многопоточной среде. Хотя конечно, если всю жизнь ходишь по костылям, более-менее ровная дорога вызывает чувство отторжения.
                    И да, корутины — это ведь не сахар поверх тредов. Ну, вы это наверняка знаете.

                      0
                      Не, целый язык именно ради горутин — это еще понятно: нам нравятся горутины, и мы придумали целый язык, чтобы именно их было удобно использовать. Язык для нативной разработки.

                      Я 7 лет в Java-разработке, и существующую инфраструктуру многопоточности и конкарренси как костыльную или ущербную не воспринимаю абсолютно, а мне уж пришлось этого наесться ввиду специфики работы.
                        0
                        Я 7 лет в Java-разработке

                        Так в Java или в Android? Concurrency в джаве и в андроиде — это, как говорится, две большие разницы.

                          0
                          7 в Java, чуть поменьше и пореже в Android.
                            0

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

                              0
                              Что, простите? Девайс с 4 Гб ОЗУ нынче «С ограниченными ресурсами»? Вы делаете меня смеяться. Ну и какой кейс дает ощутимую экономию на корутинах/файберах? Вон завели вы в проектике thread pool, один фиг у вас файберы эффективно на нем исполняются. Да, шедулятся рантаймом, а не операционкой, и из этого следуют некоторые неявные минусы.
                              А плюс с моей позиции, как разработчика Android-приложения — упрощение макетирования layout. Такой себе плюс чтобы пересаживаться на новый язык.
                                0

                                Внезапно не все устройства даже сейчас получают столько ОЗУ. Об Android Go и "the next billion" слышали? А надо бы слышать. И да, вы же в курсе, что будь хоть 10гб на устройстве, у приложения есть своя песочница максимум с сотней-второй мегабайт.
                                А лайауты на Анко — это как раз так себе плюс, который к тому же ортогонален языку отлин как таковому.

                                  0
                                  Не все, конечно. Когда я разрабатываю очередную приложеньку — я вполне себе четко представляю нижний предел по ресурсам и API Level. Если не таскать в песочницу многосотметровые битмапы — живется вполне себе беззаботно.
                      +2

                      В чем суть JPHP написано на странице проекта в GitHub'e:


                      1. Замена уродливой и несогласованной стандартной библиотеки функций Zend PHP.
                      2. Поддержка многопоточности и потокобезопастности на уровне движка языка.
                      3. Поддержка юникода, полная поддержка, как хотели в PHP 6.
                      4. Возможность интегрироваться с библиотеками Java.
                      5. Расширить применение PHP.

                      На английском
                      • Ability to use java libraries in PHP
                      • Upgrading performance via JIT and JVM
                      • Replacing the ugly runtime library of Zend PHP with a better runtime library.
                      • Using the PHP language not only on the web
                      • Also: unicode for strings and threads
                0
                Пожалуйста, не давайте советов о том, в чём вы не разбираетесь. Java всё-таки пока еще официальный и основной язык разработки для OS Android, а Kotlin — уже поддерживаемая, но пока неосновная альтернатива.

                Большой вопрос кто тут дает советы в том, в чём не разбирается.

                Kotlin уже больше года как назван «first class language on Android», что собственно и означает его официальную поддержку. До I/O 2017 «официальным» языком был только один — Java, а на той конференции объявили официальную поддерку Kotlin.

                С тех пор у гугла все чаще и примеры в презентациях и туториалах встречаются на Kotlin, а иногда уже бывает что и нету аналогичного примера на Java и информация подается только на котлине.

                Больще информации здесь: developer.android.com/kotlin
                  –2
                  Kotlin нужен только для того, что бы капитализация JetBrains выросла. Ибо они сразу переходят в другую лигу.
                  Google будет впендюривать Kotlin, по тому что 100% у них есть идея выкупить — это вcе у ребят из JetBrains.
                  Как и любая инет контора, идея в том что бы максимум технологий замкнуть на себя.

                  Но в целом взлетит или не взлетит Kotlin на 100% не известно
                    0
                    Не, Гугл нужен Котлин, как язык, чтобы Оракл от него окончательно отвязался.
                      0

                      Поздно, батенька :) Котлин уже взлетел, как минимум, в среде Android-разработки.

                        –1
                        Не взлетел же. Сравните количество кода на Java и на Kotlin.
                          0

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

                            0
                            … Ибо для джавы почти всё что можно уже написано, да :)
                            Статистика, она такая.
                              0
                              Ибо для джавы почти всё что можно уже написано

                              Смешно. Но даже если бы и так, котлину благодаря обратной совместимости с джавой, это только на руку.

                                0
                                Ну, это очень философский вопрос уже.
                                  0

                                  Ну, мы здесь вообще философствуем :) Вот вам плюсов котлина недостаточно для телодвижений. А миллионам мух многим другим разработчикам (как и вашему покорному слуге, извольте заметить) этот весь сахар и плюшки по нраву. Особенно это приятно, если не сидел всю жизнь только с теплой ламповой джавой и ничего удобнее не знаешь.

                      0
                      Спасибо, я знаю где больше информации. Совершенно неважно как там Котлин назван, важно другое — всего год назад. Вот когда Google перепишет на Котлин весь SDK, официально задепрекейтит Java, вот тогда он станет основным. А пока — основной Java. И «поддерживается Kotlin», да. Но с любовью гугла сначала интродьюсить, а потом депрекейтить все что можно, год для официальности мало, да и котлин-специфичного жирка маловато пока. Лет пять хотя бы подождем. А до тех пор пишем на Java и радуемся.
                        0
                        Полностью согласен
                          0
                          > Вот когда Google перепишет на Котлин весь SDK

                          ИМХО, от того на чем написано SDK абсолютно не должно влиять на клиентский код который этим сдк пользуется, тем более с той интероперабельностью которую нам дает Котлин.

                          Окей, пишите на Java и радуйтесь, никто не запрещает. Просто есть чувство что вы как-то очень сильно ошибаетесь насчет популярности Котлина уже сейчас. Мы вот пишем уже почти два года новый код только на Котлине и тоже радуемся.
                            0
                            Ну, плодить сущности плохая идея ж. Один язык — меньше разночтений. Если не секрет — зачем вы пишете на Котлине, что вас увело от Java? Именно с практической точки зрения (эффективность разработки, скорость исполнения кода, етс).
                              0
                              Лично для себя открыл что там прям очень уж много приятных плюшек в синтаксисе самого языка — и работа с nullability, и extension-функции, и data-классы… список можно продолжать.

                              В двух словах, на Kotlin у меня получается код который делает то же самое что и код на Java, но его меньше, его проще читать, писать и поддерживать.
                                –1
                                включить Java 8 source level и подключить Lombok. Останется разве что nullsafety и extensions.
                                  0
                                  Ваш подход:

                                  > включить Java 8 source level и подключить Lombok. Останется разве что nullsafety и extensions.

                                  плюс разобраться с новыми для себя концепциями, написать новый класс (или переписать старый) с новыми знаниями и радоваться

                                  Альтеранатива:

                                  Подключить Котлин к проекту (чаще всего одной кнопкой в IDEA/Android Studio)

                                  плюс разобраться с новыми для себя концепциями, написать новый класс (или переписать старый) с новыми знаниями и радоваться.

                                  Такая ли уж большая разница? А если как я — с самого начала считал Java слишком многословным языком и хотел писать все то же самое, но короче да ещё и с плюшками типа nullsafety и extensions?

                                  Вот я и выбрал второй путь.
                                    –1
                                    плюс разобраться с новыми для себя концепциями

                                    Запомнить пяток аннотаций — это новые концепции? Или лямбды с стримами? И убить геттеры/сеттеры после навешивания аннотаций на Data-класс.

                                    Nullsafety в общем случае достигается правильным проектированием — выбрасывать исключения вместо возврата null.
                                      0
                                      Что-то вы не в ту степь пошли, извините, но я перестану отвечать.

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

                                    Java 8 на андроиде — это скорее насмешка, чем действительно то, что можно назвать восьмёркой. И те, кто считает ломбок альтернативой котлину — сами себе злобные буратины. Я сейчас попал на проект, где джава и ломбок, так последний я больше выпиливаю, чем в новом коде использую. Проще, право, уже ручками конструкторы/геттеры/сеттеры, чем с ним играться.

                                      0
                                      Да норм, аннотацию Data на класс, приватные поля — и больше ничего для data entity не надо.
                                      +1
                                      Подключить Lombok и потом сутки ждать пока отработает кодогенерация на большом проекте?
                                        0
                                        Какие у вас интересные проекты. На последнем проекте, где у нас ломбок в полный рост был — сборка шла минут пять.
                        0
                        // промахнулся веткой
                          –1
                          В каком смысле?
                          0
                          Я знаю одного знакомого который на Basic андроид приложение писал, он к нему привык, наверно так же как люди в этой статье:-)
                            +1
                            «Да и использовать JavaFX на Android» — тама проект Gluon вроде как есть.
                              0
                              Да это он самый. Но если его запустить лагает жутко.
                              +1

                              Оххх, давно я перестал отслеживать развитие jphp, думал что проект уже не развивается… А оно вот как. :)

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое