Создание EXE приложений на PHP

    INTRO

    Все мы знаем что PHP предназначен для быстрого создания динамических Web страниц. Во всяком случае именно это написано на официальном сайте разработчиков PHP. Однако почему бы не попробовать найти PHP «немного» иное применение, например, попробовать создать полноценное приложение для Windows? Заинтересовал? Тогда понеслась!

    Чёрный квадрат

    Приложения делятся на консольные и оконные. Начнём с создания первых, так как это проще. Итак, для начала нужно определиться с тем, что мы будем писать… я предлагаю написать простой MD5 & Base64 Encoder — вещь в хозяйстве нужная и полезная, тем более здесь всё достаточно просто. Для запуска PHP скрипта из командной строки и передачи ему нужных параметров используется следующая конструкция:
    php.exe [опции] [-f] <наш скрипт> [параметры]

    Что касается содержания самого скрипта, то количество переданных параметров хранится в переменной $argc, а сами параметры хранятся в массиве $argv. На этом краткий инструктаж по консольным приложениям закончен и пришла пора приступить к активным действиям.

    Чтобы не утруждать Вас написанием скрипта, я решил написать его за Вас. Вот что у меня
    получилось:

    <?php
    if($argc!=3) { echo "
    +--------------------------------------+
    | Create MD5 hash: enc md5 string |
    | Create Base64 hash: enc b64 string |
    +--------------------------------------+\n";
    } else {
    echo "\n";
    if($argv[1]=='md5') { // MD5 encode
    echo md5($argv[2])."\n\n"; die();
    }
    if($argv[1]=='b64') { // Base64 encode
    echo base64_encode($argv[2])."\n\n"; die();
    } else { echo «Unknown command. Type \»enc\" for help.\n\n"; }
    }
    ?>

    <img src=«habrastorage.org/getpro/habr/olpictures/cf6/1d1/61b/cf61d161b4a795fc4c658d661d96fdae.gif» width=450 height=186 border=0 alt=Демонстрация работы скрипта" hspace=10 vspace=10>

    Скрипт написан и теперь самое интересное — компиляция в EXE приложение. Для компиляции консольных приложений я использую Roadsend Compiler Studio. Его можно скачать на сайте www.roadsend.com после бесплатной регистрации. Скачали? Теперь открываем Roadsend IDE, создаём новый проект (Project -> New), прописываем необходимые параметры (наш скрипт рекомендую кинуть именно в директорию проекта), жмём «OK» и наконец даём заветное Project -> Build. Теперь направляемся в папку с проектом и если Вы всё правильно сделали — в ней Вы найдёте готовый EXE. Это всё? Да. Всё просто, если знать некоторые нюансы. Единственное что я рекомендовал бы — иногда полезно пошаманить с подключаемыми библиотеками, а так же можно упаковать наш EXE UPX`м, хотя эту тему я затрону чуть ниже. Теперь перейдём к оконным приложениям…

    Окошки

    Как Вы наверное уже догадались — при создании оконных приложений штатными средствами PHP уже не обойтись, поэтому для начала нужно выбрать инструмент для разработки нашего окошка. Среди всех инструментов больше всего выделяются два — это достаточно раскрученый PHP-GTK (www.gtk.php.net) и менее раскрученный, но не менее функциональный WinBlider (www.winbinder.org). Здесь как раз тот случай, когда более раскрученный и известный оказывается не так уж и хорош (это моё имхо), поэтому для разработки нашей первой форточки на PHP мы будем использовать WinBlinder. Для начала его нужно скачать. Готово? Окей, двигаемся дальше…

    Винблиндер имеет свой собственный формат данных — phpw, который Вы можете сразу смело привязывать к вашему любимому редактору кода. По умолчанию при запуске phpw файла открывается содержащийся в нём PHP скрипт и прогоняется через интерпретатор с уже подключеными библиотеками блиндера. Как Вы наверное поняли — учится программировать на этой балалайке Вам придётся самим, однако в это нет ничего сложного, особенно человеку хоть немного знакомому с ООП в PHP. Однако даже незнакомый тоже сможет на нём кодить, так как по сути блиндер (в отличии от PHP-GTK) поддерживает и процедурное программирование. Кроме того WinBlinder весьма неплохо документирован, а инсталл архив уже содержит в себе несколько весьма любопытных примеров (особое внимание прошу обратить на редактор форм). У блиндера есть ещё куча фишек, функций и интересностей, но рамки данной статьи не позволяют мне на них останавливаться. Теперь пожалуй самое подходящее время вспомнить о нашем кодере. Чтобы не перегружать всё кодом я решил написать лишь MD5 Encoder:

    <?php
    // Подключаем основную библиотеку
    include «include/winbinder.php»;

    // Даём метки окнам редактирования
    define('IDC_EDITBOX1002', 1002);
    define('IDC_EDITBOX1003', 1003);

    // Рисуем окошко
    $winmain = wb_create_window(null,
    AppWindow,
    'MD5 Hash Generator by S1B [SBT]',
    WBC_CENTER, WBC_CENTER, 315, 134,
    0x00000000, 0);

    // Шпигуем окошко кнопками

    # Рисуем рамочку
    wb_create_control($winmain, Frame, '', 10, 10, 290, 85, 0, 0x00000000, 0, 0);
    # Рисуем надписи (лейблы)
    wb_create_control($winmain, Label, 'Текст:', 23, 35, 45, 15, 0, 0x00000000, 0, 0);
    wb_create_control($winmain, Label, 'Hash:', 23, 65, 45, 15, 0, 0x00000000, 0, 0);
    # Рисуем окошки редактирования (нижнее будет неактивным), и загоняем их данные в переменные
    $text=wb_create_control($winmain, EditBox, '', 78, 30, 210, 20, IDC_EDITBOX1002, 0x00000000, 0, 0);
    $hash=wb_create_control($winmain, EditBox, '', 78, 60, 210, 20, IDC_EDITBOX1003, 0x00000040, 0, 0);

    // Две необходимые надписи =)
    wb_set_handler($winmain, «process_main»);
    wb_main_loop();

    function process_main($window,$id) {
    # Объявляем данные окошек редактирования глобальными
    global $text,$hash;
    switch($id) {
    case IDC_EDITBOX1002:
    wb_set_text($hash,md5(wb_get_text($text)));
    break;
    case IDCLOSE:
    wb_destroy_window($window);
    break;
    }
    }
    ?>

    Код достаточно прост и думаю посидев с документацией 1-2 часа Вы начнёте разбираться в нём так же, как и я. Ну а теперь кульминация — собираем форточку… Для этого предлагаю создать отдельную директорию и перенести наш скрипт туда. Так же нужно перенести туда папку include из phpcode директории винблиндера. Готово? Теперь компилируем! Эээ… стоп не нужно хвататься за Roadsend IDE. Как? А вот так! Он не поддерживает блиндер, а поддерживает только GTK, причём судя по туманным ответам разработчиков Roadsend на их форуме — поддержку блиндера можно ещё долго ждать. Однако вытрем сопли, и будем искать другие пути, и имя этим путям Bamcompile (www.bambalam.se/bamcompile/). Однако по каким-то причинам версия 1.21 не всегда верно работает и иногда компилирует всё в неработающее приложение, однако версия 1.1 такими глюками не страдает, поэтому рекомендую использовать её. Теперь щедро выделяем для нашего компилятора отдельную папку, заходим в командную строку и гордо командуем:
    bambalam -w -c C:\PHP_Projects\MD5_Hash_Generator\ md5.phpw md5.exe

    Процесс компиляции

    Если всё сделано правильно, то в директории с компилятором будет лежать свежесколоченое оконное приложение. Всё. Добавлю лишь, что все приложения я ещё рекомендовал бы упаковывать UPX`ом (который идёт сразу с Bamcompile).

    Наше приложение

    Волшебный ларец

    Все вышесказанное конечно весьма интересне и познавательно, однако бывают моменты когда нужных инструментов под рукой нет… Что делать тогда? Специально для такого случая есть один весьма любопытный приём получения EXE через шаманство в опциях SFX архива WinRAR. В качестве примера я буду использовать наш первый скрипт для консоли. Для начала помещаем наш скрипт в отдельную папку, туда же копируем php.exe и php*ts.dll. Далее создаём в этой же папке run.bat следующего содержания:

    @echo off
    php.exe -q console.php %1 %2


    Теперь нам необходимо это добро упаковать, для этого выделяем все файлы, жмём правой кнопкой и выбираем «Add to archive...».



    В появившемся окне выбираем формат архива RAR, выставляем максимальное сжатие и ставим галочку «Create SFX archive».



    После этого переходим во складку «Advanced -> SFX Options», там выставляем переключатель на «Create in curent folder» и в «Run after extraction» прописываем «run.bat», а так же во вкладке «Modes» выставляем галочку «Unpack to temporary folder», а так же выставляем переключатели «Hide all» и «Overwrite all files».



    По вкусу можете прилепить свою иконку в соответвующей вкладке. Теперь подтверждаем создание архива и на выходе получаем EXE без всяких компиляторов.

    OUTRO

    Итак, сегодня я показал Вам, как легко и просто можно раздвинуть границы использования PHP. Конечно кто-то всё это назовёт бредом, скажет мол размер у приложений большой, и память у них течет, и муторно всё это. Пусть говорят, однако никто не призывает Вас писать все оконные приложения на PHP, а данная статья лишь неплохое подспорье для пхп кодеров и всех интересующихся. На сим я закончу. Удачи.
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 66
      +11
      жесть :)
      • НЛО прилетело и опубликовало эту надпись здесь
          +2
          учту на будущее ;)
          0
          А я так писал парсер xml-файлов и это действительно жесть :) Basic отдыхает :)
          0
          Кросавчег! Давно хотел найти подобное описание с примером.
            0
            Регулярно использую PHP в Linux. Причем, как в оконном режиме (PHP-GTK), так и в консольном.

            Компиляция, я так понял, для распространения приложений, исходный код которых не хотелось бы раскрывать? Надо ли такие приложения на PHP писать?
              0
              см. OUTRO
                +1
                Гугл по данной фразе ничего интересного не выдает. Может поделитесь ссылкой?
                  +1
                  Вот это действительно жесть! =)))
                    0
                    угу
                  +2
                  Понял о чем вы)))
                0
                Если скрипты должны работать и на PHP < 4.3.0, то надо использовать $_SERVER['argv'] и $_SERVER['argc'] вместо $argv и $argc

                http://php.net/manual/ru/features.commandline.php
                Начиная с PHP 4.3.0, при использовании CLI SAPI переменные $argc и and $argv зарегистрированы и заполнены соответствующими значениями. В более ранних версиях создание этих переменных, так же, как и для CGI или модуля веб-сервера, требует значение on директивы register_globals. Независимо от версии PHP или статуса опции register_global они всегда доступны как элементы массива $_SERVER или $HTTP_SERVER_VARS. Например: $_SERVER['argv']
                  0
                  да, не учёл. Однако сейчас мало кто использует PHP 4.3.0 :)
                    0
                    когда делаешь кастомное приложение, то можно смело забить.
                    но, когда делаешь боксовый скрипт, то лучше перестраховаться.
                  0
                  А не пробовал ли кто запускать этот exe`шник через апачку как cgi?

                  Будет ускорение работы?
                    +3
                    А если не секрет, а зачем? ;)
                      0
                      Для особо понятливых - читаем OUTRO, оно написано для того чтобы таких вопросов не возникало.
                      0
                      Можно еще топором ложку выстругать :-)
                        0
                        Ложкой хотя бы есть можно
                        0
                        Пару лет назад это было бы очень полезно. =)
                        Тогда кроме PHP ни на чем не говорил.
                          +1
                          А я это видел здесь. Причём давно.
                            +1
                            на автора посмотрите :)
                            просто я решил вуступление на хабре с этой статьи начать
                            0
                            Мне кажется решение предложенное автором заслуживает внимание как минимум за то, что оно работает.

                            Я бы только под 7z это завернул (если там есть запуск файла после распаковки, надо проверить :) ), или под что-нибудь другое не требующее денег :) RAR не айс как по мне :)
                              0
                              Есть в 7z возможность запускать файлы, если пользоваться не обычным SFX модулем, а модулем для установок http://forum.oszone.net/showthread.php?t…
                              +5
                              Надеюсь все понимают, что PHP-код в машинные команды не переводится, а получившийся экзешник, это упакованный интерпретатор и байт-код сценария?
                                +1
                                "Roadsend PHP is a free, open source implementation of the PHP language. It includes a compiler that produces native binaries (no interpreter required)."
                                0
                                PHP я люблю, и даже год назад на PHP 5.1.? пробовал написать OpenGL приложение с помощью своего же модуля к GLFW. По началу все получалось, но потом заглянув в диспетчер задач и увидев как PHP медленно, но верно пожирает память, не высвобождая ресурсы, отказался от этой затеи. unset(..) не помогал, да и что это за дело, когда в конце каждой функции надо делать unset'ы. Возможно в PHP 5.2 с этим уже намного лучше или я упустил включение в настройках какого-то параметра.
                                Фанатам осталось сделать модуль к графическому движку (Ogre, Irrlicht и пр.) и тогда будет у нас отличный боекомплект для разработки игр :)
                                  –1
                                  Ты гонишь =)
                                    0
                                    Хм, в интернете можно легко найти исходники другого модуля GLUT - можете опробовать на нем и убедиться сами.
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    0
                                    К чему вы это говорите в данной теме?
                                    Очередное начало холивара в стиле, "а вот я слышал от знакомого?"
                                    По этим словам единственное что можно заключить — ваш знакомый, э..., очень сильно начинающий, так сказать, в PHP.
                                    –1
                                    ухты, пятиколесный велосипед
                                      0
                                      А где же int main(void) {} ?
                                      Шутка :-D

                                      На самом деле полезно, давно хотел попробовать, а теперь даже гуглить не надо. Спасибо!
                                        0
                                        int main(int argc, char **argv){} и это не шутка!
                                        шутка :)
                                        0
                                        Я конечно видел php-gtk. Но чтоб на винде. Это жесткая жесть ребята…
                                          0
                                          ага. это мегажесть. теперь буду пробовать создавать окошки на HTML =D
                                            +1
                                            Откройте для себя XUL и HTA :)
                                              0
                                              и опять таки gtk....
                                          0
                                          да, о таком я даже не думал, большое спасибо за информацию, сейчас буду экспереминтировать!
                                            0
                                            WinBlider
                                            WinBlinder
                                            Винблиндер

                                            Судя по имени сайта (http://www.winbinder.org), правильнее будут "WinBinder" и "Винбиндер".
                                              0
                                              видимо прилетало НЛО и ставило букву "l" во время написания статьи ;)
                                                0
                                                А, ну если так, то можно не исправлять. НЛО знает об истинных именах лучше нас :)
                                              0
                                              А какой размер то вышел у бинарников? а то не напиано, а жаль.
                                                0
                                                500 килобайт :) это уже жатый UPX. Для тех кому "дык это же афигеть как много" - читаем OUTRO :)
                                                0
                                                Спасибо за статью.
                                                Есть некоторые мелкие вещи реализованиые на пхп, и лениво их переписывать на чем-то еще.
                                                Может пригодится в условиях отсутствия инета и соответственно невозможности использовать залитый на хостинг легкий скрипт и нежелание ставить пхп-апач на машину. А поверьте такое нередко бывает. Бум пользоваться..
                                                  0
                                                  Во имя Патрика! Что за маразм?
                                                  Я читал OUTRO, но Вы можете мне объяснить, где ЭТО может действительно понадобиться?
                                                    0
                                                    ЭТО может понадобится тем кто вот нифига не смыслит ни в чём кроме PHP, не хочет / не имеет времени изучить другой язык программирования, но безумно хочет выйти за пределы браузер и написать оконное приложение. вот так

                                                    хотя печёнкой чую, что ответ Вас не удовлетворит ))
                                                      0
                                                      Да, да. Что люди не придумают, лишь бы не знать Java, которая не только JSP, но и консольная, и серверная, и 3D, и... платформо-независима. :)
                                                        0
                                                        вы дорогой, очень похожи на любителя, забивать гвозди микроскопами. :)
                                                        Java это не панацея.. Да и учить ее для парочки простеньких скриптов, на мой взгляд, весьма бессмысленно.
                                                      0
                                                      По-моему очень полезно когда надо быстро сделать что-то банальное, а скорость и объемы не важны.
                                                      0
                                                      Офигеть.

                                                      Автор только что продемонстрировал как можно вытирать задницу наждачной бумагой.
                                                        0
                                                        Даааа, большего бреда никогда не видел. И эти люди потом считают себя программистами. Написать скрипт на пхп я еще понимаю, но компилить из него бинарь - маразм.

                                                        ЭТО может понадобится тем кто вот нифига не смыслит ни в чём кроме PHP, не хочет / не имеет времени изучить другой язык программирования, но безумно хочет выйти за пределы браузер и написать оконное приложение.

                                                        Не правда ли похоже на онанизм?
                                                          0
                                                          нет, не похоже. Онанизм не дает результата, PHP - дает.
                                                          0
                                                          оба сообщения написаны одним и тем же троллем... уж больно синхронно регистрируетесь и пишите :/
                                                            0
                                                            Да, с логикой тоже все плохо :)
                                                            это Иркутск так плохо влияет? А, товарисчь эксперт, с неадекватной самооценкой и с поломаным всеми кому не лень секбуном :))))
                                                              0
                                                              да у тя просто не всё в порядке, иначе какой смысл гадить без причин и инкогнито?
                                                            –1
                                                            Офигенно, ребята, просто офигенно. :)

                                                            Свалился со стула и долго приходил в себя. Большой плюс автору за научный подход, большой плюс тому, кто это сюда закинул, за то, что он это сделал. Утро начинается с веселого, что называется. :) Ждём статей "Программирование библиотек для gcpp на Ms Visual Basic", и "Написание Windows-приложений средставами языка PL/M"... Спасибо, автору респект! :)
                                                              0
                                                              Судя по полетевшим минусам в карму, кажется, моей доброй иронии не оценили... о_О
                                                                0
                                                                блин, я поражаюсь некоторым людям. Русским языком интро и аутро написано вроде, а всё равно мало - обязательно нужно что-то ляпнуть. Разметил я и автор я, надеюсь тебя это успокоит и будет тебе совсем хорошо!
                                                                  0
                                                                  Вы меня совершенно не поняли. Я внимательно прочитал и интро и аутро, и прекрасно понял, зачем этот пост был написан. Наоборот, я высказался в том духе, что мне очень понравилось, я понимаю, что день был тяжелый, но вы прочтите повнимательнее. :) ПыСы: при всём уважении, мы с вами на брудершафт не пили... :)
                                                              –1
                                                              Уберите это из веб-разработки в блог РНР. Или в юмор :)
                                                                0
                                                                Как мой комментарий попал на самый верх?!!!!!!!!!!!!!
                                                                  +1
                                                                  Кто-то считает написание консолек и окошек на РНР веб-разработкой?
                                                                0
                                                                и что, данный exe легко переносится на машину без PHP?
                                                                  +1
                                                                  забавно, но это именно то, от чего просил воздержаться сам автор РНР :)
                                                                  Если не изменяет память — первая же заповедь разработчика на РНР звучит примерно так:
                                                                  «не надо пихать РНР куда ни попадя, он предназначен ТОЛЬКО для веб-страниц»

                                                                  Но пример интересный, безусловно :)
                                                                  спасибо

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

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