devlephant / soulengine

PHP4Delphi based Engine for Windows Desktop
12 stars 2 forks source link

Миграция на php 5.6 #6

Closed ghost closed 5 years ago

ghost commented 5 years ago

Обновление PHP4Delphi и всех сопутствующих элементов для поддержки php 5.6.41

vGhost2000 commented 5 years ago

А стоит ли на 5.6 мигрировать то? Может если делать то сразу 7.2+ ???

Делал я такое, даже сделал. И вроде работало :-) Потом в итоге я это всё забросил. Потому что php 5.x.x уже безнадёжно устарел. Первое что придётся сделать, выпилить нафиг php4delphi и написать собственный аналог. С php5.6 он работать вообще не будет. Совсем. Там (в пхп) слишком много изменений которые ломают обратно совместимую логику с php4delphi. Вообще сам по себе php4delphi ужасен. Там просто ппц сколько много всего лишнего и не нужного. Быстро это всё работать не будет. Если делать что то такое, то: 1) начать с нуля. DS устарел и содержит кучу пхп кода который мягко говоря не айс. Структура проекта модулей, прочего, в общем не хочу обижать Диму и промолчу. В своё время это было круто, но на дворе 2019. 2) Начинать надо на Embarcadero Delphi 10.2 не ниже. Лучше выше. Почему 10.2+? Потому что там появились FireMonkey визуальные компоненты позволяющие писать кросс платформенные приложения. Мне удалось скомпилить и запустить php gui приложение на винде и андроиде. На линуксе тоже скорей всего завелось бы, просто лицензии не было. 3) PHP часть модуля писать на zephir https://zephir-lang.com/ это резко ускорит разработку и позволит в итоге писать программы которые нельзя будет декомпилировать. К тому же использование зефира позволит делать вставки сишного кода и вызывать любые winapi процедуры которыми не обладает не DS, не PHP, примеры того как я чутка подкорректировал PHP код самой DS и что из этого вышло: http://home.vghost.me/numlock%20winapi%20demo%20app.htm http://home.vghost.me/ScreeenShotDemo.htm http://home.vghost.me/ScreenShotDCDemo.htm 4) написать транслятор php->zephir->c->байткод. 5) оформить расширение для delphi где это всё будет автоматизированно чтоб не изобретать собственную иде долго и упорно, а пользоваться готовой.

У меня в итоге всё затухло вот на этой стадии: http://home.vghost.me/fistdemo.htm К этому моменту вышел php7.1 и продолжать разработку на php 5.6 было глупо. А переписывать 50% интеграции с php на версию 7 было уже и лень, да и на работе озадачили вторым проектом, так что времени уже совсем не осталось и я забил.

ghost commented 5 years ago

А стоит ли на 5.6 мигрировать то? Может если делать то сразу 7.2+ ???

Делал я такое, даже сделал. И вроде работало :-) Потом в итоге я это всё забросил. Потому что php 5.x.x уже безнадёжно устарел. Первое что придётся сделать, выпилить нафиг php4delphi и написать собственный аналог. С php5.6 он работать вообще не будет. Совсем. Там (в пхп) слишком много изменений которые ломают обратно совместимую логику с php4delphi. Вообще сам по себе php4delphi ужасен. Там просто ппц сколько много всего лишнего и не нужного. Быстро это всё работать не будет. Если делать что то такое, то:

  1. начать с нуля. DS устарел и содержит кучу пхп кода который мягко говоря не айс. Структура проекта модулей, прочего, в общем не хочу обижать Диму и промолчу. В своё время это было круто, но на дворе 2019.
  2. Начинать надо на Embarcadero Delphi 10.2 не ниже. Лучше выше. Почему 10.2+? Потому что там появились FireMonkey визуальные компоненты позволяющие писать кросс платформенные приложения. Мне удалось скомпилить и запустить php gui приложение на винде и андроиде. На линуксе тоже скорей всего завелось бы, просто лицензии не было.
  3. PHP часть модуля писать на zephir https://zephir-lang.com/ это резко ускорит разработку и позволит в итоге писать программы которые нельзя будет декомпилировать. К тому же использование зефира позволит делать вставки сишного кода и вызывать любые winapi процедуры которыми не обладает не DS, не PHP, примеры того как я чутка подкорректировал PHP код самой DS и что из этого вышло: http://home.vghost.me/numlock%20winapi%20demo%20app.htm http://home.vghost.me/ScreeenShotDemo.htm http://home.vghost.me/ScreenShotDCDemo.htm
  4. написать транслятор php->zephir->c->байткод.
  5. оформить расширение для delphi где это всё будет автоматизированно чтоб не изобретать собственную иде долго и упорно, а пользоваться готовой.

У меня в итоге всё затухло вот на этой стадии: http://home.vghost.me/fistdemo.htm К этому моменту вышел php7.1 и продолжать разработку на php 5.6 было глупо. А переписывать 50% интеграции с php на версию 7 было уже и лень, да и на работе озадачили вторым проектом, так что времени уже совсем не осталось и я забил.

Спасибо за обращение, отвечу поэтапно :)

  1. Благодаря надобности "начинать с нуля" (а по-другому дс на новую php и не перенесёшь) смысла такого делать вообще нету, есть Hyper IDE, под неё свой движок, свои костыли, свой аналог Hip-Hop'а, там пусть и будет 7.2, вообще та студия не для GUI+php костылей, а для веба в целом, но то уже отдельный разговор. DS пусть остаётся ds, смысла переписывать, оставляя в той-же оболочке -нету. (только копирайт угробить да и всё) Под DS максимум изменений: переписать "компилятор", обновить дизайн через AlphaControls. P.s ветку "слабых" изменений можно просмотреть в говносборке.
  2. Спасибо за совет, учту и обновлюсь Однако есть вопрос - FMX же были и раньше, в XE8 +/- стабильная версия была, но, они что, наконец привели их к нормальному виду ? :smile: P.p.s если Вы про возможность компиляции под линукс - FMX этой магией ещё не обладает, разве что FMXLinux, но данное решение относительно правильное.
  3. В чём плюсы такого решения, не лучше ли использовать своё? Учитывая, что там будет некий неприятный вид связки C++ -> C (Zephyr) <-> Delphi? Не лучши ли C++ <-> Delphi? Или учитывая, что delphi базируется на C, данное решение является более безопасным? P.s пробовали на зефире собирать - нашли пару уязвимостей в плане декомпиляции.

4, 5 - понятное дело, что статика это плохой опыт :) :) :) Вообще любой опыт от Dim-S отличный пример того, как не нужно делать, здорово учит хорошо программировать, если человек обладает достаточной фантазией в плане "как сделать иначе")

ghost commented 5 years ago

У меня в итоге всё затухло вот на этой стадии: http://home.vghost.me/fistdemo.htm К этому моменту вышел php7.1 и продолжать разработку на php 5.6 было глупо. А переписывать 50% интеграции с php на версию 7 было уже и лень, да и на работе озадачили вторым проектом, так что времени уже совсем не осталось и я забил.

Вау, хороший пример, видно, что работы не мало было проделано, немного непонятно мне по структуре обращение к компонентам, или там для класса указывать источник на форме?... мне до него далеко, наверное, а может и нет. Развеселило "выйти нафиг"

vGhost2000 commented 5 years ago

1 Под DS максимум изменений: переписать "компилятор", обновить дизайн через AlphaControls.

А зачем? Я вот сейчас на php5 писать ничего не стал бы. Т.е. пользоваться DS этой как следствие тоже. Смысл тратить время на то что уже не кому не надо какой? Если хочешь сделать что то полезное, начинать надо с php 7.2

2. Однако есть вопрос - FMX же были и раньше, в XE8 +/- стабильная версия была, но, они что, наконец привели их к нормальному виду ? 😄

FMX был и в DX3. Но поддержка linux платформы появилась только начиная с 10.2. Для меня лично это не маловажный факт, т.к. я в основном под линукс пишу.

2. FMX этой магией ещё не обладает,

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

3. В чём плюсы такого решения, не лучше ли использовать своё?

Не лучше. По многим причинам. Например, самая важная время. Свою ты писать будешь очень долго, а потом ещё дольше баги править, а можешь заюзать готовое. Которое поддерживает куча народу. Второе: это решение очень автоматизирует создание классов в пхп клонов delphi классов. Если посмотришь моё последнее видео, увилишь там кучу классов типа \delphi\vcl[бла бла бла] (и не только vcl). Я не один из них не писал, они динамически создаются одним из моих скриптов при первом из хаюзании и потом статично собираются в dll. Я по сути написал 2 не больших класса, от которых наследовались все компоненты. А теперь вот сравни, код на зефире который я написал:

    public function __setEvent(string! $name, $callback)
    {
        var $object_var, $method_var;

        if (typeof $callback == "object") && ($callback instanceof Closure) {
            return Core::processResult(Core::w_setEvent($this->__self, $name, null, $callback));
        }

        if (typeof $callback == "array") && (fetch $object_var, $callback[0]) && (fetch $method_var, $callback[1]) {
            return Core::processResult(Core::w_setEvent($this->__self, $name, $object_var, $method_var));
        }

        throw new Exception("Incorrect parameters passed to setEvent");
    }

Код на сях который сгенерил мне зефир, и который мне не пришлось писать самому. А теперь ещё примени к этому коду тот факт что тут много зефировских макросов, которые сильно уменьшили размер этого кода, т.е. пиши я его на чистом си, он был бы ещё больше!

PHP_METHOD(Delphi__Object, __setEvent) {

    zend_bool _0, _6, _7;
    int ZEPHIR_LAST_CALL_STATUS;
    zephir_fcall_cache_entry *_1 = NULL, *_3 = NULL;
    zval *name_param = NULL, *callback, *object_var = NULL, *method_var = NULL, *_2$$3 = NULL, *_4$$3, *_5$$3, *_8$$4 = NULL, *_9$$4;
    zval *name = NULL;

    ZEPHIR_MM_GROW();
    zephir_fetch_params(1, 2, 0, &name_param, &callback);

    if (unlikely(Z_TYPE_P(name_param) != IS_STRING && Z_TYPE_P(name_param) != IS_NULL)) {
        zephir_throw_exception_string(spl_ce_InvalidArgumentException, SL("Parameter 'name' must be a string") TSRMLS_CC);
        RETURN_MM_NULL();
    }
    if (likely(Z_TYPE_P(name_param) == IS_STRING)) {
        zephir_get_strval(name, name_param);
    } else {
        ZEPHIR_INIT_VAR(name);
        ZVAL_EMPTY_STRING(name);
    }

    _0 = (Z_TYPE_P(callback) == IS_OBJECT);
    if (_0) {
        _0 = (zephir_instance_of_ev(callback, zend_ce_closure TSRMLS_CC));
    }
    if (_0) {
        _4$$3 = zephir_fetch_nproperty_this(this_ptr, SL("__self"), PH_NOISY_CC);
        ZEPHIR_INIT_VAR(_5$$3);
        ZVAL_NULL(_5$$3);
        ZEPHIR_CALL_CE_STATIC(&_2$$3, delphi_core_ce, "w_setevent", &_3, 14, _4$$3, name, _5$$3, callback);
        zephir_check_call_status();
        ZEPHIR_RETURN_CALL_CE_STATIC(delphi_core_ce, "processresult", &_1, 13, _2$$3);
        zephir_check_call_status();
        RETURN_MM();
    }
    _6 = (Z_TYPE_P(callback) == IS_ARRAY);
    if (_6) {
        ZEPHIR_OBS_VAR(object_var);
        _6 = (zephir_array_isset_long_fetch(&object_var, callback, 0, 0 TSRMLS_CC));
    }
    _7 = _6;
    if (_7) {
        ZEPHIR_OBS_VAR(method_var);
        _7 = (zephir_array_isset_long_fetch(&method_var, callback, 1, 0 TSRMLS_CC));
    }
    if (_7) {
        _9$$4 = zephir_fetch_nproperty_this(this_ptr, SL("__self"), PH_NOISY_CC);
        ZEPHIR_CALL_CE_STATIC(&_8$$4, delphi_core_ce, "w_setevent", &_3, 14, _9$$4, name, object_var, method_var);
        zephir_check_call_status();
        ZEPHIR_RETURN_CALL_CE_STATIC(delphi_core_ce, "processresult", &_1, 13, _8$$4);
        zephir_check_call_status();
        RETURN_MM();
    }
    ZEPHIR_THROW_EXCEPTION_DEBUG_STR(zend_exception_get_default(TSRMLS_C), "Incorrect parameters passed to setEvent", "delphi/_Object.zep", 146);
    return;

}

Ах да, яж те самое главное не сказал, я с зефира начал не сразу, сперва я писал на чистом php sdk, тык вот, я 8 месяцев писал, написал порядка 200 килобайт исходного кода. Закопался в мемликах, багах, в общем ппц. А потом я познакомился с зефир. Я за полтора месяца на зефире переписал с нуля всё что было написано за 8 месяцев!, а также написал много чего ещё нового функционала, чего не было в первой версии, например автоматизировал кучу задач по регистрации событий и прочего. Например если ты посмотришь DS, там для каждого класса delphi в DS есть аналог с просто куууучей логики и методов. У меня они тоже есть, пишутся автоматически и все выглядят так:

namespace Delphi\Vcl\Grids;

use Delphi\_Object;
use Delphi\Core;

class TCustomDrawGrid extends \Delphi\Vcl\Grids\TCustomGrid
{
    public      $qualified_class_name   = "Vcl.Grids.TCustomDrawGrid";
    protected   $__class_name           = "Vcl.Grids.TCustomDrawGrid";
    const       __class_name            = "Vcl.Grids.TCustomDrawGrid";
} 
namespace Delphi\Vcl\Grids;

use Delphi\_Object;
use Delphi\Core;

class TDrawGrid extends \Delphi\Vcl\Grids\TCustomDrawGrid
{
    public      $qualified_class_name   = "Vcl.Grids.TDrawGrid";
    protected   $__class_name           = "Vcl.Grids.TDrawGrid";
    const       __class_name            = "Vcl.Grids.TDrawGrid";
} 

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

3. Учитывая, что там будет некий неприятный вид связки

Он вовсе не неприятный, а наоборот. Учитывая то, что для того чтоб это всё работало и не пришлось на делфи изобретать велосипед как это было сделано в php4delphi, я по сути всю работу с пхп перенём в сам пхп. У меня было порядка 20 процедур всего, которые занимались обменом данных между php-delphi. Визуальная часть выполнялась на стороне delphi, а классы и объекты пхп были на стороне зефира. Они друг другу просто "говорили что нужно сделать" и каждый делал это на своей стороне. Это в разы уменьшило количество кода и багов, как на стороне делфи так и на пхп.

3. C++ -> C (Zephyr) <-> Delphi?

Ты видимо не понял. Зефир это по сути транспиллер. Он берёт маленький удобный код, написанный на его "птичьем языке", который очень на php похож и распарсив логику, переводит его в нативный сишный код на котором написан сам пхп. Далее это всё собирается через MS VS в php5ts.dll в котором кроме стд классов пхп оказываются ещё и твои классы.

Не лучши ли C++ <-> Delphi? 8 месяцев VS 1.5

3. Или учитывая, что delphi базируется на C, данное решение является более безопасным?

ЧЕго? На object pascal оно базируется.

3. P.s пробовали на зефире собирать - нашли пару уязвимостей в плане декомпиляции.

Это какие же? :-D

Вообще любой опыт от Dim-S отличный пример того, как не нужно делать,

Не соглашусь.

Вау, хороший пример, видно, что работы не мало было проделано,

Полтора месяца. После первого, не удачного 8 месячного опыта правда.

немного непонятно мне по структуре обращение к компонентам

А что там не понятного, логика полностью из делфи. У меня там всё на магических методах сделано. Если создаёшь класс скажем \Delphi\Vcl\Grids\TCustomDrawGrid Он берёт CLASS, распарсивет эту строку заменяя слеши на точки, вырезав префикс делфи, получается "Vcl.Grids.TCustomDrawGrid" и шлёт в делфи вызов создай объект класса "Vcl.Grids.TCustomDrawGrid", на стороне делфи метод createClass принимает и через rtti создаёт что просят. Тоже самое везде, при обращении к свойствам, вызовах методов и прочего, Везде на стороне php "волшебные методы" которые формирую строковые представления того что где и как надо вызвать, плюс несколько методов кастинга параметров и типов данных

vGhost2000 commented 5 years ago
Он берёт __CLASS__, распарсивет...

гитхаб порушил смысл подчёркиваний :)

vGhost2000 commented 5 years ago

А ну да, первый вариант как уже говорил 200 килобайт кода, на зефире 30 килобайт в которых вся старая логика, плюс много новой!

ghost commented 5 years ago

А зачем? Я вот сейчас на php5 писать ничего не стал бы. Т.е. пользоваться DS этой как следствие тоже. Смысл тратить время на то что уже не кому не надо какой? Если хочешь сделать что то полезное, начинать надо с php 7.2

Тю, много текста, можно короче ведь: 1) Динамика основана на RTTI, зефир тут не при чём, у нас под студию такая-же реализация, но тут вопрос насчёт конвертирования типов, оно ведь с заморочками идёт - через RTTI не получить никак массив с установленной длинной и процедурный тип никак не передать, в том числе указатели, их через костыли - integer( Pointer * ), разве что так... 2) Так и не добавили поддержку линукса, в релизных версиях как не было, так и нет, вот так то... 3) "Ты видимо не понял. Зефир это по сути транспиллер. Он берёт маленький удобный код, написанный на его "птичьем языке", который очень на php похож и распарсив логику, переводит его в нативный сишный код на котором написан сам пхп. Далее это всё собирается через MS VS в php5ts.dll в котором кроме стд классов пхп оказываются ещё и твои классы." а чем это отличается от того, что я написал? по сути то-же самое. вместо двух составляющих получаем три, лучше, чем реализация в DS, но хуже, чем реализация без зефира. 4) насчёт неприятности - всё-же речь идёт не о сравнении с php4delphi, он даже peachpie'йу проигрывает, слишком много WinAPI, слишком много повторного конвертирования. улитка

Уязвимости - движок (HyperBlank) почти весь виден через олю, можно что нужно повытягивать из проекта, понятное дело не в виде голых исходников, но всё равно итог неприятный, так же ресурсы видны, в qt они шифруются как-то по хитрому, может это выделывание.

ghost commented 5 years ago

Вообще любой опыт от Dim-S отличный пример того, как не нужно делать,

Не соглашусь.

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

vGhost2000 commented 5 years ago

зефир тут не при чём

Очень причём, на php там тоже динамика, если в статике класса нет скомпиленного он его динамически создаёт в памяти. Описать все классы в Delphi ты не опишешь. Но даже если опишешь, кто то поставил в делфи себе SynEdit и хочет его заюзать, в твоей либе нет на стороне пхп этих классов. Динамика на RTTI обрабатывается на стороне php тоже динамикой.

  1. через RTTI не получить никак массив с установленной длинной и процедурный тип никак не передать, в том числе указатели, их через костыли - integer( Pointer * ), разве что так...

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

Так и не добавили поддержку линукса, в релизных версиях как не было, так и нет, вот так то...

Да не страшно, можно доставить отдельно

а чем это отличается от того, что я написал? по сути то-же самое.

Я не настаиваю, просто делюсь личным опытом. Я в итоге пришёл к этому решению не просто так.

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

Аа, ты про DS. Это да. Тут даже bcompiler не спасает. Я писал проектик который инжектит в php5ts.dll в реальном времени свою dll'ку которая переопределяет процедуры php отвечающие за исполнение кода, вытягивает из него массив опкодов и превращает их в пхп код обратно. Это работает с любыми подобными продуктами (ZendENcoder и т.д. не помню остальных названия уже). А вот в случае с зефиром, как раз таки такого не случится, потому что там нет по факту никакого php кода. Там сишный код и вытянуть исходник ты уже не вытянешь. Ты можешь скорректировать поведение программы - взломать. Но исходник получить не выйдет. В этом самое большое преимущество зефира!

понятное дело не в виде голых исходников,

Да вот как раз нет, в DS вытягиваются и они тоже, видео даже где то валяется в файлопомойке, но чёт найти не могу, видимо в каком то архиве уже, по этому не ищется.

в qt они шифруются как-то по хитрому, может это выделывание.

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

Ну да, расположение табов/доков в главном окне - хороший пример,

Я не про то, я про во первых саму идею. Во вторых имея готовый пример ты можешь многому научиться на чужих ошибках, не делая их сам. Для меня изучение DS стало очень полезным опытом. Сперва я в принципе научился на его примере что есть RTTI, потом уже только пошёл дальше. До этого про RTTI я не слухом не духом, даже не знал с какой стороны к ней подойти.

ghost commented 5 years ago

зефир тут не при чём

Очень причём, на php там тоже динамика, если в статике класса нет скомпиленного он его динамически создаёт в памяти. Описать все классы в Delphi ты не опишешь. Но даже если опишешь, кто то поставил в делфи себе SynEdit и хочет его заюзать, в твоей либе нет на стороне пхп этих классов. Динамика на RTTI обрабатывается на стороне php тоже динамикой.

SPL? Мы через него классы из use хватаем :) Вполне хорошая практика) Ааа, всё понял, с зефиром что-то, он умеет классы искать используемые? Круто

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

Ага, но я про костыли не спрашивал, если идти в костыли, то можно и TObject в RTTI регистрировать, но об этом лучше отдельно) Впринципе те массивы можно через функции Get(index:integer) и Set(index:integer;value:TVarRec) редактировать)

понятное дело не в виде голых исходников, Да вот как раз нет, в DS вытягиваются и они тоже, видео даже где то валяется в файлопомойке, но чёт найти не могу, видимо в каком то архиве уже, по этому не ищется.

Простите, сейчас отредактирую ответ выше, речь шла о HyperBlank(тоже движок) Насчёт DS - там можно по файлу compile,php выстроить обратную логику и вот уже "дикампилятар ат мастера пхп-3000", XOR так же легко дешифруется как и любой "протектор" на ds, но у меня ума или сообразительности не хватило обойти виртуализацию

vGhost2000 commented 5 years ago

SPL? Мы через него классы из use хватаем :) Вполне хорошая практика) Ааа, всё понял, с зефиром что-то, он умеет классы искать используемые? Круто

Нет, сам зефир ничего автоматом не создаёт, я видимо плохо умею объяснять и выражать мысли, есть у меня такой недостаток. Я просто в дев версию внедрил специальный код, который 1) налету создаёт класс в пхп если его нет в dll при первом обращении к нему, в реальтайме во время выполнения проекта. 2) в моей папке с исходниками проекта пишет zep файл с этим классом, и при следующей перекомпиляции он есть уже статично в dll. Не в dev версии я оставлял только пункт 1 что делало проект юзабельным у других даже если каких то delphi компонентов у меня нет на моей системе на которой была создана сборка php расширения.

Впринципе те массивы можно через функции Get(index:integer) и Set(index:integer;value:TVarRec) редактировать)

я так делал

function pZvalToTValue(z: pzval; silentWrongType: boolean; TSRMLS_DC: Pointer): TValue;
var
  data: ^ppzval;
  param_obj: TObject;
  tempstr: RawByteString;
  oid, I: integer;
  arrayOfTV: TArray<TValue>;
begin
  case z^._type of
    IS_NULL           : result := nil;
    IS_LONG           : result := zint(z);
    IS_DOUBLE         : result := zdouble(z);
    IS_BOOL           : result := zbool(z);
    IS_STRING         : result := zstr(z);
    IS_RESOURCE       : raise Exception.Create('IS_RESOURCE not implemented');
    IS_CONSTANT       : raise Exception.Create('IS_CONSTANT not implemented');
    IS_CONSTANT_ARRAY : raise Exception.Create('IS_CONSTANT_ARRAY not implemented');
    IS_ARRAY          : begin
      SetLength(arrayOfTV, z^.value.ht.nNumOfElements);
      for I := z^.value.ht.nNumOfElements - 1 downto 0 do
        arrayOfTV[I] := pZvalToTValue(dw_get_array_element(z, I, TSRMLS_DC), silentWrongType, TSRMLS_DC);
      result := TValue.From(arrayOfTV);
    end;
    IS_OBJECT         : begin
      // объект не наследник враппера, т.е. чистый пышный объект и на стороне делфи ничего нет.
      oid := dw_get_object_id(z, TSRMLS_DC);
      if oid = 0 then begin
        result := TValue.From(z);
        exit;
      end;

      param_obj := TObject(oid);
      if param_obj.InheritsFrom(TClassReference) then
        result := (param_obj as TClassReference).Val
      else if param_obj.InheritsFrom(TRecord) then
        result := (param_obj as TRecord).FVal
      else
        result := param_obj;
    end
  else
    if not(silentWrongType) then
      raise EErrorZvalType.Create('Undefined zval._type = ' + inttostr(z._type));
  end;
end;

Где dw_get_array_element:

function dw_get_array_element (arrayVar: pzval; index: integer; TSRMLS_DC: pointer): pzval; cdecl; external 'php5ts.dll';

А в пхп:

zval * dw_get_array_element(zval * params, int index TSRMLS_DC)
{
    zval *result;

/* и вот этой строкой я описал кучу логики работы с памятью, выделением
освобождением, получением элемета и т.д. примерно строк 20 кода благодаря 
тому что есть зефир */
    zephir_array_fetch_long(&result, params, index, PH_NOISY | PH_READONLY, "delphi/Core.zep", 120 TSRMLS_CC);

    return result;
}
ghost commented 5 years ago

@vGhost2000 Сделал #8 #6 #5 Вот так-та

vGhost2000 commented 5 years ago

Вот, кстати, ещё, посмотри:-) https://github.com/krakjoe/ui

ghost commented 5 years ago

Вот, кстати, ещё, посмотри:-) https://github.com/krakjoe/ui

У меня уже в принципе от начала совсем другое представление о костылях, по идее это всё можно склеить. И php на си написан, и delphi pascal под базис си берёт (вставки кода на си (-файлов) иначе б не поддерживал) и зефир на си транслирует. Значит это всё можно совместить, убрав использование API до максимального минимума, и вклеивая либо весь код сразу в код php, с исправлением типа приложения от библиотеки на standalone-приложение/desktop-/console-, либо вклеивая конечный код в код программы на lazarus/d, используя вставки. Такое представление у меня было чуть ранее, ещё когда взглянул на PQ, и понял, что форма поставки дс - вообще мусор, решил просто не обсуждать пока своё что-то не накостыляю. В итоге две недельки писал конвертер, и понял что всё-же второй вариант возможен, если над ним поработать, насчёт первого я не уверен, т.к всё же как-то компиляцию php переписывать придётся, а это ещё больше работы, как для того, кто вообще от программирования на си далёк

ghost commented 5 years ago

Вот, кстати, ещё, посмотри:-) https://github.com/krakjoe/ui

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

ghost commented 5 years ago

А стоит ли на 5.6 мигрировать то? Может если делать то сразу 7.2+ ???

Делал я такое, даже сделал. И вроде работало :-) Потом в итоге я это всё забросил. Потому что php 5.x.x уже безнадёжно устарел. Первое что придётся сделать, выпилить нафиг php4delphi и написать собственный аналог. С php5.6 он работать вообще не будет. Совсем. Там (в пхп) слишком много изменений которые ломают обратно совместимую логику с php4delphi. Вообще сам по себе php4delphi ужасен. Там просто ппц сколько много всего лишнего и не нужного. Быстро это всё работать не будет. Если делать что то такое, то:

  1. начать с нуля. DS устарел и содержит кучу пхп кода который мягко говоря не айс. Структура проекта модулей, прочего, в общем не хочу обижать Диму и промолчу. В своё время это было круто, но на дворе 2019.
  2. Начинать надо на Embarcadero Delphi 10.2 не ниже. Лучше выше. Почему 10.2+? Потому что там появились FireMonkey визуальные компоненты позволяющие писать кросс платформенные приложения. Мне удалось скомпилить и запустить php gui приложение на винде и андроиде. На линуксе тоже скорей всего завелось бы, просто лицензии не было.
  3. PHP часть модуля писать на zephir https://zephir-lang.com/ это резко ускорит разработку и позволит в итоге писать программы которые нельзя будет декомпилировать. К тому же использование зефира позволит делать вставки сишного кода и вызывать любые winapi процедуры которыми не обладает не DS, не PHP, примеры того как я чутка подкорректировал PHP код самой DS и что из этого вышло: http://home.vghost.me/numlock%20winapi%20demo%20app.htm http://home.vghost.me/ScreeenShotDemo.htm http://home.vghost.me/ScreenShotDCDemo.htm
  4. написать транслятор php->zephir->c->байткод.
  5. оформить расширение для delphi где это всё будет автоматизированно чтоб не изобретать собственную иде долго и упорно, а пользоваться готовой.

У меня в итоге всё затухло вот на этой стадии: http://home.vghost.me/fistdemo.htm К этому моменту вышел php7.1 и продолжать разработку на php 5.6 было глупо. А переписывать 50% интеграции с php на версию 7 было уже и лень, да и на работе озадачили вторым проектом, так что времени уже совсем не осталось и я забил.

Весь концепт такое себе. Вот концепт лучше Минус Delphi (она устарела, Лазарус уже бодрее и лучше неё в почти всех планах стал, сейчас части орг. и бизнес - логики не хватает лишь) PHP-код => zephyr => src [c] PHP-src => parser => main [c + h] files Main [c + h] files + src [c] => program patch Lazarus base src + program patch => end-point program.