Воркшоп в Студии
#workshop #backend #php #dbms
Студия откроет двери всем желающим посетить наш воркшоп по Backend-разработке 31 октября 2019 в 19:00. Тема мероприятия — «Обработка больших массивов данных». Формат — лайфкодинг с обсуждением происходящего и обменом опыта.
Подробную информацию об ивенте можно найти здесь.
Приходите, будет интересно и полезно.
#workshop #backend #php #dbms
Студия откроет двери всем желающим посетить наш воркшоп по Backend-разработке 31 октября 2019 в 19:00. Тема мероприятия — «Обработка больших массивов данных». Формат — лайфкодинг с обсуждением происходящего и обменом опыта.
Подробную информацию об ивенте можно найти здесь.
Приходите, будет интересно и полезно.
Жадный импорт
#backend #php
Разрабатывая веб-сервис для крупного застройщика, мы столкнулись с задачей импорта большого количества номенклатурных данных. Причем данные выгружались из различных корпоративных систем клиента и представляли собой файлы формата
Данные импорта содержали информацию об объектах застройки с подробными их характеристиками. Данные по каждому объекту перед сохранением в БД должны были проходить определенный препроцессинг в виде валидации, проверок существования справочной информации и определения операции вставки/изменения. Все стандартно.
Осуществляя считывание информации об объектах из различных файлов, мы накапливали информацию на промежуточных шагах в массивы. Затем обрабатывали каждый элемент этого массива — создавали промежуточные объекты для валидации и в конечном итоге модели для сохранения. Упрощенный псевдокод такого подхода можно посмотреть здесь.
При импорте большого количества данных из множества разнородных файлов потребление оперативной памяти становилось все больше. В один момент импорт съел 2 Гб.
«Хватит это терпеть», — сказал разработчик Илья и призвал на помощь генераторы. Их использование позволило избавиться от промежуточных накоплений и обрабатывать данные построчно на лету. Весь процесс импорта после внедрения генераторов стал занимать практически константное значение потребляемой RAM.
Наш псевдокод немного преобразился. Стоит отметить, что использование генераторов делает код чище и позволяет работать с нативными итераторами в PHP.
#backend #php
Разрабатывая веб-сервис для крупного застройщика, мы столкнулись с задачей импорта большого количества номенклатурных данных. Причем данные выгружались из различных корпоративных систем клиента и представляли собой файлы формата
csv и xml.Данные импорта содержали информацию об объектах застройки с подробными их характеристиками. Данные по каждому объекту перед сохранением в БД должны были проходить определенный препроцессинг в виде валидации, проверок существования справочной информации и определения операции вставки/изменения. Все стандартно.
Осуществляя считывание информации об объектах из различных файлов, мы накапливали информацию на промежуточных шагах в массивы. Затем обрабатывали каждый элемент этого массива — создавали промежуточные объекты для валидации и в конечном итоге модели для сохранения. Упрощенный псевдокод такого подхода можно посмотреть здесь.
При импорте большого количества данных из множества разнородных файлов потребление оперативной памяти становилось все больше. В один момент импорт съел 2 Гб.
«Хватит это терпеть», — сказал разработчик Илья и призвал на помощь генераторы. Их использование позволило избавиться от промежуточных накоплений и обрабатывать данные построчно на лету. Весь процесс импорта после внедрения генераторов стал занимать практически константное значение потребляемой RAM.
Наш псевдокод немного преобразился. Стоит отметить, что использование генераторов делает код чище и позволяет работать с нативными итераторами в PHP.
Отлично, оптимизируем дальше
#backend #php #orm
Разрабатывая веб-сервис для крупного застройщика, мы сделали ставку на архитектуру проекта для удобства сопровождения и расширения. В прошлой заметке мы рассказали об оптимизации импорта с сохранением удобства разработки, а сегодня поделимся судьбой импортированных данных при доставке их конечному пользователю.
Первоначально, в пострелизный период, сервис хранил и обрабатывал около 300 квартир с сопутствующими номенклатурными данными. Для обеспечения реактивности интерфейсов и удобства вывода данные о сущностях и их атрибутах собирались в единую структуру. Это позволяло достаточно быстро перестраивать клиентский вывод без дополнительных REST-запросов, при этом фильтруя и сортируя данные.
Сервис развивался, и в какой-то момент нам выгрузили 1200 квартир. С учетом всех реляций количество связанных объектов стало достаточно большим — на одну квартиру приходилось около 12 связанных объектов с нетривиальной выборкой через ActiveRecord-модели. Конечный набор json-данных стал формироваться за 4 секунды.
«Хватит это терпеть», — сказал разработчик Илья и принялся оптимизировать, вооружившись профайлером и литром пива. Исходные данные профайлера: 4 секунды, 64 Мб памяти и более 140 запросов в БД. Используя эти данные, мы добавили недостающие индексы по ключам на уровне СУБД, а самое главное — мы оптимизировали реляции в ActiveRecord-моделях и сократили количество запросов к БД. После первой итерации профайлер показал следующее: 3 секунды, 32 Мб памяти и 80 запросов в БД.
Для того чтобы выборки одних и тех же данных не дублировались для каждой квартиры, все справочные данные были вынесены в отдельные запросы для единоразового выполнения.
После этой итерации мы получили следующие результаты: 1,5 секунды исполнения, 24 Мб и 54 запроса. Профайлер показал, что бОльшая часть времени тратится на манипуляции с ActiveRecord-моделями — инициализация и маппинг данных в объекты.
«Не на массивах же все это делать»
На последнем этапе оптимизации мы отказались от использования ORM. ActiveRecord-модели были заменены на заполнение простых DTO-объектов. Общение с БД и выборку данных мы реализовали через построитель запросов фреймворка Yii. Финальный результат: 0,4 секунды, 18 Мб памяти и около 32 запросов в БД.
#backend #php #orm
Разрабатывая веб-сервис для крупного застройщика, мы сделали ставку на архитектуру проекта для удобства сопровождения и расширения. В прошлой заметке мы рассказали об оптимизации импорта с сохранением удобства разработки, а сегодня поделимся судьбой импортированных данных при доставке их конечному пользователю.
Первоначально, в пострелизный период, сервис хранил и обрабатывал около 300 квартир с сопутствующими номенклатурными данными. Для обеспечения реактивности интерфейсов и удобства вывода данные о сущностях и их атрибутах собирались в единую структуру. Это позволяло достаточно быстро перестраивать клиентский вывод без дополнительных REST-запросов, при этом фильтруя и сортируя данные.
Сервис развивался, и в какой-то момент нам выгрузили 1200 квартир. С учетом всех реляций количество связанных объектов стало достаточно большим — на одну квартиру приходилось около 12 связанных объектов с нетривиальной выборкой через ActiveRecord-модели. Конечный набор json-данных стал формироваться за 4 секунды.
«Хватит это терпеть», — сказал разработчик Илья и принялся оптимизировать, вооружившись профайлером и литром пива. Исходные данные профайлера: 4 секунды, 64 Мб памяти и более 140 запросов в БД. Используя эти данные, мы добавили недостающие индексы по ключам на уровне СУБД, а самое главное — мы оптимизировали реляции в ActiveRecord-моделях и сократили количество запросов к БД. После первой итерации профайлер показал следующее: 3 секунды, 32 Мб памяти и 80 запросов в БД.
Для того чтобы выборки одних и тех же данных не дублировались для каждой квартиры, все справочные данные были вынесены в отдельные запросы для единоразового выполнения.
После этой итерации мы получили следующие результаты: 1,5 секунды исполнения, 24 Мб и 54 запроса. Профайлер показал, что бОльшая часть времени тратится на манипуляции с ActiveRecord-моделями — инициализация и маппинг данных в объекты.
«Не на массивах же все это делать»
На последнем этапе оптимизации мы отказались от использования ORM. ActiveRecord-модели были заменены на заполнение простых DTO-объектов. Общение с БД и выборку данных мы реализовали через построитель запросов фреймворка Yii. Финальный результат: 0,4 секунды, 18 Мб памяти и около 32 запросов в БД.
Франц Апачевич Кафка 🤣
#backend #php
Для того чтобы пользователь не ждал завершения тяжелых интеграционных операций, лучше исполнять их в фоновом режиме. Например, отправки email-письма через внешний SMTP-сервер или получения курса валют из системы внутреннего контура банка.
В зависимости от ситуации мы применяем различные механики запуска процессов в фоне, но в большинстве своем они сводятся к организации очередей обработки и к работе с брокерами сообщений.
В простейшем случае очередь сообщений можно организовать на одной таблице в реляционной БД, в которую добавлять записи с действиями для обработки и удалять (помечать выполненными) при завершении этой обработки. Для каждого современного фреймворка существуют расширения или composer-пакеты, реализующие работу с очередями.
Например, для Yii расширение yii2-queue включено в ядро фреймворка. Такие расширения поддерживают современные драйверы очередей, основанные на работе с RDBMS, Redis, RabbitMQ, Beanstalk, Gearman и т.д.
Отходя от фреймворков, рассмотрим, как в простейшем случае организовать работу с еще одним, более продвинутым, распределенным, журналируемым диспетчером сообщений — Apache Kafka.
Для быстрого запуска инфраструктуры, опишем сервисы, необходимые для работы Apache Kafka в docker-compose.yml. Допустим, что контейнер консольного PHP-приложения строится на образе php:7.3-cli-alpine. Тогда для взаимодействия c Apache Kafka нам необходимо дополнить этот образ специальным расширением-клиентом php-rdkafka.
Теперь осталось сделать простейшую реализацию механизма отправки и получения сообщений. В рамках пилотной настройки небольшой простейший сервис обмена сообщениями на основе Apache Kafka готов.
З.Ы. Для обеспечения подсветки синтаксиса в IDE при работе с классами
#backend #php
Для того чтобы пользователь не ждал завершения тяжелых интеграционных операций, лучше исполнять их в фоновом режиме. Например, отправки email-письма через внешний SMTP-сервер или получения курса валют из системы внутреннего контура банка.
В зависимости от ситуации мы применяем различные механики запуска процессов в фоне, но в большинстве своем они сводятся к организации очередей обработки и к работе с брокерами сообщений.
В простейшем случае очередь сообщений можно организовать на одной таблице в реляционной БД, в которую добавлять записи с действиями для обработки и удалять (помечать выполненными) при завершении этой обработки. Для каждого современного фреймворка существуют расширения или composer-пакеты, реализующие работу с очередями.
Например, для Yii расширение yii2-queue включено в ядро фреймворка. Такие расширения поддерживают современные драйверы очередей, основанные на работе с RDBMS, Redis, RabbitMQ, Beanstalk, Gearman и т.д.
Отходя от фреймворков, рассмотрим, как в простейшем случае организовать работу с еще одним, более продвинутым, распределенным, журналируемым диспетчером сообщений — Apache Kafka.
Для быстрого запуска инфраструктуры, опишем сервисы, необходимые для работы Apache Kafka в docker-compose.yml. Допустим, что контейнер консольного PHP-приложения строится на образе php:7.3-cli-alpine. Тогда для взаимодействия c Apache Kafka нам необходимо дополнить этот образ специальным расширением-клиентом php-rdkafka.
Теперь осталось сделать простейшую реализацию механизма отправки и получения сообщений. В рамках пилотной настройки небольшой простейший сервис обмена сообщениями на основе Apache Kafka готов.
З.Ы. Для обеспечения подсветки синтаксиса в IDE при работе с классами
RdKafka можно в зависимости проекта добавить stubs-пакет.Жучки в моей голове 🐛🐞🐜
#backend #debug #php
Мы не раз писали о способах отладки и профилирования frontend-приложений посредством браузера.
А как же отлаживается backend?🤔 Начинающий php-разработчик предпочитает использовать простые конструкции вывода для отладки данных и структур. Например, такое сочетание крайне часто можно встретить в коде джуниор-разработчика:
Лишь бы такая отладка не дошла до прода 😩
Для полноценной отладки и профилирования кода мы используем Xdebug, который поставляется как php-расширение. Современные IDE, например JB PhpStorm, с легкостью интегрируются с этой библиотекой отладки, как в случае с локальным php-интерпретатором, так и в случае если Xdebug установлен в Docker-контейнере. Наши разработчики применяют специально подготовленное Docker-окружение, и поэтому мы используем второй вариант.
Современные php-фреймворки также предоставляют отладочные инструменты уровня приложения. Например, для профилирования SQL-запросов, которые генерирует ORM.
Удобные отладочные панели есть у фреймворков Yii и Laravel. Если вы не используете каркасы, а разрабатываете приложение на разнородных composer-пакетах или на микрофреймворках, то можно применять, например, PHP Debug Bar.
Важно помнить, что любые средства отладки, будь то отдельные php-расширения либо встроенные в ваш фреймворк компоненты и модули, должны быть отключены в промышленном и тестовом окружении. Их работа регрессивно влияет на производительность приложения, а также через отладочную информацию злоумышленник может получить ценные данные. Инструменты отладки и профилирования должны быть доступны только в процессе разработки веб-приложения.
#backend #debug #php
Мы не раз писали о способах отладки и профилирования frontend-приложений посредством браузера.
А как же отлаживается backend?🤔 Начинающий php-разработчик предпочитает использовать простые конструкции вывода для отладки данных и структур. Например, такое сочетание крайне часто можно встретить в коде джуниор-разработчика:
...
var_dump($someVar); // print_r($someVar);
die();
...
Лишь бы такая отладка не дошла до прода 😩
Для полноценной отладки и профилирования кода мы используем Xdebug, который поставляется как php-расширение. Современные IDE, например JB PhpStorm, с легкостью интегрируются с этой библиотекой отладки, как в случае с локальным php-интерпретатором, так и в случае если Xdebug установлен в Docker-контейнере. Наши разработчики применяют специально подготовленное Docker-окружение, и поэтому мы используем второй вариант.
Современные php-фреймворки также предоставляют отладочные инструменты уровня приложения. Например, для профилирования SQL-запросов, которые генерирует ORM.
Удобные отладочные панели есть у фреймворков Yii и Laravel. Если вы не используете каркасы, а разрабатываете приложение на разнородных composer-пакетах или на микрофреймворках, то можно применять, например, PHP Debug Bar.
Важно помнить, что любые средства отладки, будь то отдельные php-расширения либо встроенные в ваш фреймворк компоненты и модули, должны быть отключены в промышленном и тестовом окружении. Их работа регрессивно влияет на производительность приложения, а также через отладочную информацию злоумышленник может получить ценные данные. Инструменты отладки и профилирования должны быть доступны только в процессе разработки веб-приложения.
Быстро и метко про хороший ООП-код
#useful #backend #php
А вы думаете об архитектуре своего кода? Расскажите нам в комментариях.
Полезное видео от core-разработчика Yii Framework.
https://youtu.be/SKwchYgaJN8
#useful #backend #php
А вы думаете об архитектуре своего кода? Расскажите нам в комментариях.
Полезное видео от core-разработчика Yii Framework.
https://youtu.be/SKwchYgaJN8
Микрозаметка про микрооптимизацию PHP 7+
#backend #php
Практическое применение микрооптимизаций в PHP 7+ скоро полностью войдет в признаки хорошего тона при написании кода. Так, некоторые нативные функции PHP лучше вызывать явно с префиксом корневого пространства имен
Например, в известном инструменте анализа кода PHP Coding Standards Fixer можно встретить вот такой issue с достаточно большой историей обсуждения, вплоть до недавнего времени. Кстати, запрос на фичу поступил от одного из основных контрибьюторов фреймворка Symfony, в котором эта микрооптимизация уже применяется достаточно давно.
#backend #php
Практическое применение микрооптимизаций в PHP 7+ скоро полностью войдет в признаки хорошего тона при написании кода. Так, некоторые нативные функции PHP лучше вызывать явно с префиксом корневого пространства имен
\. Это гарантирует их более быстрое исполнение через интерпретацию соответствующих opcodes.
Например, в известном инструменте анализа кода PHP Coding Standards Fixer можно встретить вот такой issue с достаточно большой историей обсуждения, вплоть до недавнего времени. Кстати, запрос на фичу поступил от одного из основных контрибьюторов фреймворка Symfony, в котором эта микрооптимизация уже применяется достаточно давно.
Отправка почты кабанчику
#backend #debug #php
При разработке и внедрении веб-сервисов мы постоянно используем нотификацию пользователей посредством email-уведомлений. Регистрация, восстановление забытого пароля, маркетинговые акции — все эти события влекут за собой доставку контента пользователю через почту в виде текстовых или html-писем.
До недавнего времени на этапе отладки работы механизмов email-нотификации мы отправляли генерируемые приложением письма в файл, тем самым эмулируя отправку реального письма.
Современные фреймворки в debug-режиме позволяют конфигурировать свои компоненты-мейлеры для мнимой отправки писем в файлы. Так, Yii Mailer имеет параметр конфигурации useFileTransport, а Laravel позволяет указывать драйвер отправки.
Для себя мы нашли более удобный способ эмуляции отправки и просмотра email-уведомлений — MailHog. Причем для фреймворка такой сервис настраивается и представляется абсолютно так же, как и реальный внешний SMTP-сервер, правда, без шифрования.
Этот сервис состоит из двух основных частей — SMTP-сервера и HTTP-приложения для просмотра и управления полученными от клиентов письмами. При этом реализовано несколько режимов хранения писем — в оперативной памяти и в файловой системе. Приятным дополнением ко всему является возможность поставки сервиса в окружение Docker и Docker Compose, а значит, интеграция и внедрение в окружение наших разработчиков.
#backend #debug #php
При разработке и внедрении веб-сервисов мы постоянно используем нотификацию пользователей посредством email-уведомлений. Регистрация, восстановление забытого пароля, маркетинговые акции — все эти события влекут за собой доставку контента пользователю через почту в виде текстовых или html-писем.
До недавнего времени на этапе отладки работы механизмов email-нотификации мы отправляли генерируемые приложением письма в файл, тем самым эмулируя отправку реального письма.
Современные фреймворки в debug-режиме позволяют конфигурировать свои компоненты-мейлеры для мнимой отправки писем в файлы. Так, Yii Mailer имеет параметр конфигурации useFileTransport, а Laravel позволяет указывать драйвер отправки.
Для себя мы нашли более удобный способ эмуляции отправки и просмотра email-уведомлений — MailHog. Причем для фреймворка такой сервис настраивается и представляется абсолютно так же, как и реальный внешний SMTP-сервер, правда, без шифрования.
Этот сервис состоит из двух основных частей — SMTP-сервера и HTTP-приложения для просмотра и управления полученными от клиентов письмами. При этом реализовано несколько режимов хранения писем — в оперативной памяти и в файловой системе. Приятным дополнением ко всему является возможность поставки сервиса в окружение Docker и Docker Compose, а значит, интеграция и внедрение в окружение наших разработчиков.
Yii Framework
Mailer, yii\swiftmailer\Mailer
Не ORM единым
#orm #dbms #doctrine #activerecord #php
Для абстрагирования работы с БД современные фреймворки используют Persistence Layer, где обычно реализуется паттерн Active Record или применяется ORM.
В результате на уровне приложения мы работаем с map-объектами, которые предоставляют удобный API для безопасного (насколько это возможно) манипулирования данными. Такое удобство может негативно сказываться на общей производительности приложения, особенно при сложных выборка зависимых данных.
Одним из решений проблем производительности является внедрение подхода CQRS. Здесь работа по чтению и записи данных разделяется на отдельные методы-обработчики, но от автоматического мапинга данных придется отказаться в пользу plain-text-запросов на выборку данных.
Разобраться с таким подходом новичку поможет доклад ниже 👇
#orm #dbms #doctrine #activerecord #php
Для абстрагирования работы с БД современные фреймворки используют Persistence Layer, где обычно реализуется паттерн Active Record или применяется ORM.
В результате на уровне приложения мы работаем с map-объектами, которые предоставляют удобный API для безопасного (насколько это возможно) манипулирования данными. Такое удобство может негативно сказываться на общей производительности приложения, особенно при сложных выборка зависимых данных.
Одним из решений проблем производительности является внедрение подхода CQRS. Здесь работа по чтению и записи данных разделяется на отдельные методы-обработчики, но от автоматического мапинга данных придется отказаться в пользу plain-text-запросов на выборку данных.
Разобраться с таким подходом новичку поможет доклад ниже 👇
PHP 8: почти новогодний подарок
#php #release #backend
Вышел релиз PHP 8 🎉
Ну а в преддверии этого события было организовано мероприятие с участием основных core-разработчиков — Дмитрия Стогова и Никиты Попова.
Если вы не смотрели прямую трансляцию, то запись мероприятия можно найти здесь. Стоит досмотреть до конца, чтобы послушать сессию «вопрос-ответ» с участием core-разработчиков.
Мы бы хотели выделить несколько наиболее полезных фич, которые точно будем применять. Итак, поехали 👇
— Атрибуты/аннотации. Раньше аналогичный функционал был реализован различными библиотеками на основе обычного
— Расширенная типизация. Раз, два, три! Более строгая типизация была добавлена уже в 7-й версии, но сейчас мы получаем больше возможностей:
— Именованные аргументы. Мы все ближе к Python? 🤔 Нет, но данное поведение теперь позволит пропускать необязательные параметры при вызове функций. Надеемся, это не приведет к росту количества параметров в библиотеках и вашем коде 😎
Все остальные изменения тоже хороши. Язык становится разнообразнее и чище. Мы, как и большинство фреймворков, уже готовы к выходу PHP 8.
А как обстоят дела у вас❓
Chulakov Dev
#php #release #backend
Вышел релиз PHP 8 🎉
Ну а в преддверии этого события было организовано мероприятие с участием основных core-разработчиков — Дмитрия Стогова и Никиты Попова.
Если вы не смотрели прямую трансляцию, то запись мероприятия можно найти здесь. Стоит досмотреть до конца, чтобы послушать сессию «вопрос-ответ» с участием core-разработчиков.
Мы бы хотели выделить несколько наиболее полезных фич, которые точно будем применять. Итак, поехали 👇
— Атрибуты/аннотации. Раньше аналогичный функционал был реализован различными библиотеками на основе обычного
DocBlock, который с трудом понимается IDE, и нужно было все держать в голове. Теперь же каждому будет доступно создание собственных атрибутов и получение из них метаинформации.— Расширенная типизация. Раз, два, три! Более строгая типизация была добавлена уже в 7-й версии, но сейчас мы получаем больше возможностей:
mixed, static и union types.— Именованные аргументы. Мы все ближе к Python? 🤔 Нет, но данное поведение теперь позволит пропускать необязательные параметры при вызове функций. Надеемся, это не приведет к росту количества параметров в библиотеках и вашем коде 😎
Все остальные изменения тоже хороши. Язык становится разнообразнее и чище. Мы, как и большинство фреймворков, уже готовы к выходу PHP 8.
А как обстоят дела у вас❓
Chulakov Dev
Способы слияния массивов в PHP
#backend #php #basics
Работа с массивами является неотъемлемой частью жизни PHP-разработчика. В массивы поступают выборки данных из БД, результаты чтения файлов и обращений к внешним API — список таких операций весьма велик.
Крайне часто необходимо сливать несколько массивов в результирующий с различными артефактами на выходе. Рассмотрим способы слияния и их отличия.
Классический. Пожалуй, самый распространенный способ, знакомый всем и каждому. Функция array_merge решает нашу проблему в случаях, когда нет необходимости следить за изменением или неизменностью числовых ключей массива.
Сложение массивов. Этот вариант мало кто использует, хотя он является классическим с точки зрения алгебры-логики. Стоит отметить, что операция такого арифметического сложения попытается сохранить числовые ключи в результирующем массиве, добавив элементы слагаемых массивов последовательно, в порядке их упоминания при сложении.
Есть два важных момента: при перемене мест слагаемых сумма меняется 😱; если в слагаемых массивах имеются значения с одинаковыми числовыми ключами, то итоговый массив будет содержать значение первого слагаемого.
Слияние с заменой значений. Функция array_replace также позволяет сохранить числовые ключи, при этом заменяя значение в исходном массиве значениями из других переданных массивов в случае совпадения ключей.
Оценить разницу в работе трех способов слияния можно в «песочнице».
#backend #php #basics
Работа с массивами является неотъемлемой частью жизни PHP-разработчика. В массивы поступают выборки данных из БД, результаты чтения файлов и обращений к внешним API — список таких операций весьма велик.
Крайне часто необходимо сливать несколько массивов в результирующий с различными артефактами на выходе. Рассмотрим способы слияния и их отличия.
Классический. Пожалуй, самый распространенный способ, знакомый всем и каждому. Функция array_merge решает нашу проблему в случаях, когда нет необходимости следить за изменением или неизменностью числовых ключей массива.
Сложение массивов. Этот вариант мало кто использует, хотя он является классическим с точки зрения алгебры-логики. Стоит отметить, что операция такого арифметического сложения попытается сохранить числовые ключи в результирующем массиве, добавив элементы слагаемых массивов последовательно, в порядке их упоминания при сложении.
Есть два важных момента: при перемене мест слагаемых сумма меняется 😱; если в слагаемых массивах имеются значения с одинаковыми числовыми ключами, то итоговый массив будет содержать значение первого слагаемого.
Слияние с заменой значений. Функция array_replace также позволяет сохранить числовые ключи, при этом заменяя значение в исходном массиве значениями из других переданных массивов в случае совпадения ключей.
Оценить разницу в работе трех способов слияния можно в «песочнице».
Азы безопасности в PHP от Александра Макарова
#backend #php #security
Используя современные библиотеки и фреймворки, мы не задумываемся о том, как их механизмы обеспечивают безопасность нашего приложения. Например, как шифруются и хранятся пароли пользователей, как валидируются email- и IP-адреса, указанные в формах ввода, как работают с данными объекты-обертки, предоставляющие доступ к HTTP-заголовкам, cуперглобальным переменным.
Если грамотно использовать современные фреймворки, то также можно в меньшей степени задумываться и об SQL-инъекциях и XSS-атаках. А если мы делаем что-то не так? 🤔
Рекомендуем посмотреть выступление Александра Макарова про базовую безопасность в PHP.
Основной тезис доклада — «нельзя доверять данным, несмотря ни на что».
Автор расскажет про способы фильтрации и валидации данных, про проблематику экранирования различных выходных потоков данных и про отдельные виды угроз.
В конце видео приводится список полезных статей и источников для чтения. Рекомендуем посмотреть в первую очередь специалистам среднего уровня и выше — тем разработчикам, которые могут влиять на архитектуру продукта через выбор используемых фреймворков, библиотек и подходов.
Chulakov Dev
#backend #php #security
Используя современные библиотеки и фреймворки, мы не задумываемся о том, как их механизмы обеспечивают безопасность нашего приложения. Например, как шифруются и хранятся пароли пользователей, как валидируются email- и IP-адреса, указанные в формах ввода, как работают с данными объекты-обертки, предоставляющие доступ к HTTP-заголовкам, cуперглобальным переменным.
Если грамотно использовать современные фреймворки, то также можно в меньшей степени задумываться и об SQL-инъекциях и XSS-атаках. А если мы делаем что-то не так? 🤔
Рекомендуем посмотреть выступление Александра Макарова про базовую безопасность в PHP.
Основной тезис доклада — «нельзя доверять данным, несмотря ни на что».
Автор расскажет про способы фильтрации и валидации данных, про проблематику экранирования различных выходных потоков данных и про отдельные виды угроз.
В конце видео приводится список полезных статей и источников для чтения. Рекомендуем посмотреть в первую очередь специалистам среднего уровня и выше — тем разработчикам, которые могут влиять на архитектуру продукта через выбор используемых фреймворков, библиотек и подходов.
Chulakov Dev
Трейты в PHP — зло? Наш взгляд на проблему
#backend #php
В конце прошлого года перед релизом PHP 8 ведущие разработчики языка высказались про неудачную реализацию трейтов в PHP. А после прошел интересный батл «Трейты в PHP — зло?».
Мы относимся к написанию и использованию собственных трейтов с большой осторожностью, стараясь их избегать. И вот несколько причин:
— трейты могут увеличивать связанность (coupling) вашего кода;
— частично решают проблему переиспользования типового инфраструктурного или обслуживающего кода, при этом несут опасность накопления бизнес-логики в руках новичка;
— трейты фактически не определяют структуру и не являются типом, но при этом позволяют применять внутри своих методов конструкции ООП. Например, вызов конструктора или обращения к контексту
А как вы относитесь к трейтам в PHP?
Chulakov Dev
#backend #php
В конце прошлого года перед релизом PHP 8 ведущие разработчики языка высказались про неудачную реализацию трейтов в PHP. А после прошел интересный батл «Трейты в PHP — зло?».
Мы относимся к написанию и использованию собственных трейтов с большой осторожностью, стараясь их избегать. И вот несколько причин:
— трейты могут увеличивать связанность (coupling) вашего кода;
— частично решают проблему переиспользования типового инфраструктурного или обслуживающего кода, при этом несут опасность накопления бизнес-логики в руках новичка;
— трейты фактически не определяют структуру и не являются типом, но при этом позволяют применять внутри своих методов конструкции ООП. Например, вызов конструктора или обращения к контексту
$this. При этом разработчик не может гарантировать, что поведение класса, к которому будет подключен трейт, совпадет с ожидаемым поведением логики работы методов трейта.А как вы относитесь к трейтам в PHP?
Chulakov Dev
❤2💩1
Быстрая сортировка массива по внешнему списку в PHP
#backend #php #lifehack
Иногда возникает необходимость отсортировать массив объектов или массив значений на основе списка значений, хранящегося в другом массиве.
Рассмотрим пример, когда эталонная последовательность идентификаторов, по которой должны быть отсортированы элементы массива
Очевидное решение, которое приходит в голову, — алгоритм на основе цикла, который содержит в себе дополнительные условные проверки и переменные для промежуточного хранения результата.
Для получения более оптимального и красивого решения задачи такой специфической сортировки мы воспользовались несколькими стандартными PHP-функциями для работы с массивами.
В алгоритме предусмотрено решение сопутствующей проблемы, когда набор сортируемых ключей массива
Поэкспериментировать с работой алгоритма можно в «песочнице».
Chulakov Dev
#backend #php #lifehack
Иногда возникает необходимость отсортировать массив объектов или массив значений на основе списка значений, хранящегося в другом массиве.
Рассмотрим пример, когда эталонная последовательность идентификаторов, по которой должны быть отсортированы элементы массива
$items, хранится в переменной $orders.Очевидное решение, которое приходит в голову, — алгоритм на основе цикла, который содержит в себе дополнительные условные проверки и переменные для промежуточного хранения результата.
Для получения более оптимального и красивого решения задачи такой специфической сортировки мы воспользовались несколькими стандартными PHP-функциями для работы с массивами.
В алгоритме предусмотрено решение сопутствующей проблемы, когда набор сортируемых ключей массива
$items может не полностью включать в себя значения массива $orders. Итоговый массив фильтруется по callback-функции, которая проверяет тип значений результирующего массива.Поэкспериментировать с работой алгоритма можно в «песочнице».
Chulakov Dev
💩1
PHP Intl. Правильная транслитерация кириллицы
#backend #php
Современные фреймворки предоставляют готовый функционал в составе библиотек или хелперов для работы с библиотекой ICU через API Intl.
Такой функционал необходим для поддержки интернационализации разрабатываемого веб-сервиса. На основе указанной локали могут устанавливаться форматы отображения валют, времени и даты, а также подбираться настройки для инициализации транслитераторов.
В разделе «Телеграм-каналы» сайта Студии во время автоматического импорта постов из наших каналов производится транслитерация названий заметок для формирования ЧПУ.
После первого релиза мы обнаружили, что транслитерация некоторых букв русского алфавита производится не совсем корректно, даже при верно установленной локали на уровне фреймворка.
Например, уникальная часть URL заметки про релиз PHP 8 после транслитерации имела вид
Для того чтобы транслитерация кириллицы производилась по традиционным правилам, необходимо произвести конфигурацию объекта-транслитератора, передав следующее значение параметра
После такой конфигурации результат преобразования наименования заметки изменится на
Стоит напомнить, что непосредственная работа с объектами-транслитераторами в зависимости от фреймворка может быть организована на различных уровнях абстракции. Например, конфигурация и подмена таких объектов может осуществляться через механизмы внедрения зависимостей.
Chulakov Dev
#backend #php
Современные фреймворки предоставляют готовый функционал в составе библиотек или хелперов для работы с библиотекой ICU через API Intl.
Такой функционал необходим для поддержки интернационализации разрабатываемого веб-сервиса. На основе указанной локали могут устанавливаться форматы отображения валют, времени и даты, а также подбираться настройки для инициализации транслитераторов.
В разделе «Телеграм-каналы» сайта Студии во время автоматического импорта постов из наших каналов производится транслитерация названий заметок для формирования ЧПУ.
После первого релиза мы обнаружили, что транслитерация некоторых букв русского алфавита производится не совсем корректно, даже при верно установленной локали на уровне фреймворка.
Например, уникальная часть URL заметки про релиз PHP 8 после транслитерации имела вид
php-8-pocti-novogodnij-podarok. Замена некоторых букв произошла некорректно.Для того чтобы транслитерация кириллицы производилась по традиционным правилам, необходимо произвести конфигурацию объекта-транслитератора, передав следующее значение параметра
$id:Russian-Latin/BGN; Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC;После такой конфигурации результат преобразования наименования заметки изменится на
php-8-pochti-novogodniy-podarok.Стоит напомнить, что непосредственная работа с объектами-транслитераторами в зависимости от фреймворка может быть организована на различных уровнях абстракции. Например, конфигурация и подмена таких объектов может осуществляться через механизмы внедрения зависимостей.
Chulakov Dev
🔥2💩1
7 важных факторов PHP-приложения
#backend #devops #php
Инженеры платформы Heroku на основе собственного опыта создали методологию для разработки SaaS-приложений.
Эта методология учитывает три важных аспекта:
— расширяемость — развитие кодовой базы и функционала;
— сопровождаемость и возможность командной работы над проектом;
— масштабируемость.
12 факторов приложения стали шаблоном для многих разработчиков и Ops-инженеров, а мы постарались адаптировать самые важные из них для приложений на PHP.
Кодовая база. Забота о коде начинается с принципов его версионирования и хранения. Используйте Git Flow или его адаптацию с учетом специфики работы ваших команд.
Зависимости. Используйте менеджер зависимостей Composer и его основные операции
Конфигурация. Предпочтительным методом обработки конфигурации является использование переменных среды. Для работы с ними мы применяем компонент symfony/dotenv.
Параллелизм. Выполняйте процессы в фоне, тем самым снижая время отклика при взаимодействии с вашим сервисом. Выделяйте веб-процессы в реальном времени и рабочие процессы. Первые принимают http-запросы от клиента, а вторые — выполняют фоновые задачи, например, с помощью брокера сообщений RabbitMQ.
Паритет разработки/работы приложения. Для того чтобы обеспечить схожесть сред разработки, тестирования и продакшена, мы используем виртуализацию на основе Docker и специально подготовленные образы, содержащие одинаковые наборы и версии библиотек. Промышленные и тестовые среды отличаются лишь степенью масштабирования, на основе технологий K8S и Swarm.
Журналирование. Фактор утверждает, что приложение должно просто писать в STDOUT и STDERR, а среда должна отвечать за маршрутизацию этих сообщений в хранилище. Технология PHP-FPM позволяет производить вывод логов в STDOUT, что крайне полезно при работе с Docker-контейнерами. Для организации процесса логирования на уровне приложения мы используем сторонние внешние библиотеки, например Monolog или компоненты фреймворков.
Задачи администрирования. Реализовать сценарии администрирования приложения можно с помощью внешних библиотек, например Symfony Console. Большинство современных фреймворков имеют встроенные средства для организации запуска консольных команд для служебных целей и миграций. Например, в Yii Framework есть понятие консольного приложения и команды.
Chulakov Dev
#backend #devops #php
Инженеры платформы Heroku на основе собственного опыта создали методологию для разработки SaaS-приложений.
Эта методология учитывает три важных аспекта:
— расширяемость — развитие кодовой базы и функционала;
— сопровождаемость и возможность командной работы над проектом;
— масштабируемость.
12 факторов приложения стали шаблоном для многих разработчиков и Ops-инженеров, а мы постарались адаптировать самые важные из них для приложений на PHP.
Кодовая база. Забота о коде начинается с принципов его версионирования и хранения. Используйте Git Flow или его адаптацию с учетом специфики работы ваших команд.
Зависимости. Используйте менеджер зависимостей Composer и его основные операции
install и update для манипуляций c composer.json и composer.lock.Конфигурация. Предпочтительным методом обработки конфигурации является использование переменных среды. Для работы с ними мы применяем компонент symfony/dotenv.
Параллелизм. Выполняйте процессы в фоне, тем самым снижая время отклика при взаимодействии с вашим сервисом. Выделяйте веб-процессы в реальном времени и рабочие процессы. Первые принимают http-запросы от клиента, а вторые — выполняют фоновые задачи, например, с помощью брокера сообщений RabbitMQ.
Паритет разработки/работы приложения. Для того чтобы обеспечить схожесть сред разработки, тестирования и продакшена, мы используем виртуализацию на основе Docker и специально подготовленные образы, содержащие одинаковые наборы и версии библиотек. Промышленные и тестовые среды отличаются лишь степенью масштабирования, на основе технологий K8S и Swarm.
Журналирование. Фактор утверждает, что приложение должно просто писать в STDOUT и STDERR, а среда должна отвечать за маршрутизацию этих сообщений в хранилище. Технология PHP-FPM позволяет производить вывод логов в STDOUT, что крайне полезно при работе с Docker-контейнерами. Для организации процесса логирования на уровне приложения мы используем сторонние внешние библиотеки, например Monolog или компоненты фреймворков.
Задачи администрирования. Реализовать сценарии администрирования приложения можно с помощью внешних библиотек, например Symfony Console. Большинство современных фреймворков имеют встроенные средства для организации запуска консольных команд для служебных целей и миграций. Например, в Yii Framework есть понятие консольного приложения и команды.
Chulakov Dev
💩2