Фишечки PHP, о которых вы, скорее всего, не знали

php

Можете нас поздравить - это двухсотая запись в блоге! А теперь перейдем к статье.

Всем айтишникам известно, что PHP - очень простой язык с низким порогом вхождения. Простой скрипт на нем сможет написать даже тот, кто не особо разбирается в программировании и не знает большинства синтаксических особенностей языка и приемов разработки на нем. Я сейчас занимаюсь написанием новой версии своего старого проекта PHP Obfuscator. Я переписываю его с нуля, чтобы он поддерживал все самые современные фичи последних версий PHP. Старый обфускатор (1.5) уже и в подметки не годится новому, хотя тот еще не дописан. Так вот, когда пишешь что-то подобное, волей-неволей оказываешься вынужден изучать синтаксис языка в мельчайших подробностях и узнаешь все его особенности и возможности. Поэтому я хочу рассказать о таких интересных свойствах языка PHP, о которых большинство людей, которые пишут на нем код, даже не слышали. Это малоизвестные или совсем новые возможности. Может быть, кто-то начнет их применять, потому что какие-то из них могут оказаться реально полезными. Многие вещи из тех, о которых я собираюсь рассказать, упомянуты в документации на PHP, но какие-то совсем не документированы. Какие-то же факты вас, вероятно, даже удивят. Кроме того, я хочу отдельно рассказать про метапрограммирование в PHP.

Читать далее «Фишечки PHP, о которых вы, скорее всего, не знали»

Skype Preview — плагин предпросмотра ссылок в скайпе

skype

Сидел я как-то в одном уютном чатике в Skype, и тут одному из участников в голову пришла весьма интересная идея: сделать плагин для скайпа, который позволял бы просматривать содержимое тех ссылок, которые вкидываются в чат, без их открытия. "А почему бы и нет?", - подумал я. Можно открывать картинки в уменьшенном варианте, если ссылка указывает на изображение (в том числе анимированные). А если ссылка ведет на обычную html-страничку, то можно отображать ее заголовок. Забегая вперед, покажу, что получилось:

plugin

Читать далее «Skype Preview — плагин предпросмотра ссылок в скайпе»

Оптимизация PHP-скриптов: практические советы

coding

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

Сразу скажу, что заниматься преждевременной оптимизацией не нужно. Стоит задуматься о переработке кода только в следующих случаях:
[+] ваш скрипт подолгу выполняется (например, делает какие-то занимающие длительное время операции в цикле);
[+] ваш скрипт очень часто выполняется (это был мой случай - иногда в день тест проходили порядка десяти тысяч человек - а это около миллиона обращений к скрипту в сутки);
[+] от используемых скриптом ресурсов зависит то, сколько денег вы платите. Если скрипт выполняется на обычном виртуальном хостинге и не превышает лимит нагрузки на процессор, то, скорее всего, можно и не париться;
[+] вы собираетесь массово распространять скрипт, и его будет использовать в конечном итоге множество людей, которым критично, сколько ресурсов скрипт потребляет.

Читать далее «Оптимизация PHP-скриптов: практические советы»

Психологический тест: история, итоги и статистика

unique_header

Вероятно, многие читатели блога знают, что я какое-то время назад ради интереса написал на PHP простенький движок, позволяющий проводить психологические тесты (и не только психологические). Работающий экземпляр размещен по адресу kaimi.io/projects/soul. Поначалу это был совсем простой скрипт, читающий конфигурацию тестов из XML и позволяющий пользователю отвечать на вопросы. В конце выдавались значения характеристик человека (вроде "задрот", "альфач" и т.д.) в процентах. Скрипт постепенно оброс новым функционалом, реализованным через плагины. Для лулзов был создан тест под названием "Социо-тест! Насколько ты задрот, битард и социофоб? Проверь себя!" (разумеется, я не имею никакого психологического образования, и всё делалось от балды и отлаживалось на себе, друзьях и знакомых). Однако, я, разумеется, не ожидал, что достаточно было один раз вбросить ссылку на него на какую-нибудь популярную имиджборду (например, 2ch), и дальше всё заработает само. Тред с тестом висел в топе несколько дней. Затем ссылку растащили по сети, и она стала появляться на таких популярных сайтах, как joyreactor.сс, dota2.ru, pikabu.ru, lurkmore.to и т.д. В Твиттере, ВКонтакте, ЖЖ и других соцсетях, а также на форумах пользователи стали делиться ссылкой на тест и результаты, что тоже прибавило посещений. Первую версию теста прошло 80 тысяч человек, были высказаны различные пожелания по его улучшению, и я решил доработать тест. Теперь актуальна новая версия, и на момент написания статьи ее прошло уже почти 250 тысяч человек! Это, пожалуй, первый проект, сделанный исключительно ради удовольствия и веселья, который помог окупить хостинг за несколько месяцев благодаря Google Ads.

Что касается движка, то постепенно были добавлены такие возможности, как рандомизация порядка ответов и вопросов, условные вопросы (которые задаются только при определенных ответах на предыдущие вопросы), получение подробного описания по каждой характеристике, вывод общего описания человека, расшаривание результатов теста, кеширование, темы и т.д. Была проведена достаточно основательная работа по оптимизации движка (про это можно написать отдельную статью). Сейчас еще остается недописанным GUI-редактор тестов. Вероятно, когда я его доделаю, я выложу и движок со всеми плагинами, и редактор.

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

Читать далее «Психологический тест: история, итоги и статистика»

Получаем бесплатные купоны к разным иностранным магазинам

Пожалуй, пришло время разбавить хардкорные статьи более веселыми :)

logo

Давным-давно я рылся в AppStore со своего iPod'а, и попалась мне на глаза забавная на первый взгляд игра Stop Those Fish, смысл которой сводился к тому, что вы, играя компанией медведей-рыбаков, должны глушить рыбу, которая атакует ваши лодки. Был и второй режим игры, доступный после окончания первого, но это уже неважно. Самым интересным оказалось то, что после прохождения каждого уровня на мой личный счет на неизвестном мне на тот момент сайте p4rc.com начислялись очки, если на iPod был включен Wi-Fi, разумеется. Я зарегистрировался на этом сайте и понял, что на эти самые очки можно покупать купоны по 25$ для самых разных американских интернет-магазинов, в том числе Amazon и Ebay (позже стали добавляться и купоны для британских магазинов, затем - билеты на премьеры в кинотеатрах США и т.д.). Один такой купон стоил 1500 очков (причем эти 1500 должны быть набраны в день, когда купон появился), и их набор честным игровым путем занимал больше часа. Новые акции на сайте появляются 1-2 раза в сутки, и во время каждой акции, как правило, доступно три двадцатипятидолларовых купона. Кто успел, тот и съел. Кроме того, за 500 очков можно было купить небольшие скидки и бонусы, доступные всегда. Сейчас на сайте доступно гораздо большее количество разнообразных наград меньших номиналов, но и стоят они дороже, например, карта iTunes на 10$ стоит аж 10000 очков, емана.

Читать далее «Получаем бесплатные купоны к разным иностранным магазинам»

Пишем собственный упаковщик. Шаг 12 — Работа над ошибками

pack

Благодаря одному товарищу из комментариев в предыдущих постах касательно упаковщика выявился один занятный баг в коде, который я поспешил исправить. Комментатор, не разобравшись в деталях работы пакера, утверждал, что код, запакованный им, окажется неспособным работать с SEH при условии, что DEP включен. При таких условиях код работал хорошо (так как весь распакованный код в памяти находится в пределах одной-единственной секции PE-файла, помеченной как исполняемая. UPX имеет такую же логику работы.). Но случайно была обнаружена следующая ошибка: если программа собрана в MSVC++, использует SEH и имеет релокации, при первом же возникшем исключении она упадет с некоторой долей вероятности (точнее, если файл загрузился не по своему базовому адресу). DEP тут, конечно же, не при чем. Все дело оказалось в злополучной директории IMAGE_LOAD_CONFIG_DIRECTORY. Она создается линкером Visual Studio. Из полезной информации она содержит таблицу адресов (RVA) SE-обработчиков и указатель на внутреннюю переменную crt __security_cookie. Как выяснилось, эта директория нужна не только для внутренностей CRT (хотя она, кажется, как раз хотела плевать на эту структуру), но и системному загрузчику (по крайней мере, в Win7. WinXP, похоже, тоже плевал на эту директорию). Упаковщик, который я описываю, перемещает эту директорию в другую секцию (см. здесь). Поэтому исправить ошибку можно, добавив в таблицу релокаций, создаваемую упаковщиком, несколько записей, которые будут править адреса, указывающие на security cookie и таблицу обработчиков SEH, чтобы он мог считать интересующую его информацию из этой директории на этапе загрузки.

Помимо правки этой ошибки я обновил код упаковщика, чтобы он собирался с использованием последней на данный момент версией библиотеки для работы с PE-файлами (PE Bliss). Ее всегда можно скачать отсюда.

Кстати, насчет библиотеки PE Bliss. Сейчас в свободное время я допиливаю новую версию, в которой появятся следующие дополнительные возможности (список примерный и может измениться):
- высокоуровневая работа с дополнительными типами ресурсов PE-файлов;
- детальный разбор .NET-бинарников (метаданные, сигнатуры, ресурсы);
- обертка над библиотекой на C++/CLI, которая позволит .NET-разработчикам удобно использовать функционал библиотеки в софте на C# или Visual Basic .NET.

Скачать исходники упаковщика: packer source
Скачать собранный вариант: packer binary

UPDATE 24.05.2016: доработки генерации таблиц релокации. В некоторых случаях (например, когда TLS-данных слишком много и присутствует директория load config, адреса в таблице релокации могли переполняться, и файл после упаковки не работал).

Minecraft + Tekkit: обзор и собственный независимый сервер

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

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

Читать далее «Minecraft + Tekkit: обзор и собственный независимый сервер»

Четвертый квест. Полное прохождение.

Прошло уже прилично времени с момента запуска нашего четвертого квеста (расположен тут, поэтому публикуем полное прохождение с блэкджеком и шлюхамиачивками и "пасхальными яйцами". Итак, как вы уже, наверное, знаете, квест этот нелинейный и имеет несколько ветвей сюжета, которые выбираете вы сами. Впрочем, после прохождения (или даже забив на нее) какой-либо ветки можно было пройти и другие, увидев в итоге весь контент и пройдя все задания. В квест было добавлено аж 40 достижений (это же модно!). Сейчас уже не получится взять все, однако я все равно опишу каждое.

Читать далее «Четвертый квест. Полное прохождение.»

Пишем упаковщик по шагам. Шаг 11. Интерфейс командной строки. Финальная версия.

Предыдущий шаг здесь.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.9). Никакие баги там поправлены не были, был добавлен функционал, который упаковщик не использует, так что ваше дело, перекачивать ее или нет :)

В этом шаге мы запилим нашему упаковщику хороший интерфейс командной строки. Я возьму вариант из старого упаковщика и модифицирую его.

Читать далее «Пишем упаковщик по шагам. Шаг 11. Интерфейс командной строки. Финальная версия.»

Пишем упаковщик по шагам. Шаг десятый. Общая архитектура.

Предыдущий шаг здесь

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

Итак, представим, что у нас есть DLL-файл, имеющий следующие директории:
- импорты
- экспорты
- ресурсы (в том числе информацию о версии)
- релокации
- конфигурацию загрузки
- TLS с коллбэками

Словом, всего по максимуму. Как это все будет расположено в упакованном файле?

Читать далее «Пишем упаковщик по шагам. Шаг десятый. Общая архитектура.»