вторник, 5 марта 2013 г.

ssh-agent + ssh-add: вводим пароль к ssh-ключам один раз за сессию

Как и многие другие юзвери, я достаточно ленив для того, чтобы при каждом чихе вводить пароли. Особенно если приходится по сто раз за сеанс подключаться к серверам по SSH - это, мягко говоря, утомляет.
Технология добавления ключей в агента уже рассмотрена вдоль и поперек в сотне различных документов, но почти все они не устраивали меня: мне лень вводить пароль к ключам при входе в сеанс - если запускать ssh-add автоматически, или не забыть запустить его при первой попытке входа по ssh, чтобы потом об этом не задумываться...

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

среда, 5 декабря 2012 г.

Замена PHP 5.3 на PHP 5.4 на Ubuntu 12.04 LBS

Наверняка многие, установив 12.04, с удивлением обнаружили, что в ней живет PHP версии 5.3.х. Меня это не слишком устраивало, так как проекты я стараюсь писать на "свежей" версии языка, чтобы было поменьше проблем при обновлениях на сервере. Итак, перелопатив кучу советов и настроив-таки рабочую машину, делюсь с вами своим опытом. Не браните громко, ибо сие произведение - мой первый опыт блоготворчества :)

В первую очередь проверьте, какую версию PHP вы имеете сейчас:
user@server:~$ php -v

Скорее всего, ответом будет:
PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch (cli)

Что ж, приступаете к замене:
user@server:~$ sudo apt-get install make python-software-properties
user@server:~$ sudo add-apt-repository ppa:ondrej/php5
user@server:~$ sudo apt-get update
user@server:~$ sudo apt-get upgrade
user@server:~$ sudo apt-get install php5 libapache2-mod-php5

С этим проблем быть не должно :)
После замены php 5.3 на 5.4 [пере]устанавливаете расширения:
user@server:~$ sudo apt-get install php5-dev php5-curl php5-gd php5-imagick php5-intl php5-mcrypt php5-memcached php5-mysql php5-xdebug php5-xmlrpc

Если у вас есть расширения, которые устанавливались вручную (например, xdebug) или через pecl (например, mongo) - удаляете их и снова устанавливаете, как ни в чем не бывало:
user@server:~$ sudo pecl uninstall mongo
user@server:~$ sudo pecl install mongo

Снова смотрите на версию:
user@server:~$ php -v

Я сразу после процедуры получил следующее:

Failed loading /usr/lib/php5/20090626/xdebug.so:  /usr/lib/php5/20090626/xdebug.so: cannot open shared object file: No such file or directory
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib/php5/20100525/ffmpeg.so' - /usr/lib/php5/20100525/ffmpeg.so: cannot open shared object file: No such file or directory in Unknown on line 0
PHP 5.4.9-4~precise+1 (cli) (built: Nov 30 2012 10:42:23)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies

Рассудив здраво, решил с ffmpeg-ом не заморачиваться (необходимости в нем пока не наблюдается), и я его снес.

Как видите, осталась проблема с xdebug. Но с ней справиться было легко: немного шаманства с locate показало, что теперь его .so-шка просто-напросто лежит в другой папке :) Мне осталось лишь вручную заменить путь с  "zend_extension=/usr/lib/php5/20090626/xdebug.so" на новый "zend_extension=/usr/lib/php5/20100525/xdebug.so" - и все заработало как часы:
user@server:~$ sudo nano /etc/php5/conf.d/20-xdebug.ini

Заметка для особо любопытных: обратите внимание, что теперь имена почти всех .ini-файлов в /etc/php5/conf.d (кроме установленных вручную) начинаются с 10- или 20-.

Снова проверяете:
user@server:~$ php -v
Если остались проблемы (скорее всего это "ручные" расширения) - переустанавливаете расширения, на которые ругается система (смотри выше). У меня система выдала следующий ответ:
PHP 5.4.9-4~precise+1 (cli) (built: Nov 30 2012 10:42:23)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans


Если же (ура!) все в порядке - рестартуете апач:
user@server:~$ sudo service apache2 restart

Вуа-ля, пользуйтесь :)

суббота, 13 октября 2012 г.

Web Standards Days Киев 2012

Это небольшой отчет о конференции Web Standards Day, которая прошла сегодня в Киеве.

Web Standards Day мероприятие для меня непрофильное, я не фронтенд девелопер и не верстальщик. Поэтому, накауне, я немного сомневался, стоит ли идти на этот ивент или лучше досмотреть недавно выложенные в открытый доступ видео с парижского Symfony Live. Решение принял в пользу первого варианта и остался доволен. В целом, конфренция прошла отлично, скучно не было, узнал кое-что полезное, да и впечатления остались позитивные.

Мероприятие проходило в гостинице "Мир". Конференц-зал там не очень большой, человек на 150. Сегодня он был заполен чуть больше, чем полностью. Я пришел минут за 10 до начала и едва не остался без места :) Впрочем, по итогу, мест хватило всем и стоять никто не остался. Больше ничего не буду говорить об организации, в целом все было хорошо.

Из докладчиков особено  хочется отметить Вадима Макеева aka @pepelsbey. Его рассказ о правильном использовании ссылок, псевдоссылок и кнопок был из серии "просветляющих", и я настоятельно рекомендую посмотреть видеозапись доклада всем, кому хоть иногда приходится верстать html.

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

После докладов экспромтом было организовано небольшое обсуждение, посвященное в основном организации командной работы. А одна из последних реплик особенно порадовала. Вы что-то слышли о применении TDD при верстке? :)

Хочу поблагодарить всех докладчиков и организаторов. Это здорово, когда люди делятся своим опытом. И при этом делают это бескорыстно. Обязательно пойду на такой ивент в следующем году.





пятница, 25 мая 2012 г.

PHP и чувствительность к регистру

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

Так вот. В PHP чувствительны к регистру:
  • переменные;
  • константы;
  • ключи ассоциативных массивов;
  • свойства и константы классов.
В PHP не чувствительны к регистру:
  • функции;
  • методы класса;
  • языковые конструкции( include, echo и т.д.);
  • ключевые слова (if, while, false, null и т.д.).
Это просто нужно помнить, но я все время забываю. Потому и решил кинуть это в блог.

суббота, 24 марта 2012 г.

Управление ресурсами в Symfony2





На этой неделе, помимо прочих задач, я занимался клиентской оптимизацией на своем рабочем проекте. И узнал кое-что новенькое, чем и спешу с Вами поделиться.

Статья называется "Управление ресурсами в Symfony2". Поэтому хочу сразу оговориться, что я понимаю под словом "ресурс" (англ. asset). В данной статье под термином "ресурс" я подразумеваю HTTP ресурс, запрашиваемый браузером во время загрузки документа, т.е. это javascript файлы, css файлы, изображения и т.д.

Итак, приступим. В официальной документации по Symfony2 можно прочитать, что включать ресурсы в шаблоны нужно так:

// css
<link href="{{ asset('/css/main.css') }}" type="text/css" />


// javascript
<script src="{{ asset('/js/main.js') }}" type="text/javascript"></script>


// images
<img src="{{ asset('/images/header.png') }}" alt="" />

Но для чего же нужна функция asset()? Почему не желательно указывать в атрибутах href и src относительный путь к файлу на сервере? Давайте разберемся.

Я взял для демонстрации несколько файлов из Blueprint CSS Framework и подключил их в шаблоне таким образом:

<link href="{{ asset('/css/blueprint/reset.css') }}" type="text/css" media="screen, projection">
<link href="{{ asset('/css/blueprint/grid.css') }}" type="text/css" media="screen,  projection">
<link href="{{ asset('/css/blueprint/forms.css') }}" type="text/css" media="screen,  projection">
<link href="{{ asset('/css/blueprint/forms.css') }}" type="text/css" media="screen,  projection">
<link href="{{ asset('/css/blueprint/typography.css') }}" type="text/css" media="print">
<!--[if lt IE 8]><link href="{{ asset('/css/blueprint/ie.css') }}" type="text/css" media="screen, projection"><![endif]-->


Если больше ничего не настраивать в конфиге, то Symfony отрендерит приведенный кусок шаблона в такой html:

<link href="/css/blueprint/reset.css" type="text/css" media="screen, projection">
<link href="/css/blueprint/grid.css" type="text/css" media="screen,  projection">
<link href="/css/blueprint/forms.css" type="text/css" media="screen,  projection">
<link href="/css/blueprint/forms.css" type="text/css" media="screen,  projection">
<link href="/css/blueprint/typography.css" type="text/css" media="print">
<!--[if lt IE 8]><link href="/css/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->

В принципе, этого достаточно. Но, Symfony2 может сделать для вас кое-какую дополнительную работу. Стоит всего лишь задать несколько опций в конфигурации проекта.

1. Множественные домены

Symfony2 позволяет задать список доменов, а точнее список базовых URI. Т.е. в конфигурации можно прописать адреса источников из которых доступна загрузка ресурсов для нашего проекта.

Так как у меня всего один сервер, да и тот локальный, я просто прописал несколько доменов в /etc/hosts, а затем добавил эти же алиасы в конфигурации виртуального хоста. Теперь в конфигурационном файле я могу задать базовые URI для загрузки ресурсов:

framework:
    templating:
        assets_base_urls:
            - http://asset1.test.local
            - http://asset2.test.local
            - http://asset3.test.local
            - http://asset4.test.local
            - http://asset5.test.local


Тогда наш кусочек шаблона выведется как-то так:

<link href="http://asset2.test.local/css/blueprint/reset.css" type="text/css" media="screen, projection">
<link href="http://asset3.test.local/css/blueprint/grid.css" type="text/css" media="screen,  projection">
<link href="http://asset1.test.local/css/blueprint/forms.css" type="text/css" media="screen,  projection">
<link href="http://asset1.test.local/css/blueprint/forms.css" type="text/css" media="screen,  projection">
<link href="http://asset5.test.local/css/blueprint/typography.css" type="text/css" media="print">
<!--[if lt IE 8]><link href="http://asset5.test.local/css/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->

Т.е. Symfony добавит к каждому относительному пути указанному в функции asset() один из базовых URI из конфига. Я не разбирался с тем, в каком порядке будут подставлены URI из конфигурационного файла, могу лишь сказать, что последовательность всегда одна и та же. Т.е. если мы использовали один домен для загрузки ресурса, то этот ресурс для пользователя всегда будет загружаться с выбранного домена. В другом случае эта фича не имела бы смысла, т.к. все ресурсы кешируются браузером. И браузер понимает ресурс с другого домена как уникальный и скачивает его вместо того, чтобы использовать закешированный.

Таким образом используя конфигурационную опцию assets_base_urls можно разнести ресурсы на несколько серверов или использовать CDN. Но даже, если у вас всего один сервер, как в моем случае. То все равно имеет смысл сконфигурировать для вашего сервера дополнительные домены и использовать их как алиасы для загрузки ресурсов. И сейчас объясню зачем.

Дело в том, что браузеры имеют ограничения на количество открытых соединений к одному домену. В таблице ниже приведено количество возможных одновременных соединений с одним доменом для разных браузеров (информация не проверена).


Browser HTTP/1.1 HTTP/1.0
IE 6,7 2 4
IE 8 6 6
Firefox 2 2 8
Firefox 3 6 6
Safari 3,4 4 4
Chrome 1,2 6 ?
Chrome 3 4 4
Chrome 4+ 6 ?
iPhone 2 4 ?
iPhone 3 6 ?
iPhone 4 4 ?
Opera 9.63,10.00alpha 4 4
Opera 10.51+ 8 ?



Таким образом, использование нескольких URI для загрузки ресурсов с одного физического сервера позволяет эти ограничения обойти, т.е. можно использовать большее количество соединений. Откуда следует, что ваши ресурсы будут загружаться в большее число потоков, а значит быстрее. Один дополнительный домен позволяет открывать в два раза больше соединений, если задано в конфиге пять доменов - можно использовать в пять раз больше соединений.

2. Сache busting


Как я уже говорил, все ресурсы кешируются на стороне клиента (т.е. браузером). Но что делать, если вы, скажем, обновили стили и пользователям нужно загрузить новую версию стилей, а старая версия находится в кеше. Решение в данном случае простое. В запрос нужно просто добавить какое-нибудь уникальное значение. URI ресурса в этом случае поменяется и браузер загрузит новую актуальную версию. И совсем не обязательно сообщать пользователям: "Мы там стили обновили. Почистите в Вашем браузере кеш, пожалуйста!" :)

В Symfony2 можно просто указать в конфиге версию ресурсов. Например, я добавил в свой конфиг такие строки:

framework:
    templating:
        assets_version: 1.0.0

и получил такой html:

<link href="http://asset2.test.local/css/blueprint/reset.css?1.0.0" type="text/css" media="screen, projection">
<link href="http://asset3.test.local/css/blueprint/grid.css?1.0.0" type="text/css" media="screen,  projection">
<link href="http://asset1.test.local/css/blueprint/forms.css?1.0.0" type="text/css" media="screen,  projection">
<link href="http://asset1.test.local/css/blueprint/forms.css?1.0.0" type="text/css" media="screen,  projection">
<link href="http://asset5.test.local/css/blueprint/typography.css?1.0.0" type="text/css" media="print">
<!--[if lt IE 8]><link href="http://asset5.test.local/css/blueprint/ie.css?1.0.0" type="text/css" media="screen, projection"><![endif]-->

Можно обновлять версию автоматически при каждом деплойменте, чтобы не забыть.

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

Чтобы реализовать такое поведение, снова отредактируем конфиг:

framework:
    templating:
      assets_version_format  : %%s?v=%%s

И проверим, что же у нас получилось:

<link href="http://asset2.test.local/css/blueprint/reset.css?v=1.0.0" type="text/css" media="screen, projection">
<link href="http://asset3.test.local/css/blueprint/grid.css?v=1.0.0" type="text/css" media="screen,  projection">
<link href="http://asset1.test.local/css/blueprint/forms.css?v=1.0.0" type="text/css" media="screen,  projection">
<link href="http://asset1.test.local/css/blueprint/forms.css?v=1.0.0" type="text/css" media="screen,  projection">
<link href="http://asset5.test.local/css/blueprint/typography.css?v=1.0.0" type="text/css" media="print">
<!--[if lt IE 8]><link href="http://asset5.test.local/css/blueprint/ie.css?v=1.0.0" type="text/css" media="screen, projection"><![endif]-->

Как вы поняли в параметре assets_version_format задается шаблон для sprintf(). Только знак процента нужно дважды указывать для экранирования.

На этом на сегодня все. И сделаем свои приложения лучше... с Symfony2!

среда, 1 февраля 2012 г.

Видео с ZF Conf 2011

На сайте конференции ZFConf www.zfconf.ru выложили в открытый доступ видеозаписи докладов и слайдов с конференции, которая прошла 15 мая 2011 года в Санкт-Петербурге. До этого видео было платным.

Для получения доступа к разделу с видео нужно пройти по ссылочке http://www.zfconf.ru/2011/video/, ввести в форму имя и адрес электронной почты. Ссылка на закрытый раздел с видео будет выслана на адрес, который вы укажете.

Меня лично заинтересовали доклады товарищей из JetBrains и KnpLabs. Хотя представителей Геометрии и Sphinx тоже послушаю.

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

Единственный недостаток, в том, что в качестве хостинга видео выбрали Яндекс.Видео. Я всем сердцем ненавижу этот сервис.

Если есть желание предварительно посмотреть список докладов, это можно сделать тут.

UPD. Посмотрел несколько докладов:

1. Доклад Николая Матвеева "
Как может помочь среда разработки при написании приложения на Zend Framework?" - вообще можно не смотреть. PHPStorm - лучшая IDE, которая сейчас существует для PHP. И если вы раньше с ней не работали, только испортите первое впечатление невнятным докладом. Если работали - зря потратите время.

2. Доклад Константина Кудряшова про Behat тоже можно пропустить. Пиар и ничего больше. Хотя продукт, конечно, заслуживает внимания. Но лучше посетить офсайт и попробовать написать пару тестов.

3. "
Толстая модель: История разработки собственного ORM". Достаточно "живенько". В принципе, ничего особенно полезного нет, но интересно.

4. Доклад про Sphinx - тоже пиар. Но Sphinx я считаю, стоит пиарить, тем более так красиво, как это сделал докладчик :-)

понедельник, 30 января 2012 г.

Forma PRO. Join us!


Я работаю в компании Forma PRO. Слышали?.. Нет?.. Тогда слушайте :)

Я уже работаю тут год+. Сравнительно недавно, хотя, это как посмотреть, некоторые из моих друзей, бывало, меняли по три компании за год :)


В Forma PRO мы занимаемся разработкой web приложений. Работаем в основном с PHP фреймворками Symfony и Symfony2. Коллектив у нас небольшой: девять прогаммистов, один админ, один менеджер. Это не считая руководства.






Я не занимался никогда аудитом знаний у PHP разработчиков, но могу сказать, что средний уровень девелоперов в компании достаточно высокий.  При необходимости, есть к кому обратиться за советом или консультацией по архитектуре, тестированию, оптимизации или по работе с какой-нибудь библиотекой.  Кроме программирования  интересы и увлечения у нас самые разные: бильярд, сноубординг, автомобили, танцы, тренажерный зал, настольный теннис, футбол, сериалы, театр, кино и даже ролевые игры (но не те, где нужно в пациента и медсестру переодеваться :) ).


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


Если говорить о содержании работы. За год я успел поработать в нескольких проектах.  Два первых были небольшими и несложными, сроком около месяца каждый. Один из них был на CMF Apostrophe. Затем был проект побольше, уже на двух девелоперов и сроком около трех месяцев. Мы занимались переносом уже готового сайта на CMF Diem. Не очень интересно, зато я успел за это время неплохо покопаться в Diem'e. Следующий проект снова был маленьким, нужно было закончить небольшой сайт. Я просто переписал его на  Diem'е. Видимо, решив, что я уже в достаточной степени владею Symfony, мне доверили начинать новый проект самому. Он был написан где-то за месяц и получился в итоге достаточно интересным. Два последних проекта, в которых я работал, продолжаются и сейчас. Первый из них основывается на Symfony 1.4, в нем я проработал около трех месяцев. А с октября начал другой проект на Symfony2. На текущий момент маленьких проектов у нас не осталось и каждый сотрудник работает в более или менее крупной интернациональной команде. Например, в моей команде работает группа девелоперов из Бельгии и менеджер из Нидерландов.


Мне очень нравится подход к выбору проектов. Тут никогда не хватались и не будут хвататься за первую попавшуюся работу. Если предлагаемый проект не новый, мы делаем ревью, чтобы оценить качество кода. Если код не достаточно качественный, как правило, отказываемся от сотрудничества. Приницпиально не беремся за интернет-магазины, сайты-визитки, сайты построенные на различных CMS.




И, вообще, отличительная черта нашей компании - демократия в разумных пределах, не переходящая в анархию :) Большинство общих вопросов мы стараемся решить сообща, как правило путем дебатов и голосования :)


Рабочее время у нас не фиксированное. Есть договоренность, что сотрудник должен отработать 40 часов в неделю. Но никто не следит, во сколько ты приходишь или уходишь с работы. Я, обычно, работаю с 9 до 18. Основная масса сотрудников приходит на работу в 10-11 утра.



Стараемся проводить внутренние семинары, где обмениваемся опытом. Это бывает не так часто, как хотелось бы, но с покупкой проектора, думаю, что эти мероприятия станут более регулярными. Расположение офиса достаточно удобное. 5 минут до метро Пушкинская, 7 минут до метро Университет. Проблем с парковкой, как правило, не бывает.




В качестве дополнительной компенсации компания оплачивает сотрудникам обеды, ежедневный лимит на обед составляет 50 гривен. Обычно ходим небольшими компаниями в "Старгород", "Смак", "Якиторию" или, на худой конец, в "Терку".


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


В конференц руме у нас есть большой стол на котором теперь периодически устраиваем поединки по настольному теннису :)




Что касается корпоративных мероприятий, то таких масштабных мероприятий как в NixSolutions у нас не бывает. Впрочем, довольно часто выбираемся в боулинг или в паб, или еще куда-нибудь. В августе ходили в поход на байдарках.


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


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






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


Какие знания лучше будет прихватить с собой на собеседование? Обязательно нужно знать PHP и ООП, нужны уверенные знания по MySQL и кончено же нужно иметь общее представление о принципах WEB-разработки. Все остальное не является строго обязательным. Но конечно же учтется при приеме на работу умение верстать, javascript, тестирование, опыт работы с применением agile практик, владение популярными фреймворками (особенно Symfony, Zend, Doctrine) и т. д.
Собеседовать, скорее всего, будут 3 человека. Директор, менеджер и один из разработчиков. После успешного прохождения собеседования испытательный срок для джуниор девелоперов составит 2 месяца. Для разработчиков с более выскокой квалификацией, как правило, испытательный срок длится один месяц.


Вот и все, что я хотел рассказать о своей работе. Надеюсь увидеть кого-нибудь из читателей моего блога у нас на собеседовании.