Получи случайную криптовалюту за регистрацию!

Beer::PHP 🍺

Логотип телеграм канала @beerphp — Beer::PHP 🍺 B
Логотип телеграм канала @beerphp — Beer::PHP 🍺
Адрес канала: @beerphp
Категории: Технологии , Образование
Язык: Русский
Количество подписчиков: 3.05K
Описание канала:

Здесь публикуются короткие заметки о PHP, Linux, Unit Testing, DB, OOP, etc., выдержки из статей, книг, видео, курсов и других материалов.
Теперь тебе больше не нужно перерывать тонны информации ;)
@genkovich — написать автору канала.

Рейтинги и Отзывы

3.33

3 отзыва

Оценить канал beerphp и оставить отзыв — могут только зарегестрированные пользователи. Все отзывы проходят модерацию.

5 звезд

1

4 звезд

0

3 звезд

1

2 звезд

1

1 звезд

0


Последние сообщения 4

2021-09-14 09:07:17 Битовые операции (часть 1, сдвиг влево и вправо)

В мире PHP эти операции встречаются редко, однако в статьях, книгах, либках и других источниках легко можно встретить запись типа:

~
$memory = memory_get_usage() >> 20;

И тут наступает ступор, что за ">>"? Лезешь в доку а там

$a >> $b — Сдвиг вправо. Все биты переменной $a сдвигаются на $b позиций вправо (каждая позиция подразумевает "деление на 2").

Чё сдвигается, куда? Зачем вообще оно надо? Давайте разбираться.

Думаю многие знают, что число в двоичной (бинарной) системе исчисления представляет собой набор нулей и единиц. Например число 6 будет представлено как 00000110.

Побитовый сдвиг в PHP - это арифметическая операция. Биты, сдвинутые за границы числа, отбрасываются. Сдвиг влево дополняет число нулями справа, сдвигая в то же время знаковый бит числа влево, что означает что знак операнда не сохраняется. Сдвиг вправо сохраняет копию сдвинутого знакового бита слева, что означает что знак операнда сохраняется.

Возвращаемся к нашему оператору >>

$n = 6; // 00000110
$k = $n >> 1; // 00000011

Здесь четко видно, что мы отбросили самый правый бит, а слева дополнили нулём. Соответственно запись 00000011 в двоичном представлении равна 3 в десятичном. То есть фактически сдвинув один бит — мы поделили на 2, а если сдвинем на 2 бита, то еще раз поделим на 2 (то есть на 4), на 3 бита — получится что на 8.

Стоп. Да это же степени двойки!

Возвращаясь к нашему первому примеру >> 20, получится, что мы делим наше исходное значение на 2 в степени 20. Легко запомнить, что 2^10 = 1024. Тогда:

$memory = memory_get_usage() / (1024 * 1024);

Так как функция memory_get_usage() возвращает значение в байтах, то мы всего-лишь перевели всё в Мб. Получается достаточно удобно:

>> 10 приводит в Кб
>> 20 приводит в Мб
>> 30 приводит в Гб

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

$y = 5; // 000000101
echo $y << 2; // 000010100 (5 * 4 = 20)

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

define('U_READ', 1 << 0); // 0001
define('U_CREATE', 1 << 1); // 0010
define('U_EDIT', 1 << 2); // 0100
define('U_DELETE', 1 << 3); // 1000
define('U_ALL', U_READ | U_CREATE | U_EDIT | U_DELETE); // 1111

Выглядит интересно, но об этом и других битовых операциях мы поговорим в следующей части :)

#php #junior #source
1.7K viewsКирилл Сулимовский, 06:07
Открыть/Комментировать
2021-09-03 09:20:00 Атрибуты (part 1, что это такое?)

Сейчас много разговоров о PHP 8, ещё больше о 8.1. Есть куча крутых фишек, есть спорные, а есть те, с которыми лень разбираться. Одна из таких атрибуты. К сожалению только несколько человек из тех, кого я собеседовал, смогли ответить на вопрос — что это такое. Причины могут быть разные (еще не перешли на 8 / долго и лениво читать / оно как-то работает и пусть), но для тех, кто всё же хочет чуть-чуть разобраться я пишу этот пост.

Сама концепция уже давно известна, мы много лет используем аннотации (докблоки) для добавления каких-то метаданных к классам, свойствам, методам, переменным и т.д. Думаю всем давно известны примеры из PHPUnit, Doctrine ORM, Assert и многих других либок и фреймворков.

Как это работало раньше?

В PHP докблоки «рефлексивны»: к ним можно получить доступ с помощью метода API Reflection getDocComment() на уровне функции, класса, метода и атрибута. Сначала нужно было получить комментарии класса и метода(ов), затем с помощью регулярных выражений распарсить необходимые аннотации. Код выглядел примерно так.

Как это работает сейчас и в чём разница?

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

Также можно (а согласно документации даже очень нужно) создавать классы атрибутов для этого нужно использовать атрибут #[Attribute], который можно импортировать из глобального пространства имён с помощью оператора use. Они могут быть пустыми, но так-же могут содержать дополнительную информацию, в виде параметров которую также легко можно прочитать:

$attributes = $reflection->getAttributes(MyAttribute::class);
foreach ($attributes as $attribute) {
$attribute->getArguments();
}

Как вы поняли из примера, параметры будут переданы в конструктор класса MyAttribute. Параметры могут быть простыми скалярными типами, массивами, константами и т.д.

В следующей части рассмотрим ограничения, повторяющиеся атрибуты, класс ReflectionAttribute и фильтрацию ;)

#php #middle #source
1.8K viewsКирилл Сулимовский, edited  06:20
Открыть/Комментировать
2021-09-02 15:00:41
Сегодня я решил поделиться одним каналом, который читаю сам. Его ведет Артём Бородатюк, основатель Netpeak Gruop, где я работаю в одной из компаний :)

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

1. Подробная инструкция "Как воплотить в жизнь идею IT-стартапа" с минимальными потерями времени и денег. Буквально недавно скидывал одному из подписчиков.

2. Тенденция выгорания - почему это происходит и как это остановить? Думаю это очень актуальная тема в нашей сфере.

3. Прикольный плагин для браузера, который составляет твой психопортрет и подбирает наилучшую стратегию для общения.

Подписывайтесь, там еще много прикольных постов, которые стоит почитать ;)
1.8K viewsКирилл Сулимовский, 12:00
Открыть/Комментировать
2021-08-30 17:00:26 AmoMedia (Genesis) шукає Jun, Mid PHP Devs.

Ми – найбільша Digital Media компанія України. Щоденно наші сайти дивиться мільйонна аудиторія (80% з якої – США).
Один з наших найвідоміших проектів -
AmoMama – входить в Топ-200 новинних
сайтів світу. Ми про медіа нового покоління: якісний контент на основі аналітики, несемо правдиву і унікальну інформацію.

Цінності та стандарти проекту AmoMama:
• Наші читачі - наш пріоритет номер один;
• Ми пропонуємо нашим читачам у всьому світі
найактуальніший розважальний контент;
• Ми незалежне та аполітичне видання;
• Наша сила – це робота із органічним трафіком.

Про нашу команду:
2 BE (Sen PHP/Go, Mid);
5 FE (2 Sen, 2 Mid, Jun);
5 QA (Sen/TL AQA, Mid AQA, 2 Mid Man, Sen Man); 3 DevOps.

Тобі до нас, якщо:
• Зацікавлений працювати в продукті.
• Хочеш працювати з цікавим стеком технологій: PHP 7.4, Symfony 5, Yii 2, MySQL 8, MongoDB, Memcached, ElasticSearch, Docker, AWS.
• Хочеш додатково вивчити Go.
• Зацікавлений в можливості розвитку (маємо кейс, коли кандидат приходив до нас як Senior, взяли як Middle, проте за рік виріс до Lead всього направлення).
• Прагнеш до постійного навчання і не стоїш на місці.
• Є бажання проявляти ініціативу і впливати на результати
продукту - тут точно почують твої ідеї.

Що потрібно, аби долучитися до нашої команди:
• Досвід в ролі BE Engineer від 1 року;
• Знання PHP 7;
• Маєш досвід роботи з будь-яким фреймворком PHP;
• Працював з MySQL;
• Маєш розуміння OOP, Solid;
• Буде плюсом досвід роботи в продуктовій команді. Потрібно буде глобально розуміти специфіку продукту.

Нас об’єднує не офіс або робочий час, а спільні інтереси та мета. Ми створюємо щось осмислене і нам подобається це робити разом!

Вакансія в Києві, з можливістю по чт і пт працювати віддалено.
Тут повний опис: https://gen-tech.breezy.hr/p/03e95f2502f1.

Писати: https://t.me/iryna_zavtonova
996 viewsКирилл Сулимовский, 14:00
Открыть/Комментировать
2021-08-25 09:20:00 Хеш-таблицы, Hash Tables (part 2)

В данной части мы немного подробнее поговорим о вычислительной скорости (О большое) и о том, как там всё происходит под капотом.

Ранее мы рассматривали бинарный поиск по телефонному справочнику. Хоть он работает достаточно быстро, но всё равно занимает время O(log n). Теперь представьте, что есть человек с феноменальной памятью, который смог запомнить все записи из этого справочника и вместо того, чтобы искать телефон в книге — вам достаточно назвать имя и фамилию, а этот человек мгновенно предоставит номер телефона. Получается, что в этом случае он может назвать номер телефона за время О(1), независимо от размера справочника. То есть этот алгоритм работает еще быстрее, чем бинарный поиск.

Но при чем тут хеш-таблица?

Продолжим рассматривать пример из предыдущего поста. Представим, что у нас есть пустой массив $phones = []; В котором и будут храниться все номера телефонов. Передаём "Sam Doe" в нашу хеш-функцию, получаем 998, сохраняем номер телефона в элементе массива с индексом 998:

$phones = [];
$index = someHashFunction('Sam Doe');
$phones[$index] = '+1-555-5030';

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

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

$index = someHashFunction('Lisa Smith'); // 1
$phone = $phones[$index];

Соответственно мы сразу знаем где находится элемент, а значит, что скорость выполнения операции поиска (а также вставки и удаления) равна O(1). Но сразу оговорюсь, что это не совсем так.

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

$index = someHashFunction('Sam Doe'); // 234
$index = someHashFunction('Jack Duck'); // 234

Для решения подобных ситуаций можно использовать метод цепочек:

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

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

Если выбран метод цепочек, то вставка нового элемента происходит за O(1), а время поиска зависит от длины списка и в худшем случае равно O(n). Если количество ключей n, а распределяем по m-ячейкам, то соотношение n/m будет коэффициентом заполнения.

Cтруктур хэш-таблиц огромное множество, и ни один из них не совершенен, в каждом есть компромиссы. Одни варианты лучше при добавлении данных, другие — при поиске и т. д. Выбирайте реализацию в зависимости от того, что для вас важнее.
1.4K viewsКирилл Сулимовский, 06:20
Открыть/Комментировать
2021-08-20 11:00:16
Получи практический опыт в IT от экспертов NIX!

Приглашаем всех на онлайн-презентацию наших бесплатных программ обучения.

Когда: 26.08, в 16:00
Где: на YouTube-канале NIX

Во время онлайн-трансляции ты узнаешь:
● какие IT-направления можно изучать в NIX;
● какие знания нужны, чтобы попасть на бесплатное обучение;
● как проходят групповые занятия с ментором.

Для кого:
● студентам и выпускникам технических и гуманитарных специальностей;
● начинающим программистам и другим IT-специалистам;
● всем, кто мечтает начать карьеру в IT.

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

Хочешь узнать больше?
Эксперты NIX ответят на все твои вопросы в прямом эфире.
Не теряй времени — жми на колокольчик на странице трансляции по ссылке, чтобы вовремя получишь напоминание о начале cтрима.
1.2K viewsКирилл Сулимовский, 08:00
Открыть/Комментировать
2021-08-19 13:00:55 Хеш-таблицы, HashTables (part-1)

Ну что, отпуск окончен, теперь с новыми силами пришла пора приступить к статьям :) Здесь речь пойдёт именно о структуре данных. То есть пока мы не будем вдаваться во внутренности php (например под капотом языка массивы реализованы именно с помощью хеш-таблиц).

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

Пока звучит сложно, но сейчас попробуем разобраться ;) Для начала определимся с тем, что такое хеширование.

Хеширование — операция, которая преобразует любые входные данные в строку (реже число) фиксированной длины. Функция, реализующая алгоритм преобразования, называется "хеш-функцией", а результат называют "хешем" или "хеш-суммой". Наиболее известны CRC32, MD5 и SHA (много разновидностей). Также стоит упомянуть, что хеш не имеет возможности быть преобразованным обратно в исходные данные.

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

Например, на картинке выше мы видим, что хеш-функция сопоставила ключ John Smith с индексом 873, а далее в хеш-таблицу под этим индексом было записано значение, а если быть точным, то комплексный объект, содержащий исходный ключ и значение (в нашем случае номер телефона).

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

$key = 'John Doe';
$index = crc32($key) % 1000; // по модулю
print_r($index); // => 434

В данном примере мы используем так называемое "адресное пространство", которое задаёт размеры нашей хеш-таблицы. Так как мы получаем остаток от деления на 1000, то все значения нашего индекса будут лежать в диапазоне от 0 до 999. Возникает вопрос "может ли случиться так, что для разных ключей будет рассчитан один и тот же индекс?" — может, но это не значит, что значения затрутся. Структура таблицы станет чуть сложнее, незначительно вырастет вычислительная сложность, но подробнее об этом в следующем посте ;)

Главное, что ваша хеш-функция должна:

1. Быстро вычислять хеш (индекс), в разных источниках можно встретить понятие "адрес", это одно и то же;
2. Всегда возвращать один и тот же адрес для одного и того же ключа;
3. Использует все адресное пространство с одинаковой вероятностью;

Зачем так всё усложнять?

Вся прелесть этой структуры данных заключается в скорости выполнения операций, но об этом мы поговорим в следующей части. Если забыли о том, что такое О-большое, то вот напоминалка ;)

#middle #algorithm #source
1.2K viewsКирилл Сулимовский, edited  10:00
Открыть/Комментировать
2021-08-13 10:05:00 Твоя карьера начинается на NIX IT Camp!

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

Когда: 23–24 августа, регистрация с 10:30
Где: Харьков, Арт-завод «‎Механика», Парковая зона

На мероприятии ты сможешь:

● прослушать лекции о .NET, Java, iOS, Android, Magento, JS, BA, QA, PM, DevOps и по нетехническим направлениям;
● пообщаться с экспертами и принять участие в практических воркшопах;
● узнать о вакансиях в NIX и пройти экспресс-собеседование с рекрутером;
● получить оффер в команду в тот же день!

Все участники смогут получить на почту электронный сертификат, подтверждающий участие в образовательных лекциях и воркшопах на NIX IT Camp — достаточно отсканировать специальный QR-код во время ивента. При желании ты всегда сможешь прикрепить сертификат к своему резюме.

Для кого мероприятие:

● студентов и выпускников технических и гуманитарных специальностей;
● студентов и выпускников IT-курсов;
● начинающих программистов;
● фрилансеров из сферы IT — разработчиков, тестировщиков и всех-всех IT-специалистов;
● всех, кто мечтает начать карьеру в IT.

Не пропусти самый масштабный IT Camp этого лета. Регистрируйся по ссылке!

P.S. Мы заботимся о комфорте каждого участника. Поэтому просим соблюдать правила безопасности. Подробнее — на сайте мероприятия.
1.5K viewsКирилл Сулимовский, 07:05
Открыть/Комментировать
2021-07-28 09:20:00 Введение в Opcode и Opcache

Во время нескольких последних собеседований, которые я проводил, задавал кандидатам на Middle позицию вопрос: Можешь в общих чертах рассказать что такое Opcache, зачем он нужен и как он работает? К сожалению ни один из них даже не попытался. Я был крайне удивлён, ведь в последнее время эта тема была на слуху, благодаря preload и JIT. Но практика показывает обратное. Подумал, что стоит посвятить короткий пост (не вдаваясь в подробности выделяемой памяти и работы ZMM) этой теме.

Все мы знаем, что PHP — интерпретируемый язык. Но что на самом деле происходит с нашим PHP скриптом?

Изначально наш код читается, происходит его разбор и преобразование в так называемые "токены". Это позволяет нашему интерпретатору разбить код на фрагменты, понять где они находятся. Этот процесс называется токенизация или лексирование.

Дальше, имея токены, происходит синтаксический анализ (он также называется parsing), который генерирует абстрактное синтаксическое дерево (Abstract Syntax Tree — AST) для того чтобы было проще понять какие есть операции и какой у них приоритет. На этом этапе приходит анализ тех самых токенов. Уверен, что каждый из вас хоть раз видел ошибку типа:

Parse error: syntax error, unexpected token "==", expecting "(" in script.php on line 10.

и задавался вопросом "что за token"? Теперь тайна раскрыта :)

Дальше происходит компиляция (преобразование) AST в операционный код (Opcode), который наконец и сможет быть выполнен. Не стоит путать, преобразование происходит не в команды ассемблера (очень низкоуровневые), это именно опкоды для виртуальной машины PHP, в них гораздо больше логики.

Далее, виртуальный движок Zend VM (Virtual Machine) получает список наших Opcode и выполняет их! Вот схема всего процесса.

Но после выполнения опкоды немедленно уничтожаются. Возникает вопрос: зачем нам каждый раз токенизирвоать, парсить и компилировать PHP код?

Очень маловероятно, что на production-серверах PHP-код изменится между выполнением нескольких запросов, а значит и Opcode будет точно таким же.

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

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

#php #middle #opcache #source
1.5K viewsКирилл Сулимовский, edited  06:20
Открыть/Комментировать
2021-07-23 09:35:00 Symfony .env и как его готовить

Чем больше я сталкиваюсь с проектами, тем больше вижу, что мало кто использует .env в Symfony так, как это рекомендуют в документации фреймворка. Решил остановиться на этом подробнее.

Как было всегда?

В Symfony до 2018 года и во многих других фреймворках мы использовали комбинацию .env и .env.dist (или .env.example). При этом сам .env не коммится в репозиторий (что логично), а .env.dist имел, как правило, только набор переменных и пустых значений.

С какими проблемами можно столкнуться?

При развертке проекта. Не смотря на то, что названия переменных есть, но сами значения надо где-то взять. Приходится что-то придумывать, у кого-то спрашивать, лезть в разные конфиги, что не очень удобно. Конечно многие выкручиваются тем, что добавляют их прямо в dist, а потом перезаписывают руками.

При добавлении новой переменной всем разработчикам следует сразу добавить её в свой .env, иначе при использовании в контейнере мы быстро отловим Exception. Конечно это тоже можно обойти и задать дефолтные значения прямо в yml.

В целом со всем этим можно жить и нет критических проблем, но что предлагают ребята из Symfony?

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

А если даже для локалки не все данные можно коммитить?

Для этого необходимо создать файл .env.local, который будет иметь более высокий приоритет, чем .env, а значит переопределит заданные переменные. Там можно перезаписать необходимые переменные. Все файлы ".local" не коммитятся, то есть для каждого отдельного сервака/компа можно создать и использовать свой .env.local.

Для каждой среды вы можете сделать свои файлы, например .env.dev, .env.test, .env.prod, они также переопределять дефолтные значения, но только в рамках заданного окружения. Эти файлы также коммитятся. Таким образом можно выстроить гибкую иерархию дефолтных значений на все случаи жизни.

Фишки:

При установке некоторых пакетов заботливый Symfony Flex будет сразу добавлять в ваш .env файл необходимые переменные, чтобы вы не забыли об этом. Например после установки Sentry composer require sentry/sentry-symfony, в env появятся вот такие строки.

Реальные переменные окружения (export) имеют преимущество над переменными из файлов. Если нужно — вы можете спокойно экспортировать переменные или сделать source .env и отказаться от использования файла.

Чтобы ускорить продакшн можно использовать composer dump-env prod, который создаст .env.local.php. Это позволит не тратить лишние ресурсы на парсинг .env файла при каждом запросе.

Вы можете переиспользовать уже объявленные переменные внутри своего .env, например:

DB_USER=root
DB_PASS=${DB_USER}-password # присвоит значение root-password

#php #symfony #env #middle #source
1.3K viewsКирилл Сулимовский, 06:35
Открыть/Комментировать