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; }
Принцип очень простой — переменная преобразуется в целый тип (можно преобразовывать и в тип с плавающей точкой, если это нужно), потом берётся строковое представление получившегося числа. На этом этапе восьмеричные, шестнадцатеричные и прочие виды записи чисел будут преобразованы в целочисленный тип, строковое представление которого — десятичное число. Справа же пришедшее остаётся в первозданном виде.

Далее мы сравниваем левую и правую часть и, если они совпадают, значит к нам пришло именно десятичное число, так как никаких преобразований с ним не произошло.
8 комментариев
28 августа 2014 10:25

Мокрая вода, крепкий алмаз, быстрый фотон

Ребята, ну нет никакого «нижнего подчёркивания». Подчёркивание всегда внизу, под чем-то. Это ↘_↙ просто подчёркивание. Оно по определению нижнее, не бывает ни среднего, ни верхнего. Уточнение, что оно внизу лишнее.
6 комментариев
27 августа 2014 22:19

Велодорога домой

Бо́льшая часть моих велопрогулок — это примерно 15 километров совокупной дороги с работы и на неё. Езжу почти каждый день, если нет дождя, а они пока ещё не так уж и часты. Сегодня случился своеобразный рекорд — моя средняя скорость была 20 км/ч. Учитывая пешеходов, светофоры и пересечённый характер местности, совсем немало. Велодорога домой (125.47КБ)
3 комментария
27 августа 2014 20:54

Недокументированные возможности модулья Memcached (для PHP)

Читая на досуге исходники модуля Memcached для ПХП, наткнулся на неожиданное: оказывается этот модуль поддерживает соединение по протоколу UDP, причём документация молчит об этом.

Делается это вот так:
$udp = new Memcached();
$udp->setOption(Memcached::OPT_USE_UDP, true);
$udp->addServer($host, $port);
В частности, это позволит нам перейти на multi-UDP схему, если добавить разные порты как несколько серверов. Надо пробовать.

Другая вещь, которая никак не раскрывается документацией — пользовательские флаги (UDF — user defined flag). К каждому значению можно прикрепить один или несколько флагов, которые при получении значения будут складываться в заданную переменную:
const FLAG = 1;
const ANOTHER_FLAG = 2;

$m->set($key, 'value', 0, FLAG | ANOTHER_FLAG); // установили флаг
$m->get($key, null, null, $flags); // флаги будут лежать в переменной $flags
У каждой функции установки и получения значений (а их несколько, этих функций) в конце есть необязательный параметр для работы с флагами. Так что во всех вариантах использования значения можно как-то пометить, а потом эти пометки получить.
4 комментария
27 августа 2014 16:13

Короткий способ определить есть ли поддержка dataURI

Придумал короткий способ определить поддержку data URI в браузере:
<script src="data:text/javascript,self.dataURI=1"></script>
Потом просто проверяете у window свойство dataURI, если оно есть, то есть и поддержка. Способ не работает в IE8 и IE9 — тот и другой не умеют загружать Джаваскрипт этим образом. Собственно, меня это не волнует — мне как раз и нужно определить, что Джаваскрипт так работает, но если вам нужно не это, то должен работать вот такой способ:
<link rel="stylesheet" href="data:text/css,html{font-size:99px}">
То есть устанавливаем у тега HTML какое-нибудь свойство, которое потом в BODY перекроем, а позже, чтобы убедиться, что поддержка дата-ури есть, смоторим что вышло (тут я при помощи jQuery это делаю):
/99/.test($('html').css('font')); // true, если есть поддержка dataURI

PHP7

Всё, PHPNG отправился в «мастер», по всей видимости, это означает, что он появится сразу после версии 5.6, которую мы увидим буквально на днях (я уже немного писал о том, что в ней нового).

PHPNG — новая версия интерпретатора, которая, по всей видимости, будет носить номер семь, чтобы избежать путаницы с PHP6 — неудавшейся попыткой перевести ПХП на Юникод, которую широко в своё время освещали, но сообщество решило от неё отказаться — большинство разработчиков англоязычны и выгоды от этого трудоёмкого процесса не видели.

Новая версия ПХП интересна переработанными внутренностями, изменение которых связано со скоростью. Установленный «ВордПресс» работает на новой версии в два раза быстрее, что впечатляет, конечно. Плохая новость — придётся переделать бо́льшую часть модулей (если не вообще все). Процесс этот сейчас движется, но только для модулей, входящих в язык, несколько модулей (в том числе важный для меня OCI8) пока ещё не поправлены.

Думаю, что миграция авторских модулей произойдёт довольно быстро.
7 комментариев
25 августа 2014 13:47

Странное с Флешем

Я с «Флешем» в последние годы не сталкивался, но и прежде подобного поведения не наблюдал. В общем, решил я вчера обновить в нашем продукте библиотеку ВебКамДжиЭс, она у нас для получения фотографии с камеры используется. Прежняя была 0.9, а тут я случайно обнаружил, что релиз вышел.

В прежней изображение с камеры получалось через Флеш, а релизная умеет использовать АПИ браузера, если таковое имеется. Правда, в «Сафари», которым я пользуюсь, этого АПИ нет и всё равно используется Флеш. Вот тут-то и столкнулся с трудностями — прежняя версия работала прекрасно, а новая отказывалась — в окне Флеша изображение с камеры есть, но ДжаваСкрипт был уверен, что всё плохо и, самое главное, не мог достучаться до Флеша.

В принципе, можно было откатиться на предыдущую версию, но смущало, что на демо-сайте ВебКама в «Сафари» всё работало нормально. Я попробовал несколько вариантов, прежде чем мне пришла в голову идея посмотреть заголовки запросов. И заметил разницу, показавшуюся несущественной, но всё-таки я решил попробовать её устранить — mime type различался.

У нас сервер отдавал Флеш с типом «application/x-shockwave-flash», а в демо-примере был «binary/octet-stream». Стоило поменять этот заголовок, и всё заработало.

Беглое гугление света не пролило, но если столкнётесь с похожей проблемой, имейте ввиду, возможное решение — смена типа для отдаваемого флеш-ролика.
Комментировать
23 августа 2014 12:36

Короткий способ определять IE

А какой сейчас самый короткий способ определять Эксплорер? Я понимаю, что привязываться к браузеру нехорошо, но у меня конкретная задача, которую никак не обойти — нужно проиграть звук в браузере (PCM wave), а ИЕ на запрос «сможешь проиграть?» к тегу AUDIO, говорит maybe. Т.е. давайте сюда свой звук, может и смогу. Я-то знаю, что не сможет — аудиотег в этом браузере «вавки» не играет, нужен EMBED.

Все короткие способы, которые раньше работали (условная компиляция, сравнение вертикального пробела с буквой v, хитрый хак с массивом и прочее) в 11-й версии работать перестали. Даже строку агента поменяли — там теперь нет MSIE.

В общем, я пока остановился на такой версии:
if (top.VBArray) {
    // IE
} else {
    // остальные браузеры
}
Но буду признателен за что-то более короткое или очевидное.
8 комментариев
19 августа 2014 14:14

ANSI-коды в имени точки вайфай

Давно интересно было посмотреть отфильтруются ли АНСИ-последовательности из имён вайфай-точек в утилитах командной строки. Оказалось, что в «Маке» фильтра нет и, посмотрев список предпочтительных сетей, можно в этом убедиться: ANSI-последовательности в имени вайфай-сети (20.31КБ) Естественно, в графическом интерфейсе ничего такого нет: ANSI-последовательности в графическом интерфейсе (44.04КБ) Судя по спецификации, в имени должна быть строка до 32 байт, заканчивающаяся символом с кодом ноль. Других ограничений нет, так что и такое странное имя можно задать.
4 комментария
16 августа 2014 23:04

Передача массива как аргументов в конструктор

Одна из вещей, из-за которых я жду ПХП версии 5.6 — это развёртывание массива в параметры. В принципе, для этого есть функция call_user_func_array, но новый синтаксис куда приятнее:
$result = call_user_func_array('myfunc', $args); // старый синтаксис
$result = myfunc(...$args); // PHP 5.6+
Но помимо приятности, он решает две проблемы.

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

Во-вторых, сейчас в ПХП нет нормального способа сделать то же с конструктором. Например, если в вашем фреймворке есть класс, возвращающий сервисы (в терминах «Симфони 2»), то в нём придётся делать либо switch/case (для скорости), либо обращаться через рефлекшн:
switch (count($params)) {
    case 0:
        $instance = new $class();
        break;

    case 1:
        $instance = new $class($params[0]);
        break;

    case 2:
        $instance = new $class($params[0], $params[1]);
        break;

    // и так далее…

    default:
        $refClass = new \ReflectionClass($class);
        $instance = $refClass->newInstanceArgs($params);
        break;
}
В новом же синтаксисе код невероятно упрощается:
$instance = new $class(...$params);
А, кроме того, становится более явным и простым. Так что очень радуюсь этому новому синтаксису.
4 комментария
12 августа 2014 13:56

Санта-Сусанна

Я не привык ждать многого от городков с огромной отельной зоной. Город Санта-Сусанна (Испания) совершенно неожиданно оказался довольно интересным местом, с сохранившимися зданиями довольно почтенного возраста.

Поскольку мы иногда пару часов катались на арендованных велосипедах, то я придумал нам квест — разыскать все смотровые башенки (их оказалось шесть), обозначенные на карте достопримечательностей, скачанной с какого-то сайта. Квест имел смысл, потому что карта была очень приблизительной, соврешенно неподробной, так последнюю башню (Torre Vall Xirau, Валь-Щирау) мы искали, в общей сложности, больше трёх часов.

Город получается трёхслойным — зона отелей у моря, дальше запутанная историческая часть, а выше в горы — зелёная зона. Её тоже планировали застроить отелями, но повезло — местные «зелёные» добились запрета. В зелёной зоне есть несколько интересных мест — башня Монтгаут 19-го века (Torre de Montagut), до которой мы не добрались, лишь увидели издалека — она стоит высоко на горе, музей Сельского Быта (Museu de la Pagesia) и огромный парк, у входа которого установлен уже не действующий фонтан Ботер (Font del Boter): Font del Boter (206.59КБ) Санта-Сусанна — город очень старый, первые упоминания относятся в 12 веку, количество сохранившихся зданий и их возраст внушает уважение, более того, тут есть даже собственный небольшой замок — Кан-Ратес (Masía Can Ratés), построенный в 16 веке. Он, конечно, куда более скромный, чем тот, что в Каркасоне (это во Франции, я о нём упоминал на прошлой неделе). На территории замка Санта-Сусанны находится одна из смотровых башен, построенная в 1584, её немного видно на фото: Masía Can Ratés (162.87КБ) Улицы в исторической части кривые, узкие, а карта у нас была только примерная, потому в поисках этого замка, мы натыкались на самые разные объекты, в том числе, почти на выезде (кстати, дальше по этой дороге находятся «Парк Приключений» и уже упомянутый музей Сельского Быта), наткнулись и на водопровод 19-го века. В настоящее время в хорошем состоянии находятся только 135 метров, а когда-то он тянулся на несколько километров и поставлял воду в замок. Водопровод (172.94КБ) Кстати, в замке есть очень неплохой, довольно ухоженный парк, где можно прогуляться — он открыт для посещения в утренние часы, кроме того, там есть бассейн, который когда-то был прудом. Сейчас в бассейне нет воды, а когда-то он, будучи прудом, думаю мог наполнялся через водопровод.

Рядом с водопроводом есть ещё один интересный объект — башня с солнечными часами, к сожалению, никаких подробностей про неё я в интернете не нашёл. Башня с часами (146.18КБ) Вернёмся к смотровым башням. Проще всего найти башню де-ла-Плана (Torre de la Plana) — она стоит прямо у моря, на выезде в сторону Барселоны и используется как билетная касса — внутри у неё аппарат для продажи билетов на электричку. Один из гидов, с которым мы выезжали из города на экскурсии, утверждал, что это новострой, но везде в интернете указан 16-й век. Torre de la Plana (131.35КБ) Труднее всего далась упомянутая в начале Валь-Щирау (Torre Vall Xirau) — тоже 16-го века постройка, на сегодняшний день находится в частном владении и является частью чьей-то дачи. Torre Vall Xirau (184.71КБ) Эту башню мы искали два дня подряд, в итоге нашли, но по дороге заблудились — оказывается карты, которые есть тут на автобусных остановках, грешат неточностью. Зато какое было удовольствие, упоров не в ту сторону по жаре, найти в ближе к тупику ошибочной дороги, источник ледяной воды, из которого местные набирали воду! Блаженство! Источник (285.00КБ) К сожалению, местные по-английски не говорили вообще и не смогли нам подсказать как найти башню, но мы справились и сами.

Меня, кстати, сильно удивляет, что такие исторические объекты находятся в частных руках, но это, наверное, просто потому, что у нас в стране это редкость из-за революции — тогда множество таких объектов перекочевала от владельцев к государству. Башня дома Галтер (Torre de Mas Galtér) в 1933 году была выкуплена у семьи Галтер, которая владела ей аж с 1440 года и так же находится в частной собственности у неких Пи. Torre de Mas Galtés (374.44КБ) Замыкает список башня Кан-Бонет-д’Аваль (Torre Can Bonet D’Avall), пристроенная в 15 веке к дому Бонета д’Аваль. В ней четыре этажа и из каждого окна можно было обороняться и стрелять в нападавших. В 1805 веке её реконструировали и отштукатурили, из-за чего она теперь кажется куда моложе, чем на самом деле. Torre Can Bonet D’Avall (240.73КБ) Вообще, интересных объектов в Санта-Сусанне гораздо больше, чем я описал — есть интересные частные дома, церкви, остатки каких-то построек. До некоторых добраться или даже сфотографировать совсем непросто — многое на частной территории, например, дом Conjunt de Mas Parera i Can Salvi семнадцатого века — чтобы до него добраться, мне пришлось обойти его с другой стороны, по полю. Conjunt de Mas Parera i Can Salvi (154.74КБ) Пожалуй, стоит закругляться. Хочется ещё упомянуть последнюю в моём рассказе постройку — часовню Санта-Сусанны (Capella de Santa Susanna), здание шестнадцатого века, сейчас, к сожалению, там сделали сплошной забор, а ещё несколько лет назад её можно было видеть в полной красе. Capella de Santa Susanna (120.27КБ) Часовня когда-то принадлежала семье Ратес — на ней тот же герб, что и на замке, к сожалению, на фотографии этого не видно. Часовня сейчас находится в частной собственности и к ней пристроен дом её владельцев.

В общем, чудесный городок, я очень рад, что мы тут провели две недели. Очень жаль, что уже завтра придётся отсюда улетать.
3 комментария
10 августа 2014 12:24

Про загар

Скоро кончается отпуск, вернусь в Казань, друзья и коллеги обязательно начнут сочувственно спрашивать — почему же я так мало загорел?

Загорел я так мало, потому что не понимаю ценности загара.

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

Эстетической стороны вопроса для меня не существует. Вообще я вижу в этом что-то странное, что те же люди, которые смеются над японцами, делающими операции на веко, чтобы довести его до европейского «стандарта», тратят огромные деньги ежегодно для того, чтобы довести свою кожу до африканского. Цвет кожи — как цвет волос, кому-то идёт рыжий, кому-то — чёрный, а кто-то не заморачивается с этим вообще и ходит как природа определила.

С вопросом здоровья ещё сложнее. Принято считать, что загар даёт что-то ценное организму, настолько ценное, что можно, видимо, принебречь раком кожи. Например, вырабатывается витамин «Д».

Во-первых, этот витамин есть в любых мультвитаминах и его употребление в таблетках не грозит раком, во-вторых, его необходимое количество вырабатывается, если находится под солнцем 2—3 раза в неделю в течении 5—15 минут.

Что там ещё упоминается? Улучшение иммунитета? Это неправда, он ухудшается, а кроме того длительное пребывание на солнце способствует старению кожи и вызывает мутации ДНК.

Говорят ещё, что это приятно само по себе. Тут надо отделить одно от другого. Приятно что? Загар или пребывание на пляже? Я могу поваляться на пляже с хорошей книгой — это может быть приятным. Но я буду намазан предохранительными мазями по самые уши. Загорю или нет — дело десятое (за неделю отдыха немного загорел), зато гарантированно не обгорю, что куда важнее для меня — обгорать и больно, и опасно.
27 комментариев
8 августа 2014 12:18

Шестая годовщина свадьбы

Сегодня у нас с женой шестая годовщина свадьбы, первая «металлическая» свадьба — чугунная. Как-то так случайно вышло, что весь сегодняшний день мы провели в путешествии — ещё утром были в Андорре (это небольшое государство — около 75 тысяч человек), днём побывали во Франции (в городах Фуа и Каркасон), а вечером приехали в Испанию (и сейчас отдыхаем в Санта-Сусанне).

А ещё как-то так получилось, что в последнее время сбывается очень много того о чём я мечтал в детстве. На этот раз сбылась моя мечта побывать в настоящем средневековом замке.

Чисто формально эта моя мечта сбылась ещё в Армении — там мы полазили на развалинах замка Амберд (седьмой век). Но от него почти ничего не осталось, так что ощущения совсем не те. Замок Амберд (130.98КБ) Сегодня же мы погуляли по огромной крепости Каркасон и его внутреннему графскому замку. Сам замок впечатляет не очень, в крепости гораздо интереснее, но зато выглядит он гораздо внушительнее и настрой передаёт, а это именно то, что я и хотел почувствовать. Замок в Каркасоне (123.23КБ) А ещё, если считать Россию, то сегодня мы посетили свою двадцать пятую страну — Францию. В первый раз мы поехали за границу как раз на свадебное путешествие, так что это тоже связанные между собой события.
7 комментариев
1 августа 2014 21:58

«Четверо под одной обложкой»

Четверо под одной обложкой (101.72КБ) Пару месяцев назад я взялся переводить в электронный вид книгу Арканова, Горина, Успенского и Камова «Четверо под одной обложкой». Меня она заинтересовала тем, что из одного рассказа, содержащегося в ней, растут ноги известнейшей фразы «рояль в кустах». К сожалению, в интернете книги не оказалось Я, с большим трудом разыскав одного из немногочисленных её владельцев, получил от него сканы и приступил к переводу в электронный вид.

Несмотря на очень хорошее качество сканированного материала, некоторые страницы пришлось перепечатывать полностью — столько в них было ошибок, я использовал для распознавания бесплатную программу, видимо поплатился качеством. Правда продвигался быстро — за пару дней прошёл две трети книги, а потом всё застопорилось — совсем не стало времени в связи с работой. И вот недавно, поторапливаемый нетерпеливым читателем, я работу возобновил, и в очень медленном темпе, буквально сегодня утром, перед отпуском всё закончил.

Это был интересный для меня опыт, теперь я не понаслышке знаю как тяжёл труд тех, кто распознаёт редкие книги, хотя в моём случае чашу сполна я не испил — книга относительно небольшого размера.

Хочу так же сказать огромное спасибо Денису Олеговичу Стребкову за предоставленные сканы!
6 комментариев
29 июля 2014 11:35

Use SVG

Поскольку «Макбук» у меня с «ретиной», я давно озаботился тем, чтобы продукт, разработкой которого я управляю, хорошо смотрелся и на «ретине» тоже. Я считаю за такими экранами будущее и не грех позаботиться об этом будущем уже в настоящем. Если уж и не внедрить везде, так хоть научиться верстать.

Одним из главных помощников в такой вёрстке является, без сомнения, формаг СВГ — формат векторной графики, который на данный момент поддерживают все распространённые браузеры (включая ИЕ, с девятой версии). Особенно приятно, что его можно включать прямо внутрь ХТМЛя, это очень удобно — если СВГ используется для кучи мелких значков на странице, то не будет лишних соединений с сервером — ведь всё грузится вместе с основным кодом.

Но встаёт другая проблема — проблема повторного использования. Если одни и те же значки присутствуют на странице в изобилии, страница будет распухать, что печально.

К счастью, есть выход. СВГ — гибкая штука, в этом формате есть возможность использования частей изображения повторно. Первым шагом нужно определить тег-контейнер с необходимыми нам изображениями, по одному в теге symbol. У каждого из них будет собственный идентификатор, по которому мы ниже будем на них ссылаться:
<svg style="display:none">
    <symbol id="folder" viewBox="0 0 49.833 67.167">
        <!-- код не рабочий, только для примера -->
        <path d="M15.938,67.…"/>
        <path d="M3.59,30.531c…"/>
    </symbol>
    <symbol id="file" viewBox="0 0 49.833 67.167">
        <path d="M12.233c0.…"/>
        <path d="M3.28C2.76…"/>
    </symbol>
</svg>
Тут у нас два изображения — folder и file, на которые мы можем сослаться следующим образом:
<svg width="28" height="37">
    <use xlink:href="#folder"/>
</svg>

<svg width="28" height="37">
    <use xlink:href="#file"/>
</svg>
Таких вставок может быть сколько угодно и все они будут использовать одни и те же изображения, описанные в теге-контейнере. Остаётся даже возможность лёгкой настройки под себя, например, можно задать парочку классов и раскрасить часть изображения в разные цвета:
svg.green {
    fill: green;
}

svg.red {
    fill: red;
}
Классы можно повесить на ссылающиеся теги СВГ, жаль только этот способ полон ограничений. Кроме как в ФФ более избирательные селекторы использовать не удаётся — всё, что ниже тега use для таблицы стилей как будто не существует. Если и есть какой-то способ это починить, я его не нашёл.
5 комментариев
29 июля 2014 00:09