Я — именитый писатель
Один из самых знаменитых и популярных писателей Евгений Владимирович Степанищев полноценно представлен в книжном каталоге интернет магазина OZON. У нас вы найдете, как лучшие книги бестселлеры, так и новинки 2013 года, которые написал автор . Кроме этого вы можете ознакомиться с краткой биографией писателя, посмотреть его фото и полный список литературы, к авторству которой, он причастен. Перед тем как купить книгу, которую написал Евгений Владимирович Степанищев вы можете прочитать отзывы читателей или анотацию к ней.
Жена на «Озоне» нашла (в самом низу страницы).
Конструкция «??»
В ПХП 7 появилась, наконец, конструкция, которая должна была быть в языке с первых версий:
echo $_GET['var'] ?? 'default'; // PHP 7
echo isset($_GET['var']) ? $_GET['var'] : 'default'; // PHP 5.6 и нижеОчень похоже на тернарный оператор без средней части, появившийся в версии 5.3, но с одним отличием: проверяется не ложь или истина, а существование.
Теперь в ПХП можно писать намного более эмоционально:
echo X-D ? :-D ??!! O_o; // это работает в PHP 7, я даже могу сказать что это значит.Может
git clone https://github.com/php/php-src.git
cd php-src
brew install re2c
brew info bison27
PATH=/usr/local/opt/bison27/bin/:$PATH
./buildconf
./configure --prefix=/opt/php-5.7 --disable-all
make
make installКто крайний присаживаться?
Азбучная истина № 6. Подойдя к очереди в кассу или ко врачу в поликлинике, грамотно спросить у людей: кто последний? Предлагая гостю принять сидячее положение, вежливо сказать: садитесь, пожалуйста. А «кто крайний?» и «присаживайтесь» — это неправильно.
Пишет В. М. Пахомов, кандидат филологических наук, главный редактор портала Грамота.РУ.
JSOND
JSOND — это ещё один «дешёвый» способ увеличить производительность вашего проекта на ПХП, наряду с igbinary. Исходный код есть на PECL, для всех систем существуют пакеты. Насколько я знаю, есть планы по замене стандартного расширения JSON в ПХП7 на JSOND.
Для интереса погонял стандартный тест пакета на одной из наших машин (мы там вчера перешли на ПХП 5.5
STR: {"i": 23, "array": [1, null, false, true, ["aha", "baba", 23, {"test": 23}]]}
JSON: time for 100000 iterations: 1.096384
JSOND: time for 100000 iterations: 0.353658
STR: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
JSON: time for 100000 iterations: 0.700904
JSOND: time for 100000 iterations: 0.202519
STR: {"a": 23.2234232}
JSON: time for 100000 iterations: 0.398129
JSOND: time for 100000 iterations: 0.083977
STR: сериализуется очень длинная строка
JSON: time for 100000 iterations: 0.392990
JSOND: time for 100000 iterations: 0.341663
STR: сериализуется переменная $_SERVER
JSON: time for 100000 iterations: 4.983888
JSOND: time for 100000 iterations: 2.321528Что приятно, АПИ полностью совместимо, так что проблем нет никаких — в вызовах надо просто добавить одну букву. Есть так же несложный способ самостоятельной замены стандартного JSON на этот модуль в интерпретаторе.
Эксперт
Помните этот известный ролик про приглашённого эксперта по рисованию красных линий? Я
Напомню в чём суть: в ролике эксперта просят подтвердить, что компания сможет нарисовать семь красных линий, строго перпендикулярных друг другу, некоторые — зелёным цветом, некоторые — прозрачным, причём одна из них должна быть в форме котёнка.
Меньше всего проблем вызвала бы перпендикулярность всех линий. Что тут сложного? В ролике нет требования, что линии должны быть прямыми, а если бы и было, детские эксперименты с лентой Мёбиуса подсказывают нам, что можно придумать поверхность с самыми чудны́ми свойствами. Легко вообразить и такую, где можно провести семь прямых линий, перпендикулярных друг другу.
Линия в форме котёнка решается ровно так же — формой поверхности. Изогнём путь одной линии так, чтобы она повторяла силуэт котёнка.
Опять же не очень сложно сделать прозрачные красные линии — надо всего лишь нарисовать их
Загвоздка с зелёным. Но если вспомнить анекдот про Роберта Вуда и светофор, то можно предложить разогнать наш объект до скорости 60 000 км/сек — на этой скорости красный свет
Это, кстати, не единственный вариант, можно попробовать выбрать оттенок красного, в котором содержится зелёный и осветить нужные нам линии чистым зелёным светом — тогда именно он и отразится. Либо, добавить в красный краситель фосфор —
Оказывается (спасибо, Ирек, что показал) существует
Виллиамсон рисует линии «используя зелёные чернила» (two drawn using green ink), в английском
Приходится признать, что в мире существуют эксперты по красным линиям круче меня!
Кухня блокадного Ленинграда
Читая в «Википедии» статью про Игоря Растеряева, увидел упоминание некой «хряпы» и «дуранды», никогда слов этих не слышал, заинтересовался. Оказывается, это упоминались названия со стола блокадников в Ленинграде.
Дуранда — это жмых от подсолнечного масла: плотные,
Хряпа — верхние капустные листья, которые остаются на поле после уборки кочанов. Обычно в пищу людьми не употребляются, используются как корм скоту. Чтобы отбить горечь, их вымачивают и засаливают.
Процедурное настоящее PHP
ПХП, к сожалению, в сердце ещё глубоко процедурный язык. Наткнулся на очередную особенность. Сначала небольшая предыстория.
Многие знают, что FastCGI в ПХП не настоящий — при каждом запросе весь код интерпретируется заново, это позволяет не заботиться об утечке памяти, сбросе состояния между запросами и ещё о многих вещах, а значит упрощает вообще всё, что соответствует духу ПХП — понизить до минимума порог вхождения. Конечно, это сказывается на производительности, но в некоторых случаях ПХП научился смягчать этот недостаток.
Например, есть такая вещь как «постоянные соединения» (persistent connections) — это специальные режим, в котором на уровне процесса PHP FastCGI соединения
Конечно,
Как известно, ПХП может свалиться в фатальной ошибкой по многим причинам, одна из них — превышение времени обработки скрипта. Соответственно, скрипт может упасть и в середине транзакции, она останется незакрытой и может остаться висеть долгое время, пока соединение не получит скрипт, в котором встретится команда закрытия транзакции.
А пока этого не произошло, блокировки на базе могут привести к коллапсу.
Как показывает практика, должен, но не обязан. Ниже простой код:
class ImportantToClose {
public function __destruct()
{
// закрываем что-то важное
echo "Вызвался деструктор\n";
}
}
$itc = new ImportantToClose;
register_shutdown_function(function() {
echo "Вызвалась shutdown function\n";
});
set_time_limit(1);
for(;;);Если запустить его в интерпретаторе и подождать секунду, то мы получим следующую ошибку:
PHP Fatal error: Maximum execution time of 1 second exceeded in fatal.php on line 18
Fatal error: Maximum execution time of 1 second exceeded in fatal.php on line 18 Вызвалась shutdown function
Можно ещё попробовать записать
Кстати, не забудьте выставить внутри shutdown function нужное вам время выполнения, если предел будет превышен, то и эта функция будет прервана, в этом случае вам уже ничего не поможет закрыть ресурс корректно.
ENUM
Не понимаю, почему в «Оракле» (это СУБД) нет такой полезной вещи как тип ENUM. Вещь совершенно необходимая, как по мне. Вот посмотрите, что понятнее:
CREATE TABLE event_queue (
…
status ENUM('done', 'new', 'failed', 'running'),
…
);или
CREATE TABLE event_queue (
…
status NUMBER(1), -- тут у нас 4 значения будет
…
);Я
Кроме удобства программиста, есть очевидная польза и для самой СУБД. Например, возьмём запрос к таблице выше, где мы определили поле status как число. Мы знаем, что статусов у нас всего четыре, это знаем мы, но это не знает «Оракл». Теперь взглянем на два совершенно эквивалентных с точки зрения программиста запроса (ведь он знает, что значений четыре) и посмотрим планы их выполнения:
SELECT *
FROM event_queue
WHERE status IN (1,2)
AND target='search' AND attempts < 3

SELECT *
FROM event_queue
WHERE status NOT IN (3,4)
AND target='search' AND attempts < 3

Как видите, разница в стоимости аж в три раза. Спрашивается, почему? Ответ очень простой, конечно: в первом случае если status оказался равен единице, вторая проверка уже не нужна, во втором случае, всегда нужны обе проверки. Почему цифры отличаются именно в два раза, а не в три, я не скажу, это, видимо, прикидка, основанная на статистике использования этой таблицы — одно из этих значений (статус «задание провалено») вообще ещё ни разу не записывалось.
Вообще, есть несколько способов имитировать тип ENUM: добавить ограничение (check), ввести новый тип. Но первое никак не сказывается на плане и требует перехода к строковому типу, а со вторым я ещё не эксперементировал.
Обладая Оракл информацией о том, что у нас в этом поле всего четыре возможных значения в этом поле, он мог бы запросто инвертировать значения и снизить стоимость.
«Открылся у нас новый бааар»
С ДДТ меня познакомил Дима Мартынов, друг детства, с которым мы дружили всю школу, а потом, когда он уехал в Ульяновск, а позже и в Питер, мы остались приятелями. Я был типичным «ботаником», только очков не носил, заучкой тоже не был, у меня была «своя атмосфера» — школа мне была неинтересна, я постигал реальность самостоятельно. На моё отношение к жизни песни группы ДДТ ложились как нельзя лучше, так же как и «Агаты Кристи», «Нау», «Пикника», «Аквариума» и некоторых другие.
Ничего из этого списка, кроме ДДТ, кстати, я в настоящее время не слушаю. Ещё с детства помню выкрик фаната «открылся у нас новый бааар», который я уже более 20 лет слышу на записи песни «Я зажёг в церквах все свечи». Всё подряд я не слушаю даже у самых любимых групп, поэтому немудрено, что я не знал, что это то ли заказ песни из зала, то ли фанат спутал вступление.
Сегодня погуглил эту реплику (за 20 лет она обязана была обрести известность) и вот что нашёл:
Много лет перед «Я зажёг в церквях все свечи» я слышал хрип уфимского поклонника «открылся у нас новый бааанк». Причём здесь банк, думал я.
Какая-то странная, зрительская реклама. Когда, в конце90-х стали перевыпускать ранние альбомы, и я услышал песню 82 года «открылся у нас новый бар», всё стало предельно ясно. Но какие там бары, когда зажигаются свечи? Эти мелкие реплики не затёрли при последующем сведении концертного альбома. Не знаю, специально, или сложно было технически.
По мне такие огрехи добавляют живости, а по прошествии стольки лет чистить их просто нельзя — они уже стали частью той записи, при прослушивании губы сами шепчут в нужном месте «открылся у нас новый бааар».
«Берегиня»

На сайте Студии Лебедева увидел шрифт «Берегиня». Это стилизация кириллического и латинского шрифтов под стиль белорусского орнамента (красная полоса над «приветом» — это он). Там есть даже цифры и знаки препинания!
В заметке про шрифт написано (на белорусском), что он может использоваться как декоративный для оформления заголовков, а по мне так лучше использовать его как субкультурный маркер для славянофилов. Сразу вспоминается
Многие начертания, как мне показалось, можно было сделать проще, но,
Чтение сильно затрудняет пробел — чтобы в этом месте не было провала, автор нарисовал очередную «загогулину», поэтому разрыва слов не видно. Но понимаю зачем это сделано — в традиционных орнаментах никаких разрывов и нет.
Вот вам загадка

Как вы думаете, для чего предназначалось белое прямоугольное устройство в центре кадра? Производилось в восьмидесятые. Правильный ответ вечером или когда
Недокументированный Memcached-2
У модуля Мемкешед для ПХП удивительно плохо с документацией, я иногда заглядываю в его исходники, с целью почитать. Недавно наткнулся на очередную опцию, описания которой в документации нет (причём в документации аналогичного модуля для Пайтона она есть).
Оказываются UDP не единственный способ ускорить работу с Мемкешед, если вам скорость важнее результата операции. Способ хорош тем, что используется протокол TCP (т. е. с гарантированной доставкой), но мы не ждём — нам главное, что
Посмотрите на пример и обратите внимание на опцию OPT_NOREPLY.
$m = new Memcached;
$m->addServer(0, 11211);
$val = str_repeat(file_get_contents('/etc/passwd'), 200);
$m->set('key', $val);
$m->setOption(Memcached::OPT_NOREPLY, true);
$m->setOption(Memcached::OPT_COMPRESSION, false);
$time = microtime(true);
$m->append('key', $val);
echo number_format(microtime(true) - $time, 4, ',', ''), "\n";Кстати, такое большое (как в примере) значение мне потом обратно прочитать не удалось, видимо превысил
Интересно, что можно делать несколько операций append подряд, очерёдность их сохраняется, корректность прочитанного — тоже. Вот только непонятно не может ли чтение получить данные между двумя append, скорее всего — может, но этот способ как раз для случаев, когда на первом месте скорость записи к кеш.
Отключение 4G (LTE) в HTC One
Я тут утопил свой замечательный смартфон «Хайскрин», который живёт неделю на зарядке и временно использую прежний смартфон жены —

По сравнению со вчерашним временем работы — просто небо и земля.
37! ≈ 1,37×10⁴³

Итак, что же произошло у меня в жизни за минувший год, с прошлого Дня рождения:
- я прочитал 44 книги
- попробовал свои силы в PHPF*ck’е, плотно поработал с поисковым движком «Сфинкса» (в итоге написал поисковик, хранящий данные в памяти на Гоу), написал автоподбиралку для словохвата, заказал себе свитер памяти Стива Джобса, возобновил заполнение раздела «99»
- добавил в «Неглупый дом» «глазок» на входе в квартиру, фото посетителей
за дверью, температуру в прихожей, а потом благополучно похоронил проект - в очередной раз побывал в Самаре, в первый — на
Шри-Ланке , в Армении (в Ереване), Азербайджане (Баку и Гобустане), Испании (вСанта-Сусанне , Рупите, Бесалу, Барселоне и Кастеллфоллите де ла Роса), Андорре (Ординои Андорра-Ла-Велья) и Франции (в Фуа и Каркассоне) - придумал
CSS-хаки для IE10 и для Хрома (исключая «Сафари») - купил турник и научился подтягиваться на одной руке, а так же вернул в число своих хобби Pump It Up, купил велосипед и летом ездил на работу на нём, а так же поучился кататься на мотоцикле, но пока не уверен, что это моё
- стал, наконец, «москвичом» — теперь у нас в собственности с женой есть квартира в пределах МКАД
- поддержал небритябрь
- в дереве предков добрался до начала некоторых фамилий, постепенно распутываю клубок, всё бо́льшая часть моих предков причисляется к однодворцам, а так же мои изыскания в некоторых ветках «добили» до
18-го века и, наконец, научился довольно уверенно читать скоропись того времени - прошёл генетическое исследование, которое, похоже, оказалось неверным (ещё напишу, когда получу результат)
- пережил два тяжёлых кризиса (не уверен, что оправился до конца хотя бы от одного)
- в очередной раз попал на «Баш»
- пострелял боевыми патронами
- ощутил свой профессиональный рост — в руководстве процессами
- в первый раз в жизни перевёл в электронный вид книгу — «Четверо под одной обложкой» Арканова, Горина, Успенского и Камова
Вцелом, кажется, стал меньше писать в блог и бо́льшую часть своей творческой энергии отдавать в проект, разработкой которого я руковожу — это система облачного документооборота.
Преобразование tnsnames.ora в JSON
По работе сделал разбор файла tnsnames.ora — файла оракловой конфигурации на ПХП в массив:
function Ora2Array($str)
{
// убираю комментарии
$str = preg_replace('/^\s*#.*$/m', '', $str);
// преобразование скаляров
$str = preg_replace('/\((\w+)\s*=\s*([^()]+)\)/m', '"$1": "$2", ', $str);
// преобразование ассоциативных массивов
do {
$str = preg_replace('/\((\w+)\s*=\s*([^()]+?)[\s,]*\)/sS', '"$1": { $2 },', $str, -1, $count);
} while ($count);
// преобразование верхнеуровневых значений
$str = preg_replace('/(\w+)\s*=\s*([^()]+?)[\s,]*(?:(?=\w+\s*=)|\s*$)/s', '"$1": { $2 },', $str);
return json_decode('{' . trim($str, ' ,') . '}', true);
}Не разбираются значения в кавычках — такого в наших конфигурациях не встречается, но добавляется несложно.
Сцорпероба
«Сцорпероба» — в дословном переводе означает «ровные по цвету». Молодой мужчина может в своей деревне выбрать себе девушку «ровней» конечно только с ее личного согласия. Это означает, что у них могут быть романтические отношения, он может ей дарить подарки, а она например вязать для него одежду и прочее.
Они могут и физически касаться друг друга, если желают, в том числе, и целоваться, и спать вместе, но только в одежде. Мужчина не смеет иметь с ней сексуального контакта и она тоже не вправе этого допускать. Их ноги и животы в то время, когда они спят вместе, не должны соприкасаться, можно только грудью и лицами.
Как правило, у этих пар платонические отношения и вечера, и ночи они проводят в беседе о радости жизни. А под утро засыпают или спиной друг к другу, или мужчина на спине, а женщина на грудь кладет ему голову. Когда наступает утро, есть правило, что женщина подает своему «ровне» рог водки (в горной Грузии нет виноградников, и там нет культуры вина как в долинной) и еду, он выпивает, благодарит и уходит по делам. Ровни не могут женится и создать семью, они должны оставить между собой чистые, романтические отношения.
Цитата из комментариев к видео, где три девушки поют
Memcached и UDP
Когда я написал про поддержку модулем Мемкешед для ПХП протокола UDP, я ещё не знал многих подробностей. Например, я думал, что ребятам из Мемкешед
Оказывается ничего подобного — UDP нужен только тогда, когда вас устраивает негарантированная доставка, т. е. вы швырнули пакет, а дойдёт ли он до кеша — неважно, при чтении это будет считаться промахом кеша.
В интернете есть статья, которая кратко раскрывает что это даёт, в ней же приводится патч «multi UDP», который Мемкешеду уже не нужен — я смотрел в код, всё там нормально давно.
Кстати, обнаружились две подробности в поддержке UDP модулем Мемкешед ПХП.
Работоспособный тест выглядит так:
$m = new Memcached('SomeID');
$m->addServer('127.0.0.1', 11211, 1);
$m_udp = new Memcached();
$m_udp->setOption(Memcached::OPT_USE_UDP, true);
$m_udp->addServer('127.0.0.1', 11211, 1);
var_dump($m_udp->set('foo', "test string"));
sleep (1);
var_dump($m->get('foo'));Недвижимая лестница

Когда мы с женой несколько лет назад были в Иерусалиме, около храма Гроба Господня, возможно я и видел на карнизе эту деревянную лестницу, но внимания точно не обратил — ну мало ли строительного инвентаря встречается у храмов? Я специально не стал вырезать из фото нужное место, чтобы было заметно насколько не цепляется глаз за эту деталь.
Оказывается, эта лестница стоит там по меньшей мере с 1834 года. Причина того, что она простояла там так долго — договорённость шести конфессий, владеющих храмом — ничего не менять, не двигать, не ремонтировать в храме без согласия всех шести владельцев.
На всех фотографиях этого храма, я с тех пор как узнал эту историю, обязательно замечаю эту лестницу.
99 бутылок: Batsh, VIM script
Потихоньку возобновил наполнение раздела «99 бутылок пива на стене» — тут я пишу американскую считалочку про пиво на различных языках программирования. Добавились языки VIM script и Batsh. Первый используется в консольном редакторе vim для написания внутренних скриптов, второй — для кроссплатформенного написания
Batsh мне вообще понравился своей идеей — простой
50. Batsh — чрезвычайно лёгкий в освоении язык
// Песня о пиве на языке Batsh Степанищева Евгения
function bottles(bottle){
if (bottle == 0) {
return "no bottles";
}
if (bottle == 1) {
return "1 bottle";
}
return bottle ++ " bottles";
}
i = 99;
while (i > 0) {
b = bottles(i) ++ " of beer";
println(b, "on the wall,", b ++ ".");
i = i - 1;
println("Take one down and pass it around,", bottles(i), "of beer on the wall.\n");
};
println("No more bottles of beer on the wall, no more bottles of beer.");
println("Go to the store and buy some more, 99 bottles of beer on the wall.");49. VIM Script — встроенный скриптовый язык программирования консольного редактора VIM. Синтаксис довольно обычен, учится легко. Мощный для своего класса — обилие встроенных функций, довольно согласованный синтаксис, различные типы массивов. Есть интересные особенности, например, возможность явного переопределения функций, префиксы переменных для явного определения зоны видимости (например, префикс «a:» у меня в функции — это аргументы) или функции, которые могут принимать
" написал Евгений Степанищев bolknote.ru"
:function Bottles(bottle)
: return get(["no bottles", "1 bottle"], a:bottle, a:bottle . " bottles")
:endfunction
:for beer in range(99, 1, -1)
: let b = Bottles(beer) . " of beer"
: echo b "on the wall," b . "."
: echo "Take one down and pass it around, " . Bottles(beer-1) . " of beer on the wall.\n"
:endfor
:echo "No more bottles of beer on the wall, no more bottles of beer."
:echo "Go to the store and buy some more, 99 bottles of beer on the wall."is_numeric
Функция is_numeric одна из традиционно неверно понимаемых программистами на ПХП. Её, обычно, понимаю как «посмотреть содержится ли в переменной
Беда в том, что понятия числа у ПХП и человека различаются. Посмотрите, все эти вызовы рассматриваемой функции вернут «true»:
var_dump(is_numeric("123e123")); // true — десятичное число в экспоненциальной записи
var_dump(is_numeric("0123")); // true — восьмеричное число
var_dump(is_numeric("0XDeadBeef")); // true — шестнадцатеричное число
var_dump(is_numeric(NAN)); // true — специальное численное значение «не число»Особенно не везёт восьмеричным числам, которые во многих языках (и в ПХП) тоже начинаются с нуля: формально выглядят как обычное десятичное (только начинается с нуля), проходят все проверки, а после преобразования теряют ведущий ноль и это может быть важно.
С незапамятных времён существует хак, который позволяет убедиться, что перед нами именно десятичное число, пусть и в строковой форме:
function is_number($var) { return (string) (int) $var === (string) $var; }Принцип очень простой — переменная преобразуется в целый тип (можно преобразовывать и в тип с плавающей точкой, если это нужно), потом берётся строковое представление получившегося числа. На этом этапе восьмеричные, шестнадцатеричные и прочие виды записи чисел будут преобразованы в целочисленный тип, строковое представление которого — десятичное число. Справа же пришедшее остаётся в первозданном виде.
Далее мы сравниваем левую и правую часть и, если они совпадают, значит к нам пришло именно десятичное число, так как никаких преобразований с ним не произошло.
Добавлено позднее: в документации к функции написано, что она так же понимает двоичную форму записи введёную недавно (число должно начинаться с «0b»), к сожалению, это неправда — в коде поддержки нет, баг заведён и в нём написано, что это проблема документации, а не функции.
Интересно ещё, что is_numeric пропускает любое количество пробельных символов слева, но плохо относится к ним справа:
var_dump(is_numeric("\f\f\t0xBadBabe")); // true
var_dump(is_numeric("1\t")); //false