Pull to refresh

Comments 34

Что только не придумают, чтоб на плюсах не писать! =)
Плюс php из коробки много удобных функций на все случаи жизни. И для написания достаточно мануала.
Минус же плюса, это чтобы начать писать что-то полезное нужно иметь больший опыт, да и одним мануалом тут не отделаешся.

Вопрос по решению, сколько потребляют ресурсов приложения? Ну и да весом приложением мы пренебрегем :)
У плюсов есть фатальный недостаток — чтобы программировать на плюсах нужно уметь программировать.
Не совсем так.

Чтобы программировать на плюсах нужно уметь программировать на плюсах. Умение программировать «вообще» только отчасти облегчает задачу. Примерно так же, как умение программировать на плюсах облегчает задачу программирования на Haskell каком-нибудь.

Их фатальный недостаток в том, что у них очень высокий порог входа, а в том, что предоставляемые ими преимущества не настолько перекрывают трудозатраты, за исключением редких специфических случаев. А вот на каком-нибудь Qt или WPF чтобы по-быстрому рычаг себе и друзьям для чего-нибудь запилить — самое оно.
Экий вы зануда :)
Код на гитхаб переложить не хотите?

Внутри как оно работает, вы построили проксю к объектам из Qt или обёртку как в PyQt? Какие подводные камни?
Не буду обманывать на счет того «как в PyQt» оно или нет, честно — не знаю. Я скачивал PyQt в надежде почерпнуть что-то полезное для себя, но не смог этого сделать в силу своих незнаний Питона.
Все классы — это действительно обёртки над Qt-шными, которые предназначены для того, чтобы расшарить доступ к не-INVOKABLE методам и за одно привести их входные и выходные значения к примитивным типам, с которыми работает PHP (int, char, bool...). Доступ к объектам со стороны PHP осуществляется через магические методы (__call, _set...), предоставляемые Zend'ом, а финальный вызов методов происходит через метосистему Qt. Если посмотреть заголовочные файлы движка PQEngine, можно увидеть, что в обертках все методы объявлены с макросом Q_INVOKABLE.

Насчет подводных камней вопрос очень интересный и двоякий.
Если говорить о разработке приложений с использованием этой библиотеки, то тут пожалуй самое страшное то, что возможны утечки. Именно при работе с объектами фреймворка Qt. Боролся я с ними долго и усердно, но не факт что искоренил их во всех местах.
Если говорить о разработке самой библиотеки, то тут в голову приходят сразу 2 момента:
  1. Непереносимость библиотеки на другие ОС. Слишком тесно все завязалось вокруг WinAPI, но в принципе, при желании «окросплатформеннить» её вполне реально.
  2. Отсутствие расширяемости библиотеки в пользу её компактности. Из-за использования статической линковки с Qt написать какое-то дополнение достаточно проблематично. На счет этого уже было несколько идей, например, вынести из движка некоторые классы в подключаемые по требованию пользователя модули. Ну как в самом Qt — нужна работа с виджетами? Подключай QWidgets, нужна работа с сетью? Подключай QNetwork и т.д.
    Думаю, если библиотека будет развиваться дальше, то её компактность рано или поздно перестанет быть оправданной, именно тогда она и будет разбита на составные части подключаемые по желаю разработчика.

Очень жаль что библиотека только для Windows.
В статье не увидел упоминания об этом.
А почему было принято решение жёстко привязываться к WinAPI? Всё таки одно из главных преимуществ Qt это его кроссплатформенность.
Такого решения не было, все получилось само собой.
В основном к WinAPI привязан только модуль, позволяющий упаковывать и вытаскивать php-код из ресурсов приложения. Я вижу только один способ решить эту проблему — нужно лишь отказаться от статической линковки. Тогда можно будет пользоваться системой ресурсов Qt (qrc).
Если сделать так, то, как мне кажется, усугубится ситуация с возможностью создания кроссплатформенной библиотеки. Это проблему тоже можно было бы решить путем открытия исходных кодов, но тогда тайна упаковки php-кода будет раскрыта и достать исходник проекта из мало-мальски защищенного приложения ни у кого не составит труда.
Вот такой замкнутый круг получается.
Ну для обфускации php кода можно использовать сторонние библиотеки специально для этого предназначенные (ZendGuard, ionCube, etc). Раз есть возмножность подключать php экстеншены, то можно использовать их.
Плюс открытые исходники возможно привлекут сторонних разработчиков, так же этому поспособствует кроссплатформенность.

На мой взгляд у проекта с открытыми исходными кодами больше шансов взлететь в подобной нише.
Security through obscurity по идее не так уж и ценна. А вот кроссплатформенность — очень даже.
Такая библиотека лично мне привлекательна тем, что теоретически можно писать приложения которые могут жить как в браузере так и на десктопе лишь частично переработав вьювы, но сохраняя всю бизнеслогику и живя в привычном фреймворке.
Если я захочу использовать YII в GUI-приложении, то сохранение кода прилинкованным к экзешнику будет несколько странным и прожорливым по памяти…
Хм, а в каком месте qrc мешает динамической или статической линковке? У меня всё работает и так и так, про Q_INIT_RESOURCE не забыли?
Тайна упаковки PHP кода — несостоятельна, я беру, делаю DLL которая является проксёй к dll ке php и смотрю какой же вы php код кидаете в eval. Если статическая линковка — то же самое только под отладчиком. Это очень легко.
Так же обращаю ваше внимание на то, что Qt лицензируется под LGPL (статическая линковка с не LGPL кодом запрещена), поэтому я сейчас пользуясь этой лицензией требую выслать мне исходные тексты программы. Заранее уведомляю что размещу их на GitHub поэтому приемлем вариант что их разместите ВЫ и вышлете мне ссылку на гитхаб.
Задействовать qrc мне ничего не мешает. Но если его подключить, приложение получается Qt-зависимым, а значит либо требует наличия shared-библиотек Qt, либо требует статической линковки, а это в свою очередь означает, что программа увеличивается в размерах в два раза (ведь библиотека и так уже собрана статикой). В настоящее время при компиляции на выходе получается нативное win-приложение, которые использует возможности движка для работы с php файлами.

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

Использование лицензии не наделяет вас или кого либо другого правом владеть исходным кодом. Продукт поставляется с заголовочными и объектными файлами библиотеки — делайте с ними что хотите: хоть на гитхабе публикуйте, хоть на луну отправляйте :)
Более того вместе с библиотекой поставляются исходники и объектные файлы статической сборки Qt, которые как бы намекают, что разработчик не вносил изменения в исходный код фреймворка. Какой не-LGPL-код вы имеете ввиду я не понимаю.

Тайна упаковки PHP кода — несостоятельна

Ну так это вы :) любой Ванька может открыть текстовый файл, который лежит в папке с приложением, и посмотреть его содержимое. А чтобы сделать прокси и посмотреть что отправляется в eval (который там, кстати, не используется) нужно как минимум знать, что приложение написано на php.
Доступна для тестов сборка для линукса: ubuntu 14.04, Qt 5.2.1, PHP 5.6.13. Пока только так.
Если есть желание пощупать, то вот информация: http://phpqt.ru/pqengine/pqengine-on-linux
Пока не очень понятно мне как у вас соотносится объект в PHP и объект в Qt.
В PyQt получили проблемы вида: Qt удалило объект а питон нет и наоборот. Во втором случае мы имеем проблему с потенциальной утечкой памяти, в первом — попытку работать с удалённым объектом.

Использование WinAPI — это не вин, серьёзно, вы сроднили два кроссплатформеных инструмента и получили Win-only приложение. Не круто вышло.
В этом плане утечек быть не должно. В движке реализовано собственное хранилище объектов. Каждый раз когда php обращается к объекту qt, это хранилище проверяется на предмет уничтоженных объектов как со стороны php, так и со стороны qt. Оверхед при этом не стучается, максимум что может произойти — пых вместо объекта получит null и выдаст соответствующее сообщение.
А вообще для «безопасного» удаления любого qt-объекта имеется метод $object->free(). По идее само ничего удаляться не должно :) Да и движок очень узконаправлен, работает по большей части только с виджетами. Оберток над такими классами как QRect, QIcon, QVector и прочими нет и не предвидится, мне кажется что это уже лишнее. Все-таки движок предназначен больше для работы именно с GUI, а не с фреймворком Qt.
Окей, не гарантирую но предполагаю проблемы в таком коде:
$w = new QWidget();
$layout = new QGridLayout;
$w->setLayout($layout);      // владение пререходит к $w
$button1 = new QPushButton($w);
$layout->addWidget($button1);
// пока всё хорошо
$w->free()  // но это же не единственный способ :)
// unset($w);  // можно добавить больше веселья или вообще заставить GC собрать её
echo $layout->count(); 
/* прикол в том что у $layout parent стал равен $w, который мы удалили и он удалит всех детей, удаление через deleteLater не является решением проблемы т.к. только откладывает её (хотя для этого кода он сработает). 
В принципе выше вы писали про хранилище объектов, если оно реализовано грамотно то проблем не будет, но тогда интересно что вернёт count , логичнее всего было бы исключение.
*/

Я не зря написал про free(), потому что это действительно безопасный метод удаления объектов. Сейчас постараюсь рассказать что же тут произойдет. Когда мы вызываем free(), движок удаляет не только сам объект, но и все его дочерние объекты. А если объект — это виджет, то удаляется и установленный Layout, если таковой имелся. В вашем коде мы бы ничего не получили, в ответ. Даже сообщения об ошибке. Движок PQEngine в этом случае бы просто проигнорировал вызов метода, но сама переменная $layout все еще существует в памяти Zend Engine (если можно так выразиться). Существовать эта переменная будет до тех пор, пока она не «исчезнет» из области видимости, либо пока мы не запишем в нее что-нибудь другое.
Тестировать наличие утечек в подобных ситуациях я привык с помощью таймера:
$timer = new QTimer;
$timer->interval = 1;
$timer->onTimer = function() {
    $w = new QWidget();
    $layout = new QGridLayout;
    $w->setLayout($layout);      
    $button1 = new QPushButton($w);
    $layout->addWidget($button1,0,0);
    $w->free();
};

$timer->start();
// запускаем код, открываем диспетчер задач и видим, что потребление памяти не возрастает ни на килобайт. Весьма непрофессиональный метод, но довольно эффективный :)


Теперь о unset(). unset() удалит лишь переменную, но qt объект останется в памяти. При этом мы с легкостью сможем получить доступ к этому объекту по его имени, либо через метод другого компонента, который бы возвратил ссылку на наш объект, например
$stack = new QStackWidget;
$widget = new QWidget;
$widget->objectName = 'myWidget';

$stack->addWidget($widget);

unset($widget);

$widget->free(); // возвратит ошибку, ведь мы удалили переменную, но
$stack->currentWidget->free(); // удалит наш виджет из памяти. Навсегда. 

// кроме того к объектам можно обращаться через специальную функцию c($objectName):
$objectName = 'myWidget';
c($objectName)->free();


За код спасибо. Очень не хватает подобных тестов «с подковыркой».
Этот пост должен был нести добро и радость php-шникам, но тут пришли вы и перекрасили всё в серый цвет. Зачем же вы так? :)
Рассказывать о достоинствах PHP и его преимуществах перед другими языками будет не уместно, да и я рискую быть закиданным помидорами (а то и чем потяжелее), но все же — быстро склепать какую-нибудь безделушку с возможностью выхода в интернет без мозголомки, да еще и обрисовать вокруг этой безделушки вполне себе функциональную форму вполне реально.
Конечно, что-то достаточно серьезное на этом не напишешь, хотя попытки были… В любом случае это не мне решать, думаю тот, кого заинтересует данная библиотека найдет ей применение.
Я бы почитал «о достоинствах PHP и его преимуществах перед другими языками», было бы интересно.
Быстрая разработка, лучшее (или одно из лучших) на рынке соотношение цена/качество у разработчиков, большое комьюнити, довольно качественная экосистема, в последние несколько лет — еще и всё для написания качественного кода. Камон, бро, пора проснуться, мы не в 2007.
Писал как-то довольно тяжеловатую консольную тулзу на пхп. Основной аргумент был в том, что 90% кода было переиспользовано из родственного проекта сайта написанного на пхп. Тот же апи, те же функции… Запускалось под виндой. Собственно оно до сих пор работает. Висит консолька у людей, с которой изредка общаются, да отслеживают ее сообщения. Если бы я тогда имел опыт с данной библиотекой, то консолька была бы не консолькой а более красивым окошком.
Переписывать библиотеки на другой язык? Вспоминать другой язык? А зачем? тулза работает на трех компах, используется только сисадминами и кодерами…
UFO just landed and posted this here
UFO just landed and posted this here
Простите за оффтоп, но в защиту PHP хочется отметить умеренные цены на хостинг чисто с PHP (что особенно интересно для персональных сайтов).
Интересно будет ли дальнейшее разве проекта. было бы крайне приятно иметь что то типа PyQt.
А то все предыдущие библиотеки подобной направленности мертвы.
В силу возможностей — будет :) по крайней мере пара-тройка нереализованных идей еще имеется.
Скажите, а есть возможность работать с веб-сокетами? Если да, то неплохо бы примерчик.
Возможность такая есть, движок поддерживает подключение php-расширений. Что для этого нужно:
  1. в директории с приложением необходимо создать папку ext и скопировать туда нужную библиотеку. В вашем случае это будет php_sockets.dll. Библиотеку можно найти в дистрибутиве php, версия должна быть либо 5.4.45, либо 5.6.11 (в зависимости от того какой версией PQBuilder вы собирали приложение);
  2. затем, для того чтобы эта библиотека подключилась, в директории с приложением создаем текстовый файл с именем pqengine.ini и со следующим содержимым:
    extension="php_sockets.dll"
    pqengine.ini — это тот же самый php.ini
Никогда такого не было, и вот опять.
Sign up to leave a comment.

Articles