Заметки за 2018 год
14 November 2018, 05:30 MSK
Удивительно, но многие разработчики не знают, как можно очень просто сделать автоматический бэкап одной или нескольких таблиц в мускуле. Восполним этот недостаток знаний.
Нам потребуется создать простой скрипт на баше, например, /var/backup.sh:
#!/bin/bash
export MYSQL_PWD='ВАШ_ПАРОЛЬ'
mysqldump -u'ВАШ_ЛОГИН' -i -c -e НАЗВАНИЕ_БД ТАБЛИЦА_1 ТАБЛИЦА_2 > /var/backups/mybackup.sql
Если вы хотите, чтобы каждый раз создавался новый файл, можно в его название включить дату и время:
#!/bin/bash
export MYSQL_PWD='ВАШ_ПАРОЛЬ'
mysqldump -u'ВАШ_ЛОГИН' -i -c -e НАЗВАНИЕ_БД ТАБЛИЦА_1 ТАБЛИЦА_2 > /var/backups/mybackup-`date +%Y-%m-%d--%H-%M-%S`.sql
Добавляем скрипт в крон (crontab -e).
Не забываем разрешить выполнение скрипта (chmod +x /var/backup.sh).
В результате выполнение скрипта вы получите файл с дампом ваших таблиц.
6 November 2018, 23:50 MSK
При разработке сайтов часто встаёт задача наладить автоматическую выгрузку файлов сайта на веб-сервер. Быстрое гугление по данной теме приводит сложные и запутанные решения, я же поделюсь очень простым. Предполагается, что у читателя есть базовые знания Linux и Git.
Итак, у вас имеется локальный сайт, гит-репозиторий и удалённый сервер с дебиан-подобным линуксом. Допустим, на сервере сайт лежит в папке /var/www/site/.
Сначала необходимо создать в репозитории новую ветку, например, deploy. Всё, что попадёт в неё, будет выгружено на сервер.
Теперь переходим к серверу. Если не установлен гит, устанавливаем:
sudo apt-get install git
Затем клонируем репозиторий в папку с сайтом (из-за особенностей гита она должна быть пуста):
cd /var/www/site/
git clone АДРЕС_РЕПОЗИТОРИЯ .
Система попросит логин и пароль.
Переключаемся на нашу специальную ветку:
git checkout deploy
Теперь можно при помощи команды git pull обновлять сайт. Но это не очень похоже на полностью автоматический способ? Идём дальше.
Во-первых, чтобы каждый раз не вводить логин и пароль, выполняем следующую команду:
git config credential.helper store
Во-вторых, настроим выполнение команды git pull раз в минуту. Для этого создаём скрипт обновления:
nano /var/www/deploy.sh
Вставляем в него следующий текст:
#!/bin/sh
cd /var/www/site/
git pull > /dev/null
Не забываем разрешить выполнение скрипта:
chmod +x /var/www/deploy.sh
Добавляем скрипт в крон:
crontab -e
В конец файла копируем строчку:
* * * * * /var/www/deploy.sh
Собственно, на этом всё. Пушите ваш код в ветку deploy на локальном хосте — он автоматически заливается на удалённый сервер.
28 October 2018, 18:16 MSK
Из сложившейся в стране ситуации у петербуржцев
есть три выхода: Торфяновка, Брусничное и Светогорск
Народное творчество
Первая часть тут.
На машине (или автобусе) в Страну тысячи озёр из России можно въехать через 3 пропускных пункта (МАПП). Обычно я въезжаю и выезжаю через Брусничное, но в этот раз изменил маршрут и объехал все три.
IMG_4268
23 October 2018, 18:50 MSK
Сейчас середина осени, и скоро наступят холода. В этой заметке я расскажу, каким образом можно просто и быстро автоматизировать отопление обычными радиаторами в квартире или доме и получить возможность изменять температуру в комнате с айфона, айпада или макбука.
В результате получится настоящий климат-контроль в доме: можно задать необходимую температуру воздуха в помещении с помощью телефона (в том числе удалённо или по расписанию), а ваш радиатор будет её поддерживать на нужном уровне. Для этого будем использовать специальный термостат (в народе называемый термостатической головкой).
Вот так выглядит конечный результат:
термостатическая головка Eve Thermo
14 October 2018, 16:15 MSK
Питерская народная забава — сгонять в Финляндию туда-обратно одним днём.
IMG_3139
16 August 2018, 01:45 MSK
Продолжаем рассказывать общественности о том, как операторы сотовой связи зарабатывают деньги мошенническим образом.
Исторически у меня несколько симок для разных нужд в Мегафоне. Недавно я заметил, что на одной из них начали утекать деньги, хотя симка лежит в ящике около полугода и временно не используется.
Идём в личный кабинет и смотрим расходы по номеру:
megagavno
WTF? Каким-то образом оказались подключены две платные услуги, за 2.5 руб. / сутки и 30 руб. / месяц.
Удивительно. Ещё раз: симка с осени 2017-ого лежит в ящике. В колл-центре сказали, что обе услуги подключены в июне. Интересно, кем? Сотрудники, разумеется, информацией не обладают. Абсурдности ситуации добавляет тот факт, что в июле я звонил в колл-центр и интересовался, какие платные услуги подключены на всех моих номерах (полезно проделывать это пару раз в год), и про эти услуги никто даже не заикался.
Дальше — ещё смешнее. В колл-центре прошу отключить злосчастные опции и вернуть деньги. SMS XXS отключили, а вот Персональный бюджет не могут. «Почему?» — спросите вы. Оказывается, эта опция только для корпоративных клиентов. Сотрудник переводит вызов в колл-центр для корпоративщиков, но там мне тоже помочь не могут, потому что, ВНИМАНИЕ, номер зарегистрирован на физическое лицо. На этом моменте уже начинает подгорать.
Мегафон, вы вообще в адеквате? Дело не в 30-ти рублях, мне просто интересно, как такое может быть?! На номере, который зарегистрирован на физ. лицо, подключена услуга только для юр. лиц, и никто не может мне её отключить! При этом совершенно не понятно, кто и как её подключил, но деньги за неё стабильно продолжают списывать.
UPD: отключили только после личного визита в салон с паспортом.
10 August 2018, 16:39 MSK
Самая большая глупость на свете — голосовые сообщения в мессенджерах. Люди, которые отправляют голосовые сообщения вместо текстовых, часто не задумываются о неудобствах для собеседников. К сожалению, последнее время лично у меня участились голосовые сообщения от совершенно разных людей, что и вынудило меня написать этот пост.
Во-первых, прочитать текст занимает в несколько раз меньше времени, чем прослушать аудиозапись.
Во-вторых, написанное текстом сообщение потом легко найти в истории обычным поиском, а голосовое нельзя.
В-третьих, прослушать голосовое сообщение сложнее, если ты на улице или не один в помещении, и практически нереально, если ты на встрече, в кино и т.д.
Отправляя очередной раз кому-нибудь голосовое сообщение вместо того, чтобы набрать текст, помните, что ваш собеседник, скорее всего, тихо вас ненавидит.
11 July 2018, 20:13 MSK
Итак, снова пост про Телеграм. Я уже рассказывал, как отправлять сообщения от имени бота (в том числе, через прокси) и как сделать бота, который умеет принимать сообщения.
Отправлять сообщения в Телеграм от бота очень просто, но есть крайне неудобная проблема: из-за ограничений Telegram Bot API бот не может писать первым. То есть, сначала пользователь, которому вы собрались что-нибудь отправить, должен первым написать вашему боту любое сообщение. Это ограничение вполне разумно и предотвращает спам сообщениями от ботов, но очень мешает честным людям. Например, отправлять сервисные сообщения с информацией о заказе в интернет-магазине.
Решение этой проблемы только одно: не использовать ботов. Придётся всё делать с обычного аккаунта.
Копаться в подробностях телеграмовского протокола MTProto не нужно, как оказалось, всё уже сделано до нас. Для PHP существует чудесная библиотека MadelineProto. Её мы и будем использовать, ниже пошаговая инструкция.
8 July 2018, 03:20 MSK
Последнее время я увлекаюсь системами умного дома и хотел бы поделиться накопившимся опытом. В серии постов на эту тему я расскажу как о попытке сделать свою систему с нуля, так и о готовых решениях.
smart-home
Педантичный читатель обязательно придерётся к термину «умный дом». Конечно, правильнее называть это домашней автоматизацией, но я позволю себе использовать хоть и неверную, но устоявшуюся формулировку.
Сейчас на рынке присутствует очень много разрозненных решений. Ради эксперимента мне захотелось попробовать сделать что-нибудь самому.
Хороший проект всегда начинается с требований к конечному результату, вот мои:
  1. Нафиг километры проводов. У меня в квартире сделан ремонт, поэтому заново штробить стены желания совсем нет. Пусть умный дом будет обмениваться данными по радио-каналу.
  2. Нафиг бредовые идеи. Встроить айпад с интерфейсом в стену? Отправлять данные на народный мониторинг? Ну уж нет, спасибо, обойдёмся без этого.
  3. Нафиг пульты. Пульты всегда теряются и ломаются. Лучший пульт — тот, который всегда с тобой. Это телефон или часы (привет, Сири!). Также не забудем оставить классические элементы управления (настенный выключатель, ггг) для менее продвинутых домочадцев.
Теперь подумаем над архитектурой. Философия моего умного дома будет такой (привет, Юникс!):
Одно устройство должно делать только одну вещь, но должно делать её хорошо.
Такой подход лаконичен и позволяет не смешивать всё в одну кучу, не усложнять архитектуру системы, превращая устройства в многофункциональные комбайны.
2 July 2018, 00:16 MSK
Когда я был студентом и любил спорить с преподавателями, мой научный руководитель всегда просил меня не делать преждевременный рефакторинг кода. Потому что отрефакторить работающий код можно за конечное число шагов, а сколько времени займёт превращение неработающей, но отрефакторенной программы в работающую — неизвестно. Спустя годы я понял, что это работает не только в программировании, но и в жизни.
5 June 2018, 18:22 MSK
Я уже писал о том, как отправить сообщение из PHP в Телеграм и как сделать своего Телеграм-бота, принимающего сообщения. Тема оказалась довольно популярной, но в связи с известными событиями у некоторых пользователей всё же могут возникать трудности. Недавно мне написал один их моих читателей и пожаловался, что мой скрипт из предыдущего поста у него на хостинге не работает.
Если вы не читали предыдущий пост по теме, сначала рекомендую прочитать его: https://kirkizh.ru/2018/04/telegram-php/.
Для решения этой проблемы проще всего использовать прокси сервер. Учтите, что прокся нужна обычная (HTTP/SOCKS), не специфичная телеграмовская (MTProxy).
Итак, новый код:
<?php
// сюда нужно вписать токен вашего бота define('TELEGRAM_TOKEN', '999999999:XXXXXXXXXXXXXXXXXXXXXXXXXXXX');
// сюда нужно вписать ваш внутренний айдишник define('TELEGRAM_CHATID', '99999999');
message_to_telegram('Привет!');
function message_to_telegram($text) {     $ch = curl_init();     curl_setopt_array(         $ch,         array(             CURLOPT_URL => 'https://api.telegram.org/bot' . TELEGRAM_TOKEN . '/sendMessage',             CURLOPT_POST => TRUE,             CURLOPT_RETURNTRANSFER => TRUE,             CURLOPT_TIMEOUT => 10,             CURLOPT_POSTFIELDS => array(                 'chat_id' => TELEGRAM_CHATID,                 'text' => $text,             ),             CURLOPT_PROXY => 'host:port',             CURLOPT_PROXYUSERPWD => 'login:password',             CURLOPT_PROXYTYPE => CURLPROXY_HTTP,             CURLOPT_PROXYAUTH => CURLAUTH_BASIC,         )     );     curl_exec($ch); }
Чтобы всё заработало, вам нужно прописать настройки вашей прокси:
  • CURLOPT_PROXY — адрес и порт, например, 127.0.0.1:3128;
  • CURLOPT_PROXYUSERPWD — логин и пароль, разделённые двоеточием;
  • CURLOPT_PROXYTYPE — тип прокси, одна из следующих констант: CURLPROXY_HTTP, CURLPROXY_SOCKS4, CURLPROXY_SOCKS5, CURLPROXY_SOCKS4A или CURLPROXY_SOCKS5_HOSTNAME;
  • CURLOPT_PROXYAUTH — метод авторизации, одна из следующих констант: CURLAUTH_BASIC и CURLAUTH_NTLM.
Если вы не знаете тип прокси и/или метод авторизации, попробуйте подобрать их методом перебора.
Если у вас остались вопросы, пишите их в комментарии или мне в Телеграм: @vkirkizh. Также подписывайтесь на мой канал: https://t.me/kirkizh. :-)
UPD: вот список рабочих прокси на 2 сентября 2018: 5.9.253.151:1080, 5.9.253.151:1081, 5.9.253.151:1082. Логин sensey, пароль sensey.
30 May 2018, 22:33 MSK
На днях я столкнулся с неочевидной проблемой с моим макбуком. Очередное обновление макоси, ничего необычного. Обновление скачалось, попросило перезагрузку, я согласился, но мак перезагружаться не хотел. Вместо этого показывал чёрный экран и курсор мыши. Я принудительно выключил/включил компьютер кнопкой питания и повторил процесс. Неудачно. Также оказалось, что простые перезагрузка/выключения мака перестали работать, симптомы те же.
Обычно при проблемах с маком рекомендуют сбросить SMC и сбросить NVRAM. Не помогло. Я позвонил в службу поддержки Эппл, те развели руками и посоветовали переустановить OS X. Переустаналивать систему мне не хотелось. Перезагружать компьютер всё время хард резетом и оставлять его без обновлений тоже.
Я перепробовал кучу разных вариантов, но всё тщетно. Уже отчаявшись найти простое решение проблемы, я заглянул в консоль и увидел там кучу ошибок, возникавших каждую секунду:
LaunchServices: Database mapping failed with result -10813, retries = 2
Очевидно, была какая-то связь. В рунете решение проблемы мне найти не удалось, но долгое гугление привело меня на форум Эппл. Оказалось, что проблема в фигне, которая называется Launch Services. Иногда ломается их база данных, и её необходимо пересоздать. Для этого необходимо открыть программу Terminal и выполнить две команды:
sudo mkdir /private/var/db/lsd
sudo /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -seed -lint -r -f -v -dump -domain local -domain system -domain user -domain network
В процессе вас попросят ввести пароль пользователя, потому что эти команды выполняются от имени администратора. В результате будет пересоздана БД служб запуска, и макось начнёт нормально перезагружаться и выключаться.
19 April 2018, 20:28 MSK
Любой хороший предприниматель знает, как важно в бизнесе иметь как можно больше информации о своих клиентах. Одна из таких полезных вещей — источник клиента: с какого канала продаж он пришёл, по какому объявлению кликнул, какой поисковый запрос ввёл и так далее. Поэтому любой хороший сайт отслеживает эти и другие данные, собирая статистику. Эту статистику можно передавать в CRM-систему и использовать для анализа эффективности рекламных компаний.
Если клиент заполняет форму непосредственно на сайте — запомнить данные об его источнике не составляет труда. Но что делать в том случае, если клиент, перейдя на сайт, не заполнял никаких форм, а просто позвонил? Данные с сайта не передаются в телефон, поэтому по-простому узнать, откуда пришёл клиент, совершивший звонок, не выйдет.
Для решения этой проблемы есть одна хитрость, которая называется коллтрекинг. Обычно, когда говорят про коллтрекинг, подразумевают дорогие сервисы с необходимостью накупить кучу телефонных номеров, которые будут подсовываться посетителям сайта в зависимости от источников (статический коллтрекинг) или сессий (динамический коллтрекинг). Всё это влетает в копеечку. Я расскажу, как сделать простой коллтрекинг бесплатно своими руками без регистрации и без смс, не нужно будет даже дополнительные номера покупать. Отмечу, метод не волшебный и обладает как плюсами, так и минусами.
Сегодня очень много людей ищет товары и услуги прямо со смартфонов. Почти половина трафика в рунете — с мобильных устройств. Важным моментом здесь является то, что люди, зайдя на сайт со смартфона, не перепечатывают телефонный номер в звонилку, а просто кликают по нему. Суть метода заключается в том, чтобы отследить клик по телефонному номеру на сайте, запомнить нужные данные о посетителе по клику, а затем связать звонок с кликом на основе временных меток.
16 April 2018, 23:52 MSK
Сегодня Роскомпозор начал думать, что заблокировал мессенджер Телеграм.
Около полутора лет назад я рассказывал, как сделать своего бота для Телеграма, который умеет принимать сообщения и отвечать на них. Но очень часто встаёт другая задача: необходимость отправлять какие-нибудь сообщения или уведомления от бота самому себе прямо из скрипта на PHP (например, с сайта). Это могут быть заявки из формы на сайте, сообщения мониторинга чего-либо, уведомления от каких-нибудь скриптов, ежедневные/еженедельные отчёты и т.д. Можно придумать тысячу сценариев, как это использовать.
Для начала необходимо создать бота. Как я уже писал в прошлой заметке, управление вашими ботами происходит через другого спецбота @BotFather. Для начала нужно добавить его в контакты и что-нибудь ему написать, после чего вы увидите список доступных команд. Отправьте боту команду /newbot, затем напишите в чат имя вашего бота, затем напишите уникальный логин вашего бота (должен заканчиваться на «bot»). В ответ вы получите авторизационный токен — сохраните его и никому не сообщайте. Этот бот будет отправлять нам сообщения.
У Телеграма довольно жёсткая политика конфиденциальности (поэтому там нет спама, как во всяких Вайберах), из-за которой ботом запрещено отправлять сообщения живым пользователям до тех пор, пока пользователь сам не начал беседу с ботом. Поэтому напишите любое сообщение вашему новому боту. Сделать это нужно всего один раз.
Далее необходимо узнать ваш внутренний айди в Телеграме. Проще всего это сделать с помощью бота @ShowJsonBot. Напишите любое сообщение этому боту. В ответ вам придут некие данные в формате JSON. Найдите поле chat, а в нём поле id. Это и есть ваш внутренний айдишник.
Теперь у нас всё готово для отправки сообщений из PHP прямо в Телеграм. Это можно сделать при помощи следующего скрипта:
<?php
// сюда нужно вписать токен вашего бота define('TELEGRAM_TOKEN', '999999999:XXXXXXXXXXXXXXXXXXXXXXXXXXXX');
// сюда нужно вписать ваш внутренний айдишник define('TELEGRAM_CHATID', '99999999');
message_to_telegram('Привет!');
function message_to_telegram($text) {     $ch = curl_init();     curl_setopt_array(         $ch,         array(             CURLOPT_URL => 'https://api.telegram.org/bot' . TELEGRAM_TOKEN . '/sendMessage',             CURLOPT_POST => TRUE,             CURLOPT_RETURNTRANSFER => TRUE,             CURLOPT_TIMEOUT => 10,             CURLOPT_POSTFIELDS => array(                 'chat_id' => TELEGRAM_CHATID,                 'text' => $text,             ),         )     );     curl_exec($ch); }
На этом всё. Если вы хотите, чтобы я сделал бота в Телеграме или другом мессенджере специально для вас, напишите мне: @vkirkizh.
1 April 2018, 22:20 MSK
Когда я нахожусь за границей в поездках, мне необходим мобильный интернет (смотреть карты, строить маршруты, гуглить инфу про места, читать отзывы, искать рестораны, отвечать на почту и т.д.), также мне необходимо оставаться на связи по телефону на своём номере.
Покупать каждый раз местную симку в каждой новой стране — плохая идея. Во-первых, местная симка решает только проблему с интернетом, но не с разговорами. Во-вторых, как правило, все они имеют предоплаченный тариф — то есть, надо заранее решить, сколько ты потратишь денег, неиспользованные средства сгорят. В-третьих, надо тратить время, специально куда-то ехать, чтобы купить эту симку. Не вариант.
Поэтому раньше я всегда пользовался дорогим роумингом. Недавно я был в Берлине и затестил новый способ оставаться всегда онлайн за границей, который гораздо бюджетнее.
Сначала решаем проблему с тем, как дёшево звонить и принимать звонки на своём номере за пределами России. Для этого нам нужен оператор Мегафон (увы, другие не подойдут). Я на нём уже более 15-ти лет, так что всё ОК. У Мегафона есть специальная услуга Мультифон (именно обычный Мультифон, а не Мультифон-Бизнес). Она бесплатная и позволяет совершать/принимать звонки, а также отправлять/принимать смски через интернет вместо GSM по своему домашнему тарифу (по сути, это превращает обычный телефон в IP-телефон). Для этого надо поставить специальное приложение Emotion (iOS, Android). Выглядит оно вот так:
emotion
Переключатель в правом верхнем углу позволяет выбирать между GSM-сетью и интернетом. На скриншоте выбран режим IP-телефонии (звонки и смс через интернет). В этом режиме, где бы мы ни находились, звонки и смски будут стоить столько же, сколько в домашнем регионе без всякого роуминга. Главное, чтобы был интернет. Звонить и отправлять смс нужно именно через это приложение, также в это приложение будут поступать входящие (на айфоне можно не бояться закрыть приложение — у меня всё отлично работало, звонки приходили даже с выключенным приложением, про андроид не в курсе). Если рядом есть вай-фай — больше ничего не нужно. Но, если не сидеть целыми днями в отеле или ресторанах, то вай-фая рядом не будет.
Теперь решаем проблему с дешёвым мобильным интернетом. Я перепробовал несколько вариантов и остановился на международной симке, которая называется Дримсим. Сама симка Дримсим с доставкой стоит 10€. Весь прикол в том, что во многих странах интернет через неё стоит очень дёшево (по сравнению с роумингом). Например, почти во всей Европе 1 гигабайт трафика будет стоить 10€. При этом, тарификация покилобайтная, и нет никаких ограничений (в том числе, на раздачу интернета на другие устройства в режиме модема). Одной симкой с одним счётом можно пользоваться в любой стране. У Дримсима есть своё удобное приложение:
drimsim
Работает это следующим образом. Вы заказываете симку, вам её привозят курьером (если заказать по специальной ссылке, то и мне, и вам дадут по 5€ на счёт). Далее пополняете счёт (это можно сделать любой банковской картой). Перед поездкой вынимаете вашу мегафоновскую симку и втыкаете дримсимовскую, включаете в мегафоновском приложении режим IP-телефонии. Профит. Если разговаривать по телефону через интернет через это приложение, трафика тратится очень немного. У меня получалось меньше 100 мегабайт за час разговора (это меньше 1€). Раньше я тратил минимум 10€ в день на роуминг, а теперь столько же трачу за целую короткую (4-5 дней) поездку.
Через Дримсим также можно совершать звонки напрямую, но это не имеет смысла. Во-первых, звонки будут идти с британского (+44) номера. Во-вторых, цены на звонки совсем не такие интересные, как цены на интернет.
Я пользовался связкой Дримсим+Мегафон в Германии и остался полностью доволен. Но у данного решения есть небольшой минус: Мегафон блокирует смски от банков в своём приложении. Частично это решается включением пуш-уведомлений, но не все банки так умеют. Плюс обычно подтверждения операций покупок по карте в интернете всё равно приходят в виде смсок. Также, к сожалению, далеко не во всех странах поддерживается LTE.
16 March 2018, 20:40 MSK
Дахау — один из первых концентрационных лагерей нацистов, находится недалеко от Мюнхена — столицы Баварии. Сейчас на этом месте открыт мемориальный комплекс в память о жертвах и узниках лагеря. Я побывал здесь во время поездки в Германию в августе 2017.
IMG_6393
11 March 2018, 03:40 MSK
Я долго думал, стоит ли публиковать в блоге не свой код, и решил, что иногда всё-таки стоит, потому что решение описываемой в этом посте проблемы в рунете мне найти не удалось.
Сразу к делу. В мобильном Сафари уже несколько Айосов подряд есть такая замечательная кнопка (вызывается по долгому нажатию на значок перезагрузки страницы в адресной строке):
request-desktop-site
Такая же кнопка есть в Хроме на Андроиде и Айосе. В английском интерфейсе называется «Request Desktop Site».
К сожалению, работает она по-дурацки: когда нажимаешь эту кнопку, браузер просто подменяет свой юзер-агент с мобильного на десктопный, и всё. Кто-нибудь верстает сайты так, чтобы подсовывать браузерам разные стили в зависимости от юзер-агента? Обычно нет.
6 March 2018, 00:20 MSK
Проблема подчёркивания ссылок в вебе стоит очень давно. Лично я согласен с Ководством Лебедева в том, что ссылки всегда должны быть подчёркнуты.
К сожалению, самый очевидный способ подчеркнуть ссылку — CSS-свойство text-decoration: underline; — имеет массу недостатков. Более-менее красиво такие ссылки будут выглядеть только у пользователей мака или айоса, причём, в любом браузере (спасибо, Эппл). Покажу на примере своего блога.
Внешний вид стандартных ссылок в ИЕ:
text-decoration-underline-ie
Это, конечно, никуда не годится. Линия очень жирная. Внешний вид стандартных ссылок на маке:
text-decoration-underline-mac
Уже лучше, линия тонкая (1 пк), но всё равно есть минусы. Во-первых, линия пересекает нижнюю часть буквы «у». Во-вторых, никаким образом кастомизировать (подвинуть по высоте, покрасить в другой цвет) линию не получится. В-третьих, работает только на яблочных девайсах. Таким образом, использовать свойство text-decoration — не вариант. Мы не будем рассматривать свойства text-decoration-style и другие, потому что их поддерживает полпроцента браузеров. Ищем другие пути.
4 March 2018, 01:10 MSK
— А погнали в Казань?
— Так зима же.
— Да пофиг.
— Погнали.
IMG_0527
24 February 2018, 18:30 MSK
9 августа, среда:
— Поехали в Нарву на машине на выходные?
— Может быть, тогда и в Таллин заедем ещё?
— Долго, давай лучше просто в Таллин самолётом.
— Давай. А что по билетам?
— В пятницу утром туда, вечером в воскресенье обратно.
— Отлично.
IMG_5850
20 February 2018, 20:55 MSK
История об ещё одном виде мошенничества в социальной сети ВКонтакте, с которым я столкнулся совсем недавно. Возможно, кому-то пригодится.
У меня есть один развлекательный паблик, который я веду в свободное время (веду не под настоящим именем, поэтому позвольте мне остаться анонимом и не приводить ссылок — на суть дела это не повлияет).
Недавно мне приходит сообщение с предложением продать сообщество:
диалог1
Выходит неплохая цена, учитывая несколько десятков тысяч человек в паблике. Я не собирался ничего продавать, но у меня закрались подозрения, что здесь не всё чисто, поэтому я продолжил диалог.
19 February 2018, 20:18 MSK
Представьте, что у вас возникла необходимость прямо с веб-страницы заказа в вашей CRM-системе открывать папку с файлами, которые к этому заказу относятся. Но не просто отображать содержимое папки, а прямо на компьютере открывать проводник с этой папкой.
К сожалению, сделать это «в лоб» не получится. Во-первых, браузеры умеют открывать только веб-страницы, а не программы на компьютере. Во-вторых, политика безопасности браузеров запрещает доступ ко всему, что явно не разрешено, тем более, доступ к файловой системе.
Вы можете резонно предположить, что есть протокол file:// (я позволю себе использовать здесь и далее слово протокол, хотя правильнее, конечно, схема URI), который позволяет браузерам открывать локальные файлы, но с ним также есть две проблемы:
  1. он не может отобразить список файлов в папке;
  2. такие ссылки нельзя открывать с внешних (не локальных) веб-страниц.
Чтобы решить данную проблему, мы будем использовать свой протокол с собственным обработчиком. Метод будет работать в Виндоус и потребует некоторых (очень простых) действий на компьютере. В ХТМЛ-коде это будет выглядеть как-то так:
<a href="myproto://C:/My Folder/123">открыть папку</a>
Можно из Джаваскрипта:
window.open('myproto://C:/My Folder/123');
Сначала необходимо придумать название протокола (у меня будет myproto) и зарегистрировать его в системе. Для этого в любом месте (хоть на рабочем столе) создаём файл с расширением .reg (например, myproto.reg) и следующим содержимым:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\myproto] "URL Protocol"="" @="URL:Myproto Protocol"
[HKEY_CLASSES_ROOT\myproto\shell]
[HKEY_CLASSES_ROOT\myproto\shell\open]
[HKEY_CLASSES_ROOT\myproto\shell\open\command] @="\"C:\\myproto.bat\" \"%1\""
Здесь myproto — название моего только что созданного протокола. Можете изменить на своё (но не используйте стандартные названия протоколов типа http, ftp, mailto и прочие).
Запускаем файл. Винда выдаст несколько вопросов и предупреждений, со всеми соглашаемся. Всё, больше этот файл на этом компьютере не нужен, можно удалять.
Далее в корне диска C: необходимо создать файл myproto.bat со следующим содержимым:
@echo off
set "path=%~1"
setlocal enabledelayedexpansion
set path=%path:myproto://=%
set path=%path:"=%
set path=%path:/=\%
set path=!path:%%20= !
set path=!path:%%5C=\!
C:\Windows\explorer.exe "%path%"
Здесь также меняем myproto на название вашего протокола. Это и будет его обработчик.
Всё готово. Теперь вы можете прямо из браузера (абсолютно любого) на данном компьютере открывать папки в проводнике в отдельном окне, просто открыв ссылку вида myproto://C:/My Folder/123.
К сожалению, данные действия придётся проделать на всех компьютерах, где необходима такая функциональность. Но, как правило, подобные вещи используются во внутрикорпоративных приложениях, где число пользователей известно и ограничено.
Тэги: batwebdevWin
18 February 2018, 11:52 MSK
Потихоньку перехожу с PHP 5.6 на PHP7 (а точнее, сразу на 7.1). Ответ на вопрос «Зачем?» выходит за рамки данной заметки, поэтому сразу к сути. Если вы тоже решили обновить версию ПХП, вы можете столкнуться с рядом неприятных ошибок, одна из которых возникает из-за ужесточения правил работы числовых операторов, начиная с версии 7.1.
Новые ошибки уровней E_WARNING и E_NOTICE были добавлены при использовании некорректных строк с операторами, ожидающими числа (+ - * / ** % << >> | & ^) и их эквивалентами с присваиванием. Ошибка уровня E_NOTICE выдается, когда строка начинается с цифр, но далее содержит не цифровые символы, и ошибка уровня E_WARNING выдается тогда, когда строка вообще не содержит цифр.
В ПХП версии 7.0 и ниже следующий код будет работать без ошибок:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
$a = 1 + '1text'; echo $a; // 2
$b = 1 + 'text'; echo $b; // 1
$c = ''; $d = 1 + $c; echo $d; // 1
В ПХП версии 7.1 и выше это код выдаст нотис в 5-ой строке, а также ворнинги в 8-ой и 12-ой:
Notice: A non well formed numeric value encountered in test.php on line 5
2
Warning: A non-numeric value encountered in test.php on line 8
1
Warning: A non-numeric value encountered in test.php on line 12
1
Первые два случая особых проблем не вызывают, потому что, если у вас в проекте встречается код, в котором математические операции выполняются над буквами, проблема явно не в ПХП.
А вот третий случай — числовые операции с пустой строкой — часто встречается в реальных проектах. Пустая строка в подобных случаях всегда считалась нулём. Так может быть, например, если вы берёте какое-то числовое значение из конфига, а оно не заполнено. Я заметил, что даже многие библиотеки подвержены данной проблеме.
Решение — одновременно простое и сложное. Нужно добавить явное приведение типа:
$c = '';
$d = 1 + (int)$c;
Проблема в том, что это приходится делать вручную, отследить все такие места автоматически, увы, не получится. И это ворнинг, а не нотис, поэтому отключение через error_reporting(E_ALL & ~E_NOTICE); не сработает. Или надо отключать все ворнинги, а это очень плохая идея.