Lint PHP files in parallel

One of the quickest and minimal code quality checks in software development is a simple syntax check. In case of PHP we have php -l <path/to/file.php>, nothing smart, nothing fancy.

In case of check automation or continuous integration you even may use Phing task PhpLintTask – runs perfectly and fails build f someone occasionally commits code with syntax errors.

But if you have many files, many CPU cores and fast enough disk – you can lint your PHP files in parallel with PHP Parallel Lint. I’ve tried this tool today and it runs twice faster than standard Phing task using serial approach.

Composer/Satis and GitHub Rate Limits

Composer/Satis and GitHub Rate Limits – hit this issue today. 60 requests per hours is not so match when you use Composer to build a project few times or you try to build local package repo with Satis with empty composer cache.

Actually, I wonder, why I didn’t hit rate limits (introduced in October 2012) earlier with Continues Integration building project few times per hour. Possibly Composer cache saved the day (TTL of cache is about 6 months by default). But I see many request (or issues) over Internet about this issue… and spent couple of hours solving it today to achieve my goals.

One of the best solutions I’ve found: Alister Bulman – Avoiding Composer Being Rate-limited by Github and it works perfectly with Composer and failed with Satis (at least for now).

After few “var_dump” of Satis and Composer I’ve found that Composer reads “global” configuration file from “COMPOSER_HOME” directory (next time do some RTFM: COMPOSER_HOME/config.json) and merges with local project settings.

So, if you place your GitHub OAuth key, created by Alister Bulman instructions, into COMPOSER_HOME/config.json file – you won’t need to place it anywhere else until you hit 5000 limit.

Example of COMPOSER_HOME/config.json:

{
"config": {
"github-oauth": {
"github.com": "<your GitHub OAuth Key>"
}
}
}

From now my Composer and Satis works fine. Might help if you use Continues Integration servers.

More about COMPOSER_HOME directory.

Some obvious things learned hard way.

PHP Conf 2009 Kaunas

Да, да я пишу о PHP Conf 2009 Kaunas, который произошёл 2 месяца назад, ещё 21 апреля 2009 года. Как-то туго у меня со свободным временем и всё что осталось свободным от работы ты тратишь на семью и отдых.

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

Организаторы были в этом году теже, что и в прошлом: InfoShow и «Net Frequency». Всё происходило в центре дистанционного обучения Каунасского технологического университета.

Тема у меня благодатная: «PHP+MySQL проекты с огромной посещаемостью», информация по ней много в сети, и я сделал просто выборку по теме и подкрепил её своими жизненными примерами. Презентацию я сделал на ура за несколько часов в одно из воскресений после прогулок по магазинам с супругой. Потом потратил пару часов на доработку.

Поездка в Каунас прошла очень гладко — 100 км на автобусе проехать очень просто и не долго по автостраде. Музыка в плеере, 3G интернет в мобильном, пара звонков, включая организаторов: попросили выслать им презентацию заранее, что-бы перенесли её в нужный компьютер — переслал её прямо в пути через Gmail клиент в Nokia. Тут всё прошло без проблем.

Сама конференция в этом году прошла очень и очень интересно и я бы сказал на довольно высоком уровне.

Во первых, все докладчики подобрали очень интересные темы:
Rytis Lukoševičius — «Как стать лучшим программистом»
Очень понравилась идея «имени-бренда», очень правильные идеи относительно того что работа должна нравиться. Это не новость, но тема в наши дни я думаю очень актуальная для многих, особенно начинающих PHP программистов.

Rimantas Liubertas — «Дистрибутивные системы контроля версий: git, mercurial, bazaar»
Актуальная тема для многих — такие системы как git или bazaar становятся всё популярней и востребованней среди разработчиков. Беглое ознакомление с ними многим может помочь в дальнейшем при их изучении, да и за всеми новостями не всегда успееш.

Paulius Jačionis — «Как справиться с огромными потоками пользователей»
Человек представил именно свою визию (точнее команды, которая работает над проектом http://www.uzdarbis.lt/), как бороться с нагрузкой, которая образуется при больших потоках пользователей имея маленький парк машин. Очень рад, что я не один здесь и решения которые принимаю я совпадают с теми, что принимают они.

Edvinas Tamošiūnas — «Как новичку влиться в команду, быстро и эффективно»
Это была довольная весёлая презентация с серьёзными и не очень советами. Кто первый раз попадал в такую ситуацию — то они полезны, кто не раз менял работу — то наверняка уже имеет свою тактику.

Giedrius Kriščiukaitis — «За качество и эффективность»
Не ожидал такой открытой презентации о том, что происходит внутри отдельно взятой компании, методах и технологиях. Местами казалось, что работать в «Net Frequency» для меня было-бы вызовом.

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

Понравилось замечания в адрес моей презентации от Giedrius Kriščiukaitis, что в ней не упомянуто ни одного способа как проверить максимальную нагрузку на разрабатываемом проекте, ни показаны числа. К сожаления у меня нет этих чисел и способов проверить — я работаю с проектом, который уже до меня разместили на нескольких серверах с распределением нагрузки и провести тесты на живом проекте не представляется возможным — ни сайт есть желание положить, ни канал с такой пропускной мощностью, так что многое делается «по приборам» и внутреннему чутью команды. Я покупать копию по «желеу» для этих нужд никто не будет.

Что не понравилось, так то, что Tomas Liubinas и Vladas Diržys не представили свои темы: «OXID eShop Community Edition» и «Не изобретай велосипед, используй framework. Плюсы Zend Framework». Я очень ждал этих презентаций.

На after-party я не пошёл, так как предстояла дорога домой, дома ждала любящая супруга и вкусный ужин. Да и не любитель я пить пиво вечером в другом городе, если потом ехать куда-то надо.

NGINX, PHP-FPM и загрузка файлов по HTTP

Наверно недели 3 сидел у меня в голове вопрос на тему NGINX + PHP-FPM (FastCGI) и как они будут работать с загрузкой файла по HTTP, если PHP-FPM процесс крутиться на другом сервере.

Сегодня наконец выпала возможность в конце рабочего дня собрать на 2 раздельных серверах такую конфигурацию, когда NGINX находиться на одном сервере, а процессы PHP-FPM на другом и NGINX весь .php прогоняет именно через те процессы, что крутятся удалённо.

Весь этот эксперимент проходил на Ubuntu Server 8.10, так что проблем с установкой или сборкой PHP или NGINX у меня не возникло. Единственное, что я сделал не верно и что меня затормозило на пол часа, так это конфигурация NGINX — я упустил строку, в которой PHP файлы указывалось искать не в Document Root, а в /scripts.

Собрать из HTML форму для загрузки файла не составляет труда, добросить за несколько минут туда PHP код, который сделает var_dump($_FILES); и отдаст содержимое загружаемого файла тоже не сложно.

Прицепить маленький текстовый файл и нажать на «Submit» ещё проще. И что же видно в результате? Всё работает идеально. Файл загружен при помощи POST на сервер с NGINX, а там передан к PHP-FPM и уже PHP-обработчик с ним работает как ему/вам угодно — что меня очень радует. Всё работает «out of the box» и никаких особых шаманских танцев не нужно.

Что огорчает, так что PHP-FPM до сих пор не входит ни в стандартную поставку PHP ни в какие-либо пакеты в стандартных дистрибутивах Linux — таскать за собой какие-либо Perl или Lighttpd spawn-скрипты не хочется, плюс те возможности, которые представляет PHP-FPM делает его очень вкусным.

Ещё огорчает, что PHP-FPM это patch к PHP и после его установки установить какой-либо модуль из PECL становиться намного сложнее если вы его хотите скомпилировать со static – приходиться использовать phpize.

Но вообще, эксперимент считаю удавшимся — сборка системы с NGINX + PHP-FPM не представляет сложности и я давно хотел испытать такую конфигурацию хотя-бы в парниковых условиях.

MySQL + PHP: charset и collation

Работаю я над одним проектом, где в день проноситься до миллиона уникальных посетителей в день. Для этого проекта я с командой работаю над маленьким сателлитом, назначения которого не имеет столь весомого значения, сколько имеет значение проблема, с которой я сегодня столкнулся. И нам крупно повезло, что кол-во данных сейчас на сателлите мизерное и он пока находиться в стадии тестирования и нагрузка на нём растёт постепенно.

Проект пишется на PHP 5.2.x + MySQL 5.0 Так как проект международный, база сателлита находиться в collation utf8_unicode_ci.

У сателлита есть 2 части: так называемая клиентская и административная. Клиентская доступна всем и дёргается постоянно, административная только администраторам, ею пользуются раз в неделю примерно пока.

Клиентская часть, из-за ожидаемой нагрузки, писалась полностью мною, без использования каких-либо фреймворков, каркасов и прочего. Благо её простейшие функции позволяли это сделать быстро. Естественно, в качестве MySQL клиента был выбран mysqli, всё как надо, сразу после соединения был выставлен нужный charset, строго как в мануале:

$conn->set_charset("utf8")

Сам mysqli был выбран потому-что проект новый и у него вроде-как получше с поддержкой UTF-8 всё устроено.

Административная часть писалась коллегой, на пару со мной, причём ответственность за качество кода лежит на мне. Для большей скорости написания мы использовали Zend Framework, который мы оба довольно не плохо освоили к этому моменту. К тому-же, административная часть имела куда больше функций и меньше нагрузки, нежели клиентская. Единственное разногласие, которое у нас было с коллегой, это использовать или нет Zend_Form или нет из-за очень сложной кастомизации самих форм и их декораторов, неразумного использования комбинации <dd> и &ltdt> вокруг скрытых полей и прочих мелких религиозных и языковых разногласий. Ни одному из нас не возник простейший вопрос, как устроен другой компонент — Zend_Db. Определит ли он сам charset и collation, который мы используем и нам нужен или будет использовать тот, что установлен по умолчанию. И вот, сегодня мы поняли что мы выстрелили себе в ногу примерно две недели назад — не то пуля летело медленно и наконец долетела, не то порох сырой ныл и сработал только сейчас.

Я всегда думал, что умный Zend_Db как-то сам узнает какой нужно charset и collation использовать, раз он сам узнаёт какие поля у таблицы и какие значения туда можно писать, а какие нет. Оказалось что нет… Я был не прав и ему об этом нужно грубо говорить (ну или клиенту вдолбить в настройки по умолчанию).

Поэтому в самом начале ему пришлось прописать следующие строку сразу после инициализации:

$db->query('SET CHARACTER SET utf8');

Теоретически, если следовать документации Configuring the Character Set and Collation for Applications, хватило-бы только SET NAMES ‘utf8’, но в таком случае collation остался бы utf8_general_ci — а нам этого не хочется. Поэтому, копнув немного глубже, в Connection Character Sets and Collations, было найдено SET CHARACTER SET utf8.

После данных изменений со стороны административной части на Zend Framework, замены $conn->set_charset(“utf8”); тоже на $conn->query(‘SET CHARACTER SET utf8’); и правок в базе данных всё заработало прекраснейшим образом.

Я вот понять не могу, почему у Zend Framework нигде об этой проблеме не написано? Зачем у mysqli есть метод mysqli::set_charset, если он меняет collation на верный? Почему в PHP мануале написано не использовать «старый дедовский способ с SET NAMES»?

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