Блог Максима Федорова

PHP разработчик. Пишу про инструменты в работе, о своих наблюдениях, хобби и проектах.

Портфолио   •   Github    •    Почта    •    Помогаю на Тостере

Ctrl + ↑ Позднее

Отвечаю на вопросы по php

Готов помочь с проблемным кодом на php. Присылайте вопросы, примеры кода и описание задач, которые вы пытаетесь решить. Мне будет полезно отрабатывать навыки, вам возможно найдется решение. Ну сайт делать вам не расскажу как, а вот как настроить сервер, починить отправку писем или как работать с циклом, массивом или классом— велкам!


Присылайте вопросы в Вконтакте или на почту

Помогаю на Тостере

2017   Помощь

Верные друзья джуниора

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

Уметь в контроль версий (GIT)

Пришел с небольшим опытом работы в Гите, но так как не работал в команде, то понятия не имел как работать с ветками. Именно тут и наплутал — сделал одну фичу, но тут же вскоре понадобилось выполнить пару несложных доработок, которые сделал поверх этой первой фичи и запушил их на dev-сервер, еле-еле распутался.

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

И еще:

Следуйте GIT WORKFLOW

Ссылки:
https://habrahabr.ru/post/60030/
https://habrahabr.ru/post/106912/

Любить следующего парня

В первый же день мне пришлось развернуть 3 проекта из приватного репозитория. Ни на одном не было инструкций и мануалов... что? куда? как? хуй его знает...

В итоге на одном проекте не было нужных для php модулей языка. На двух сыпались миграции — пришлось качать с тестового сервера копию базы (что тоже нужно догадаться — где и как взять доступы к ним?), на этих же проектах нужно было узнать — какой доступ к админ-панелям. На третьем все было хорошо, но чтобы создать администратора — нужно было пользоваться консольным приложением, команды которого (как и сам факт его наличия) знает только его разработчик — так себе зависимость ¯\_(ツ)_/¯

По итогу дня я вхреначил в README у каждого проекта инструкцию с установкой, а также вставил описание проблем и прямо захреначил коммиты в prod-ветку — с ветками в гите на тот момент я еще не разобрался ¯\_(ツ)_/¯

Делай инструкции для следующего парня!

Это сбережет новичку нервы, а опытному сотруднику время.

Уметь в  Linux

Очень важно знать консоль и работу с Линуксом. Хорошее знание SSH, настройки хостов в nginx, да и много чего — пригодилось практически с первого дня. Даже чуток помог другому новичку. Кстати почти вся команда разработчиков работает либо под Убунтой, либо под Мак-ОС.

Уметь в автоматические тесты

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

Но вещь при внедрении в проект необходимая. Например я немного улучшил пару контроллеров — разбил один большой на 3 поменьше и вынес пару методов в хелперы, но так как не могу написать тесты, да и вообще их нет на проекте, то просто напросто сейчас не могу проверить работу — фиг его знает, что могло отвалиться и в каком месте. Из-за этого доработку пришлось отложить и ждать для нее лучшего времени.

Тесты нужны, тесты важны, тесты сложны!

Первый опыт работы с учеником

Полторы недели назад взял ученика помогать с работой. В основном нужно много верстать страницы сайта и мейл-письма — хотел разгрузить себя от рутины, нужна была мотивация для самоорганизации и давно уже хотел делиться знаниями.

Бывалый верстальщик показывает как верстать с помощью БЭМ, Богданов И., 1893 год

Зачем взял помощника

Я посчитал, что если взять помощника, и через полтора-два месяца он сможет делать работу, то я смогу брать заказы по программированию и не заморачиваться с версткой и другой работой и при том нормально выучиться по программированию, плюс будет какой-никакой опыт командной работы — например через пару недель буду встраивать в нашу работу GIT, да и с какой стороны не посмотреть — это круто!

Единственным возражением было — ничего не выйдет. Но я посчитал, что это не причина  — если может не получиться, то теперь ничего никогда не пробовать?!

Как нанимал

Было 5 кандидатов — неплохо для зарплаты в 10 тысяч рублей:

  • была девушка, которая как раз собиралась найти работу для практики на лето, но ее по понятным причинам смутила работа на квартире у какого-то лысого мужика :) думаю — это нормально
  • был супер-парень, который учился на автоматизации оборудования, знал bash, Java и  C#, и вообще был матерый, в итоге он ушел в крупную компанию на стажировку, подтвердив этим свое умение думать :)
  • был матерый верстальщик, умеющий верстать пиксель в пиксель — мне показалось, что с его навыками зарабатывать 10 тысяч не совсем уместно...
  • и было два молодых не опытных парня, один закончил колледж по сварке (24 года) , другой студент-юрист (20 лет), оба примерно полгода изучали верстку — именно им и предложил встречу.

На встрече дал обоим тестовое простое задание на верстку — нужно было сделать 2 задания из 3. Оба выполнили задание еле-как, но жалею, что не дал никакого задания по математике — дело в том, что сначала позвал парнишку-сварщика, но он был слабоват в простейших математических операциях и не говорил о своих трудностях, говорил «сделаю» и не делал. Студент-юрист же наоборот — делал все с опережением, проявлял инициативу, но у него началась летняя практика, потому его не позвал на первый день работы.

В итоге взял парнишку постарше — за 3 дня до выхода дал задание как-нибудь сверстать для интернет-магазина страницы товара и категории, но первый день показал, что тяжело идет даже обычная математика — грубо говоря 100 разделить на 4 вызывали минутные задержки. Долго объяснял, как строится ХТМЛ-дерево, что такое классы и стили , когда и как нужно их применять, но я немного разочаровался и в итоге отказал после первого дня.

Но студент-юрист показал себя с лучшей стороны и за вечер выполнил это же задание, в итоге сейчас уже полторы недели работаем вместе.

Обучение и работа

Сильно изменился подход к своей работе.

Джедай Mace Windu, фильм «Звездные войны»

Теперь стараюсь к каждому рабочему дню подготовиться и подготовиться заранее, даю стажеру максимально боевые задания:

  • сверстать адаптивную страницу товара и категории
  • сверстать мобильную страницу товара
  • сверстать слайдер

Причем само задание объясняю подробно, но некоторые вопросы опускаю на самостоятельное решение — вообще не лезу, например освоить OpenServer и Filezilla давал на дом.

Круто, что получается обучаться нам обоим. Например стажер спрашивает про флексы и гриды, а я говорю — делай все без них, в итоге понял, какого хера я торможу — дал ему волю и сам пытаюсь больше усвоить уже за ним. Он сразу же освоил инструменты автоматизации, например Emmet и хоткеи в Sublime — я в самом начале пути о них и не думал, помог ему только, как делать инклуды в  php, чтобы по сто раз не переделывать шапку например. Также раньше редко обращался к документации БЭМ — со стажером дело пошло шустрее, нужно было не просто понять, а еще и объяснить — в итоге материал быстро усвоился.

Помимо всего — основная работа пошла живее, запрограммировал расширенный личный кабинет в магазине, запустил оптовый сайт, изучил несколько крупных разделов по Yii 2. Постоянно идут вызовы — например решился конкретно взяться за LESS и SASS, самому мотивации не хватало — на следующей недели запланировал разобраться и сделать урок по ним.

Что не получается

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


Если не можешь объяснить что-то простым языком — значит ты сам не понимаешь этого в полной мере. Альберт Эйнштейн

Ищу стажера веб-разработчика

Меня зовут Максим Федоров и я руковожу в Новосибирске интернет-магазином одежды (оптовый и розничный) — программирую, автоматизирую работу и помогаю компании повысить продажи, а менеджерам автоматизировать рутину.



Мне нужен помощник для верстки и доработок + помимо работы нужен напарник для изучения фреймворков Yii 2 и Vue.js (или Реакт). Можно студент, желательно из технической специальности.

Мы будем верстать, исправлять баги, создавать лендинги и рассылки, писать первые модули — например парсеры, слайдеры, дорабатывать админку и делать первое REST API. Также изучать вместе со мной программирование и разрабатывать пару сервисов.

Требования:

  • HTML/CSS — уметь быстро сверстать страницу, очень круто если верстали адаптивно
  • PHP — хотя бы понимать, что такое переменные и как подключить файл, знать в теории, что такое массивы и функции, круто если в теории понимаете объектно-ориентированный подход
  • JS — хотя бы на уровне прикрутить плагин JQuery

Условия:

  • Работать будем у меня дома (р-н Пединститута) вместе с котом :-), нужно будет работать около 80-100 часов в месяц.
  • Оплата будет в районе 10-15 тысяч рублей за основную деятельность (интернет-магазин джинс) + возможна премия за хорошую работу
  • Если вы студент, то компания может поставить официальную летнюю стажировку
  • Как понимаете — ищу больше напарника, нежели подчиненного
  • Есть свободный ноутбук с Линуксом и VPS-сервер
  • Работать будем через Github (вместе будем настраивать), а задачи ставиться будут в Трелло и Гугл-Доксе
  • Книги и недорогие подписки за мой счет

По работе остро нужна помощь, если все будет хорошо — будет повышение зарплаты (уже не из моего пирога).

[ ! ] Ко всему прочему сыпятся иногда заказы — не всегда беру из-за занятости, тут прибыль пополам.

Обо мне

Я руководитель интернет-проектов. Мне 26 лет. Сам программирую на уровне джуниора и хорошо верстаю. Помогаю новичкам на форумах по верстке и не сложным доработкам по интернет-магазинам...

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



Читаю почту hello@maksfedorov.ru
И всегда Вконтакте

2017   Работа

Роутинг для PSR 7 Response/Request. Часть 2: Проектируем Router

Содержание:

Добавление правил

Придумываем объект маршрутизации и его метод для добавления правила маршрутизации, в который передаем наш путь, HTTP метод и анонимную функцию:

Поиск нужного правила

Чтобы понять, какой обработчик к нашему запросу относится — придумываем метод, в который мы передаем наш Request, а он сам будет производить проверку по правилам выше и возвращать результат, из которого мы сможем извлекать экшн (анонимная функция) и атрибуты — далее мы должны найденные атрибутты в правилах передать в экшн, точнее в объект Request.
По итогу это должно выглядеть так:

Дополнительные методы для добавления правил**

Прежде чем создавать код для объекта Router — думаем над тем, что можно упростить.
Для того, чтобы не указывать HTTP методы в параметрах, мы можем создать методы объекта Router с названием этих HTTP методов:

Это более удобно, не нужно заморачиваться, также будет работать автоподстановка.

Проблема — много методов

В итоге мы придумали кучу методов, и по итогу можно запутаться — какие методы относятся к масиву правил, а что относится к нему.

Для решения этого — роутер разделяем на 2 части: на коллекции роутов и сам роутер.
https://gist.github.com/Maksclub/e09b1f4ad82b53b813ceb8a3043a878b

Помимо упрощения использования — данное разделение позволяет его использовать надежнее, например потом в контроллере, используя объект Router, нельзя будет добавить маршрут, так как у него нет таких методов.

Генерация адресов

Помимо разбора адресов при разработке и поддержке проектов необходимо адреса генерировать.
Конечно в самих представлениях мы можем выводить жестко:

<a href="/blog/<?= $post->id?>">
    <?= htmlspecialchars($post->title)?>
</a>

Но если нам нужно поменять роуты с /blog/ на /post/ или в магазине /product/ на еще какой-нибудь, то придется в ручную менять во всех местах, что может вылезти косяками в работе проекта.

Тогда придумываем метод generate() для нашего объект Router, с помощью которого мы и будем выводить адреса по названию маршрута:

<a href="<?= $router->generate('название_маршрута', ['id' => $post->id]) ?>">
    <?= htmlspecialchars($post->title)?>
</a>

Как видите нам необходимо имя маршрута. В принципе мы можем использовать путь, который указывали в правилах, но в случае регулярки при ее изменении нам придется менять ее во многих местах, потому для правил добавим еще один параметр с названием роута.

Укрощаем регулярное выражение в правилах

Громоздкие регулярные выражения не удобно записывать, а также метод генерации адреса с регуляркой не работает.

Тогда вместо:

$router->get('blog_show', '/blog/(?P<id>\d+)', ...);

Можно будет упрощенно использовать так:

$router->get('blog_show', '/blog/{id:\d+}', ...);

Но тогда мы не сможем использовать в данном случае сложные правила, например указать число символов в регулярном выражении, так как фигурные скобки нам усложнят парсинг адресов.

Как мы можем поступить:

  • Сам параметр указать чистым, а регулярное выражение передать отдельным параметром, например:
$router->get('blog_show', '/blog/{id}', ..., ['id' => '\d+']);
  • Сделать систему с необязательными параметрами, а сами параметры передавать как токены и задавать значения по умолчанию:
$router->get('blog_show', '/blog[/{page}]', ..., 
     [
         'tokens' => ['page' => '\d+'], 
         'default' => ['page' => 1],
]);

Будет делать именно второй вариант.

Роутинг для PSR 7 Response/Request. Часть 1: Обзор

Сухая выжимка из видео Дмитрия Елисеева PSR-7 фреймворк 2/6: Контроллеры и маршрутизация.

В ходе этого материала мы создадим полноценный роутинг с добавлением правил маршрутизации, с методами генерации, который будет работать с PSR 7 Request/Response, чтобы рассмотреть основные моменты его устройства, а также рассмотрим в конце популярные компоненты для его замены.

Содержание:

Вводные данные

У нас уже есть входная точка для нашего приложения и подключена библиотека для работы с HTTP PSR 7  — в примерах будет Zend Diactoros.

В итоге наш index.php выглядит так:

По коду:

  1. Подключаем фабрику Zend Diactoros, которая конвертирует глобальные переменные в объекты Request и Response
  2. Создаем объект Response и передаем в него значение GET параметра name или строку ’Guest’
  3. Добавляем свой пользовательский заголовок к объекту Response
  4. Отправляем на вывод, добавляя код ответа и тип контента

Первый роутинг

Получим наш пользовательский путь (после исполняющего скрипта, до параметров). На основе этого пути зададим свой объект Response и передадим в каждый соответствующий контент.

Помимо простых путей, мы можем добавить сюда более гибкие пути, например для блога в виде JSON:

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

Это и есть простейший роутинг, но как понимаете — если контент будет сколь заметным или путей будет много — работать с таким кодом будет крайне не удобно.

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

Оптимизация

Чтобы в условиях для каждого роута наши переменные не зассоряли наш эфир и глобальные переменные — поместим этот код в анонимные функции, присвоим их результат переменной $action и после условия выведем результат подходящей условию переменной:

Но у нас появляются неудобства для адресов, которые мы проверяем через регулярку и у нас появляются произвольные параметры. Мы можем передать результат регулярки в качестве параметра в анонимную функцию, но мы не можем точно знать, какие переменные мы можем ожидать.

Но мы можем воспользоваться методом withAttribute() объекта Request, тем самым изменяя сам объект Request, который мы и передаем в анонимную функцию, в итоге выглядет это так:

ADR (Action Domain Response)

Action Domain Response — частный и упрощенный случай MVC.

Суть этого подхода для нас — нам нужно сделать систему маршрутизации, при которой в зависимости от разных адресов мы возвращаем нужную анонимную функцию.

Простейший вариант:

Но для учета HTTP методов (например для REST API) это будет иметь такой вид:

Теперь мы получили представление о том, что нам нужно получить и как это должно работать, в следующей части разберем принцип построения системы маршрутизации перейти к созданию маршрутизации→

Общий принцип оплаты в интернет-магазине через платежную систему (HTTP)

Черновик — есть неточности

Если вам нужно будет организовать оплату на своем сайте и под ваш фреймворк или ЦМС нет готовых решений — его не сложно написать самому.

Общий принцип работы

Все платежные системы работают примерно по одной схеме — у них есть API, который работает в частности через HTTP. При оплате товара магазин отправляет запрос на нужный URL платежки с параметрами заказа.

Нужно несколько параметров, например некий ID заказа, стоимость (price), вспомогательные параметры (например lang(язык), currency (валюта) и т. д...)

Наша цель — редиректить наш заказ на этот адрес, например в контроллере при оплате:

return $this->redirect('https://merchant.ru/payment.aspx?' . http_puild_query([
    'id' => $order->id,
    'price' => $order->price,
]))

Когда сервер платежки получает запрос и пользователь оплачивает — происходят два варианта события: Success или  Fail

Success — значит все отлично и происходит простой редирект назад в магазин.

При регистрации в системе своего проекта мы укзаываем successUrl — именно на него платежка и редиректит, например http://shop.dev/payment/success

Fail — происходит аналогично

URL для проверки заказа

Но при этом есть самый главный URL для взаимодействия — processUrl, этот URL интернет-магазина запрашивается «тайком» платежной системой тогда, когда осуществляется платеж.

Порядок работы:

  1. Оплата → (redirect) → merchant.ru/payment.aspx?id=123&price=1000
  2. Пользователь оплачивает
  3. Когда он нажимает оплатить, платежная система идет с запросом на processUrl, например на /payment/process (GET или POST), передавая параметры — чтобы проверить заказ.
  4. Наш сайт отвечает OK или не OK
  5. Если ОК → платежка списывает с человека деньги, и выводит примерно текст «Перейи на сайт магазина» (которая ведет на successUrl)

Сигнатура

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

https://merchant.ru/payment.aspx?id=123&price=1000&signature=dfg7fh6f54jhfgjh8ол65рро6

Например это мог бы быть некий хэш параметров:

md5($id . ':' . $price);

Но такой можно подменить или разгадать, потому делается чуть сложнее.

Платежки выдают пару ключей:

$password1= 'gfg5fh7677hjf';
$password2= '454545';

Почему нельзя обойтись одним — первый используется при кодировании нашых параметров, то есть
вместо md5($id . ’:’ . $price);
делают md5($id . ’:’ . $price . ’:’ . $password1);

После того как платеж оплачен во время редиректа платежка отправляет в запросе параметр сигнатуры на основе второго пароля, а мы проверяем.

Грубо говоря, через password1 мы подписываем запрос, а на сервере платежки идет проверка, когда платежка отправляет ответ — она подписывает его через password2. Так как данные ключи есть и у клиента и у платежки — это происходит безопасно и удобно.

Как я искал работу на vc.ru и в соцсетях

С самого начала этого года мне пришлось искать работу. Небольшая история, которая может подсказать несколько интересных ходов.

Нетрадиционный поиск — через vc.ru

Сразу после НГ праздников разместил свое резюме на vc.ru, результаты:

  • 6 предложений — 3 из Москвы, 2 из Питера, 1 из Казани и 1 из Новосибирска, еще пару предложений было через месяц и через два,
  • 400 человек смотрели резюме, в среднем смотрели 2,1 страницы и провели 2,28 минуты на сайте — внимательно изучали портфолио и читали некоторые статьи,
  • Просмотры в основном из Москвы (105) и Питера (40)

Скрин на 20 января


На самом деле это успех — такой результат только с одной площадки. В резюме не стал раздувать свой опыт и навыки, зарплата была обоснована и не надута, а еще указал недостатки, что повлияло на ожидания соискателей — не было мусора и пустых вопросов.

Без остроты рассказываю про недостатки

Нетрадиционный поиск — через соцсети

Тут было проще — открыл 2ГИС и пошел по всем веб-студиям и диджитал-агентствам в центре Новосибирска. В основном старался найти руководителей в ВКонтакте или Фейсбуке и списаться с ними для встречи. Писал и звонил очень много, в итоге встретился раз 5, с некоторыми компаниями переписывался долго и в ходе переписке определялись, чем подходим друг другу.

Сообщения старался писать под потребности компании и их вакансии

Вывод:

Соцсети и тематические СМИ — комфортный и удобный канал для поиска работы

Традиционные каналы

Тем не менее, нашел работу через «Зарплата.ру» — это местный агрегатор вакансий, типа «Хедхантера». Еще искал работу по горячим вакансиям. В итоге предложили работу по размещенному резюме, на поднятие которого потратил в районе 400 рублей :)

2017   Работа

Как подписаться на меня

После страшного события в Питере (мои соболезнования родственникам) ожидаю:

  • витка затягивания гаек в интернете
  • затягивания гаек после митингов
  • до этого всего курс был однозначный

Может кто-то и заметил, вчера меня заблокировали в ВК за репост митингов https://maksfedorov.ru/blog/all/vk-zablokiroval-menya-za-repost/
не регулярных, а за одно видео, выложу его и снова заблочат.

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

Безопасность одобряю, но прослушку россиян «по умолчанию» со стороны ведомств — считаю как раз дико не безопасным и чреветым утечками данных. Наши дебилы в Госдуме вечно путают причину со следствием.

Я на связи

Связаться со мной можно любым способом, везде читаю и отвечаю — например задать вопрос или предложить работу над проектом:

РСС блога:
https://maksfedorov.ru/blog/rss/

Телеграмм:
https://t.me/@maksfedorov

Фейсбук:
https://www.facebook.com/maksfedorovru

Почта:
hello@maksfedorov.ru

ВК заблокировал за репост видео

UPD: Поддержка ответил, причина — описание на странице видео

Заблокировали за попытку вставить видео на страницу — видео о митинге 26 марта от старика, который не понимает, за что загребли столько молодых людей.

Как было все:

  1. Вставил видео на стену
  2. Меня попросил подтвердить аккаунт и сменить пароль -> обновил и снова добавил видео
  3. Слету прилетел бан на сутки

И даже не скрыли за что:

Написал, чтобы разбанили с возможностью зарепостить видео из Ютуба.

Хочу обратить внимание на «Вы» с большой буквы. Прямо испытываю оргазм от такого «уважения» «увлажнения».

Ctrl + ↓ Ранее