PHP 5.4 установка из DotDeb

Если Вам вдруг захотелось использовать последнюю версию php-5.4.x на Debian squeeze (где по-умолчанию из пакетов устанавливается php-5.3.x),
будет проще и быстрее установить его с помощью apt-get.
Первым делом необходимо добавить новые источники пакетов в файл sources.list:

deb http://packages.dotdeb.org squeeze all
deb-src http://packages.dotdeb.org squeeze all
deb http://packages.dotdeb.org squeeze-php54 all
deb-src http://packages.dotdeb.org squeeze-php54 all

Вы может получить такую ошибку при обновлении кеша:

W: GPG error: http://packages.dotdeb.org stable Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY E9C74FEEA2098A6E
W: GPG error: http://nginx.org squeeze Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY ABF5BD827BD9BF62

в этом случае необходимо добавить ключи и повторно обновить кеш:

gpg --keyserver keys.gnupg.net --recv-key 89DF5277
gpg -a --export 89DF5277 | sudo apt-key add -
gpg --keyserver keyserver.ubuntu.com --recv-key ABF5BD827BD9BF62
gpg -a --export ABF5BD827BD9BF62 | sudo apt-key add -
sudo apt-get update

Ну а теперь просто обновите установленные пакеты и обязательно нужно проапгрейдить дистрибутив:

sudo apt-get upgrade
sudo apt-get dist-upgrade

Как скомпилировать и установить php-5.4.x на Debian OS (squeeze)

Недавно я попытался установить последнюю версию PHP 5.4.x (на момент написания статьи это было 5.4.10) на мою стабильную ОС Debian OS (v6.0-squeeze-32bit).
Как вы возможно знаете, стабильная версия Debian имеет по-умолчанию в своих репозиториях версию PHP-5.3.4. Я же захотел использовать встроенный в PHP-5.4 веб-сервер.
Тогда мне казалось, что установка PHP-5.4 будет более быстрым процессом, чем конфигурированию виртуального хоста Apache. Да, я настолько ленив! 🙂
Что ж, забегая наберед, должен сообщить, что вся процедура заняла у меня 2-2.5 часа времени пока я смог запустить свои скрипты.
По правде говоря, то был первый раз когда я компилировал PHP из исходников, зато теперь я чувствую, что получил замечательный опыт в этом деле!
Ладно, давайте пройдемся по процессу пошагово.

Во-первых, вам может понадобиться установка Linux библиотеки «libxml2-dev» (хотя я не помню зачем..)
А, вспомнил! Похоже, что вы не сможет сконфигурировать PHP установщик без этой библиотеки!

sudo apt-get install libxml2-dev

Также я уверен, что большинству веб-разработчиков прийдется работать с БД из скриптов (скажем, MySQL), а в частности с расширением PDO.
Поэтому, вам необходимо скомпилировать PHP с такими опциями:

configure --with-pdo-mysql --with-mysql

(обратитесь к http://php.net/manual/en/ref.pdo-mysql.php за детальным пояснением)

Обычно, хороший разработчик активно использует дебаггер в его каждодневной работе. Как нам всем известно, самым популярным PHP отладчиком является xdebug. Это расширение может быть установлено из pecl репозиториев.
Но, прежде чем просить pecl установить для нас xdebug, удостовертесь, что у вас установлены пакет разработки php5-dev.
С этим пакетом поставляется phpize, что является необходимым условием для установки PHP пакетов через pecl.
Если у вас еще не установлен php5-dev, вы получите следующее сообщение об ошибке:

ERROR: `phpize’ failed

и вот вам команда в помощь:

sudo apt-get install php5-dev

После этого, вы сможет установить xdebug с помощью pecl:

sudo pecl install xdebug

Идем дальше. Скажем, вам приходится работать с документами, написаными не только на английском, но и на других языках (Итальянский, Португальский, Русский, Немецкий и т.д.). И предположим также, что вам необходимо обрабатывать даты в различиных форматах, который встречаются в таких документах (кстати, об этом будет моя другая публикация).
Здесь на помощь приходит расширение php5-intl! По этой ссылке — http://php.net/manual/en/intl.installation.php — вы найдете детальную информацию.
В двух словах, чтобы включить это расширение, необходимо указать опцию:

configure --enable-intl

Если вдруг конфигуратор PHP сообщит о следующей ошибке:

«configure: error: Unable to detect ICU prefix or no failed. Please verify ICU install prefix and make sure icu-config works.»

вам понадобится установить пакет Linux для работы с интернациональными данными (icu — International Components for Unicode):

apt-get install libicu-dev

Для того, чтобы иметь возможность загружать удаленные http ресурсы из ваших php скриптов, понадобится включить php5-curl.
У меня не получилось сделать это без дополнительных телодвижений, ибо я получил сообщение об ошибке следующего содержания:

configure: error: Please reinstall the libcurl distribution

Если у вас похожая ситуация, то попробуйте установить такие Linux пакеты:

sudo apt-get install libcurl4-gnutls-dev

(спасибо to http://phpconfigure.com/2011/04/configure-error-please-reinstall-the-libcurl-distribution/)

Если вам необходимо работать с мультибайтовыми кодировками и использовать функции PHP с префиксом mb_*,
понадобится включить и эту опцию:

configure --with-mbstring

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

sudo ./configure --with-pdo-mysql --with-mysql --with-curl --enable-intl --enable-mbstring=all

Что ж, как я и сказал, я надеялся, что установка PHP-5.4 займет у меня меньше времени, чем конфигурирование виртуального хоста Apache.
Как же я ошибался!.. 🙂
Тем не менее, я ни капельки не сожалею о своем выборе, ибо теперь я чувствую себя намного уверенне в области конфигурирования и установки PHP.
Мой профессиоальный уровень вырос и я открыл для себя новые интересные вещи.

Буду рад ответить на ваши вопросы и комментарии.

Fn клавиши перестали работать на Lenovo Thinkpad Edge с Debian

Однажды на моем рабочем ноуте Lenovo Thinkpad Edge 15 внезапно 🙂 перестали работать ВСЕ функциональные клавиши (регулировка яркости, громкости, управление камерой и микрофоном, wi-fi). Я не гуру в низкоуровневом Linux и всяких там acpi events… Периодически и долго пытался найти решение проблемы в интернете, но особо не зная куда копать, искал по acpi, fakekeys, Debian (установленная ОСь на ноуте)… К сожаление, не нарыл ничего. Пока однажды волей случая не набрел на замечательный форум, где было предложено неожиданное решение проблемы…
Всё дело оказалось в том, что это глючит BIOS на Lenovo Thinkpad Edge!! 🙁
Т.о., дабы вернуть состояние bios и ноута к прежнему, необходимо просто отключить питание от ноута и вытащить батарею на время около минуты или чуть больше. Это приведет к сбросу bios и acpi до состояния мо-умолчанию.
Спасибо ребятам за предложенное решение проблемы!

Как скачать аудио из ВКонтакте

Небольшой скриптец, который поможет вам создать список URL адресов mp3 файлов, который можно затем «скормить» какому-нибудь Download Master.
Сей скриптец нужно запускать в консоли FireBug (расширение к броузеру FireFox, ориентированное на программистов), находясь при этом на странице «Мои аудиозаписи».
В результате выполнения в консоль будет выведен список адресов аудифайлов вашего плейлиста. Копируете список в текстовый файл, который потом импортируете в Download Master через пункт меню File -> Import. Вуаля! Файлы качаются! Единственная проблемка — названия. Это уникальные идентификаторы файлов, а не понятные человеку слова. Хотите — переименуйте вручную, а хотите — потом можно написать скриптец, скажем на PHP, который прочитает ID3-тэги файлов и переименует файлы с использованием нормальных названий.
Собственно, сам скрипт:

var hiddenFields = document.getElementsByTagName("input");
var mp3s = [];
function getHiddenField(elem, index, collection){
    if(elem.getAttribute("type") == "hidden" && (/audio_info\d+_\d+/).test(elem.getAttribute("id"))){
        mp3s.push(elem.getAttribute("value").split(",")[0]);
    }
}
for(var i=0; i < hiddenFields.length; i++){
    getHiddenField(hiddenFields[i], i, hiddenFields);
}
console.log(mp3s.join("\n"));

Form builder — entity field: «Class BundleAliasName:EntityClassName does not exist «

После обновления symfony-2.1 до версии из транка (symfony-2.1.0-beta4) отвалилась форма, в которой я использовал поле типа entity, где в качестве класса сущности указал не полный путь к классу, а через bundle alias:

$builder
            ->add(
            'field_name,
            'entity',
            array(
                 'class' => 'BundleAliasName:EntityClassName',
                 'multiple' => true
            )
        )
.....

Код выбрасывал исключение с сообщением

«Class BundleAliasName:EntityClassName does not exist»

Если прописать полный путь через пространство имен:

array(
    'class' => 'Full\Bundle\Path\Entity\EntityClassName',
)

то все работало хорошо.
Я открыл по этому поводу тикет и оказалось, что дело в версии Doctrine! Обновление до 2.3 решило проблему!
Огромное спасибо автору комментария на гитхабе Christophe Coevoet!

Как обновить проект с symfony-2.0 до symfony-2.1

Изначально я создавал свой проект на версии symfony 2.0 без vendors (standard edition). Все зависимости были установлены через

php bin/vendors install

Проект находился в git-репозитории.

Сразу оговорка — на момент написания статьи версия symfony 2.1 находилась в стадии бета-тестирования.
Тем не менее, основная тенденция уже была понятна и значительных изменений в АПИ не предвиделось.
Одно из ключевых нововведений в symfony 2.1 — использование Composer.
На вебсайте фреймворка Symfony можно найти описание процесса создания нового проекта, но нет информации как обновить существующий.

Итак, начнем-с.
Изначально я попытался просто скопировать содержимое файла composer.json, находящегося в директории фреймворка Symnofy на github, и выполнить команду

php composer.phar update

но там нет всех зависимостей, необходимых для нормального функционирования проекта.
Потому я просто решил создать новый «пустой» проект:

php composer.phar create-project symfony/framework-standard-edition path/

в отдельной ветке git-репозитория и потом перенести изменения из ветки с версией symfony-2.0.

Признаюсь, что пришлось порешать конфликты в файлах apps/AppKernel.php, файлах config.yml, security.yml и других.
Но это не было слишком сложным заданием.
Также необходимо проапгрейдить все дополнительные bundle, которые вы используете до соответствующих версий под symfony-2.1
К примеру, для FOSUserBundle (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#installation)

{
    "require": {
        "friendsofsymfony/user-bundle": "*"
    }
}

и далее выполнить команду

php composer.phar update

Таже необходимо сделать изменения согласно этой инструкции в файлах форм и других местах. Тут уже дело персональное — смотря кто какие фичи использовал в своем проекте.

Таким образом, после всех проделанных манипуляций проект запустился успешно.
Из видимых изменений — добавили красивостей к web-debug-toolbar — появились тултипы со сводной информацией по каждому из разделов, которые показываются при наведении мышью на соответствующую иконку.

П.С.: Вот на днях встретил другой вариант апгрейда до symfony-2.1: http://buildthedamnproduct.com/upgrading-symfony-to-21-10415

Composer — minimum-stability по-умолчанию считается stable

Сегодня (4 июля 2012) Composer изменяет значение по-умолчанию свойства stability с dev на stable.
Подробнее здесь и здесь.
Что это значит? Что по-умолчанию Composer будет игнорировать пакеты RC, beta, alpha или dev.
Столкнулся я с этим, когда попытался проапдейтить зависимости проекта, использующего symfony-2.1.x, которая на момент написания заметки находится на стадии бета-тестирования.


rodush@debian:~/gtrs$ php composer.phar update
Updating dependencies
Your requirements could not be solved to an installable set of packages.

Вот что подсказал скрипт:

Potential causes:
— A typo in the package name
— The package is not available in a stable-enough version according to your minimum-stability setting
see https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion for more details.

Чтобы обойти данную проблему, самый простой способ — это в файл composer.json добавить свойство
"minimum-stability": "dev"

symfony 2.0 FOSUserBundle — ошибка «Could not load type»

Если вы используете FOSUserBundle вместе с symfony 2.0 и вам понадобилось переопределить какую-либо из форм, идущих «в комплекте» с этим плагином,
то, без сомнения, вы прочитали эту заметку: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_forms.md
После обновления вашей страницы может случиться прискорбная ситуация — сообщение об ошибке «Could not load type ….» (вместо многоточия ваш alias для кастомной формы).
Вроде бы и в файле app/config.yml все верно с отступами (имеется ввиду конфигурация fos_user сервиса), и файл конфигурации вашего сервиса service.xml (service.yml) (в CustomUserBundle) описан правильно, и везде совпадает alias, getName() и т.п…. а все та же ошибка. Бывало? Не беда! 🙂 Есть решение вашей проблемы! Читайте далее, и все окажется просто!

Чтобы понимать и правильно использовать services и dependency injection в symfony 2.x, крайне рекомендую прочитать это и это. Суть в том, что для того, чтобы фреймворк symfony увидел ваши сервисы и расширения, необходимо предоставить информацию о конфигурации вашего bundle.
Сделать это можно двумя способами.

1. Стандартная конфигурация сервиса.
Вы можете описать ваши сервисы в файле конфигурации (services.yml, services.xml, etc.) который находится внутри вашего бандла и потом просто заимпортировать этот файл в основной файл конфигурации всего приложения. Это действительно простой, быстрый и неимоверно эффективный способ.
Пример:

imports:
- { resource: parameters.ini }
- { resource: security.yml }
- { resource: @CustomUserBundle/Resources/config/services.xml }

2. Семантическое описание конфигурации.
Данный способ используется для конфигурации ядра symfony. Основная идея заключается в том, что вместо того, чтобы заставлять пользователя переопределять все параметры, вы предоставляете ему возможность задать лишь некоторые, специально созданные опции. Ваша роль, как разработчика банда, заключается в том, чтобы разобрать такую конфигурацию и подгрузить необходимые сервисы внутри класса «Extension». Используя данный метод, вам больше не нужно импортировать кофигурационные ресурсы в ваш основной файл конфигурации проекта — этим займется файл расширения (Extension).
Этот способ подробно описан во второй из приведенных выше ссылок.

Итак, возвращаясь к природе нашей ошибки. Суть дела вот в чем: может случиться так, что «кастомный» бандл для Пользователя (User) вы создавали вручную (путем копирования из существующего бандла необходимых файлов и директорий), а не при помощи консольной команды симфони (generate:bundle).
При этом, вы могли забыли создать директорию DependencyInjection и в ней файл CustomUserExtension.php и Configuration.php.
Или же, если вы не думали использовать возможности семантической конфигурации, то забыли заимпортировать файл конфигурации CustomUser сервиса в ваш основной файл проекта.

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

JavaScript — как удалить пробелы в начале и конце строки (trim)

Уже миллионы раз написано, но вставлю и я свои «5 копеек» в тему.
В javascript нет встроенной функции для обрезания лишних пробелов в начале и конце строки.
Чтобы реализовать такую возможность можно добавить необходимый метод в объект String javascript:

String.prototype.trim = function(str) { return str.replace(/^\s+|\s+$/g, ""); }