Functional approach in PHP

The code snippet below will only work in PHP-5.3+!.
Isn’t it the famous functional programming with functions as first class citizens, closures and other functional bla-bla?

<?php
 
function one($a = 0) {
    return function(callable $b) use ($a) {
        return call_user_func($b, $a);
    };
}
 
print_r(call_user_func(one(1), function ($x) { return $x + 4; } ));

This was created just for fun. As you may see, in place of callable you can put any valid PHP callable, e.g.in a form ['Class', 'method']

Use your imagination for other real things, but also try to stay not cursed later by those who will inherit your untraversable codebase :LOL:

[SOLVED] Upgrading from PHP 5.5 to PHP 5.6 on Ubuntu 12.04 LTS

Recently I had to upgrade PHP version on the build server based on Ubuntu 12.04 LTS to PHP 5.6 At that moment there was PHP 5.5 installed on the server. Everything should have been as easy and promising as described, for example, in this post. Yes, it was going well to the moment

sudo apt-get dist-upgrade

Then dpkg claimed unmet dependencies… You know, as usual. I decided — f…k it, I will remove existing php and everything related. Simple removal with

sudo apt-get remove php*

did not work fine and stuck on removing phpmyadmin.

That guysexited with an error code 10 being reported from its post-remove script. After pretty short googling, I found the solution which worked for me.

The similar shit happened with php5-imagick package, so the solution I used was similar to phpmyadmin removal. Afterwards, I checked for presence anything starting with or inlcuding php:

sudo dpkg -l | grep php

Everything was clean. OK, here we go…

sudo apt-get clean && sudo apt-get autoclean
sudo apt-get udpate && sudo apt-get upgrade && sudo apt-get dist-upgrade

…and still the same error in result:

Reading package lists… Done Building dependency tree Reading state information… Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: php5 : Depends: libapache2-mod-php5 (>= 5.6.16+dfsg-2+deb.sury.org~precise+1~) but it is not going to be installed or libapache2-mod-php5filter (>= 5.6.16+dfsg-2+deb.sury.org~precise+1~) but it is not going to be installed or php5-cgi (>= 5.6.16+dfsg-2+deb.sury.org~precise+1~) but it is not going to be installed or php5-fpm (>= 5.6.16+dfsg-2+deb.sury.org~precise+1~) but it is not going to be installed E: Unable to correct problems, you have held broken packages.

I tried install with -f flag, package-by-package. Nothing worked. The final unmet dependency was:

sudo apt-get -f install php5-json
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
 
The following packages have unmet dependencies:
 php5-json : Depends: phpapi-20121212
E: Unable to correct problems, you have held broken packages.

And here I stuck, as googling at this point didn’t help me at all… I visited the home of php5.6 PPA hoping to find something there. And a brilliant idea came to my mind — I should check APT’s sources list! I saw this files inside /etc/apt/sources.list.d:

/etc/apt/sources.list.d$ ll
total 32
drwxr-xr-x 2 root root 4096 Jan  5 11:12 ./
drwxr-xr-x 6 root root 4096 Jan  5 11:11 ../
-rw-r--r-- 1 root root  138 Jan  5 10:32 chris-lea-node_js-precise.list
-rw-r--r-- 1 root root  138 Jan  5 10:32 chris-lea-node_js-precise.list.save
-rw-r--r-- 1 root root   60 Jan  5 10:32 nginx-stable-lucid.list
-rw-r--r-- 1 root root   60 Jan  5 10:32 nginx-stable-lucid.list.save
-rw-r--r-- 1 root root  134 Jan  5 10:32 ondrej-php5-5_6-precise.list
-rw-r--r-- 1 root root  134 Jan  5 10:32 ondrej-php5-5_6-precise.list.save
-rw-r--r-- 1 root root  126 Jan  5 10:32 ondrej-php5-precise.list
-rw-r--r-- 1 root root  126 Jan  5 10:32 ondrej-php5-precise.list.save

I realised, the problem could be that packages were overwritten from older php-5.5, which apparently was installed manually to the server some time earlier. Once I removed these two files:

ondrej-php5-precise.list ondrej-php5-precise.list.save

and updated apt one more time, I was able to install PHP 5.6 as usual:

sudo apt-get install php5
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  shtool libc-client2007e node-node-uuid libicu52 libicu48 libv8-3.7.12.22 libmcrypt4 libt1-5 mlock libssl-dev libvpx1 libssl-doc zlib1g-dev libgd3 libev4 libv8-dev libc-ares2 libev-dev
  libc-ares-dev
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
  libapache2-mod-php5 php5-cli php5-json php5-readline
Suggested packages:
  php-pear
The following NEW packages will be installed:
  libapache2-mod-php5 php5 php5-cli php5-json php5-readline
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 5,575 kB of archives.
After this operation, 18.9 MB of additional disk space will be used.
Do you want to continue [Y/n]? Y

The main idea of this story, before adding new custom repository for PHP, make sure you removed any other old ones! Good luck and happy coding!

Как скомпилировать и установить 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.
Мой профессиоальный уровень вырос и я открыл для себя новые интересные вещи.

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

PHPMyAdmin session timeout

По-умолчанию время жизни сессии в новой инсталляции PhpMyAdmin и способе авторизации ‘cookie’ составляет 1440 секунд (24 минуты). Т.е. после 24 минут бездействия следующее обращение приведёт пользователя на страницу авторизации. Чтобы увеличить время жизни сессии, необходимо установить значение переменной

$cfg['LoginCookieValidity'] = 1440 * 60; // 86400 means one day (24-hours)

, скажем в 60 раз, что составит сутки.