Обновить
64K+

PHP *

Скриптовый язык общего назначения

73,53
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Снижение нагрузки на сервер с помощью WAF: реальный кейс WordPress/WooCommerce

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели7.4K

Реальный кейс снижения нагрузки WordPress/WooCommerce с помощью WAF

На WordPress/WooCommerce-сайте на shared-хостинге регулярно возникали серьёзные превышения нагрузки на веб-сервер и MySQL. Штатный антибот-фильтр хостинга проблему не решил. В этом кейсе я показываю, что изменилось после подключения внешнего WAF с индивидуальной фильтрацией трафика: какие запросы создавали лишнюю нагрузку, как отсеивались парсеры, сканеры и поведенческие боты и что происходило с поисковыми роботами.

По данным Beget, после замены фильтра суточная нагрузка сайта снизилась примерно в 45 раз, базы данных — примерно в 39 раз. При этом WordPress, WooCommerce, плагины, код и структура БД не изменялись. В статье — реальные графики, данные Яндекс Метрики, статистика WAF и разбор случаев, когда WAF, наоборот, не поможет решить проблему высокой нагрузки.

Читать далее

Новости

Бесплатный плагин для входа через VK ID на WordPress: как закрыли потребность, когда готовых решений не нашлось

Время на прочтение2 мин
Охват и читатели6.7K

Начал я делать очередной сайт на Wordpress и решил упростить регистрацию пользователям. По этому пошел по схеме вход через другие сервисы. Как стало нынче модно‑сковородно использовать авторизацию через ВК. Ее то я и решил прикрутить. Делал уже это раньше но вот сегодня столкнулся с проблемой.

И есть решение

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

Уровень сложностиСредний
Время на прочтение19 мин
Охват и читатели6.2K

Документация устаревает быстрее, чем код успевает писаться? Рассказываем, как мы построили конвейер из Python-скриптов и нейросетей, который сам находит изменения в PHP-контроллерах и обновляет документацию API Invapi.

Читать далее

Четыре CMS, один интерфейс публикации: WordPress, 1С-Битрикс, InSales и Joomla

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели5.1K

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

Оказалось наоборот. Четыре CMS — четыре разных мира, и в каждом свой способ соврать вам об успехе.

Joomla возвращает 400, когда статья уже создана: плагин «Умный поиск» падает после записи в базу. Повторили запрос — получили дубль. InSales требует published_at даже у черновика, потому что черновиков там просто нет. А у 1С-Битрикс метода для создания статьи через API не существует вовсе — официальная документация прямо говорит про read-only режим.

Внутри: как выглядит общий интерфейс на четыре системы, почему CIBlockElement::Add() возвращает ошибку при успешно созданном элементе, зачем понадобилась двойная буферизация вывода и прямой SQL в обход автотранслитерации.

Читать далее!

Матрешка из Base64 и ROT13: разбираем вредоносный .sh, который пришел за FreePBX

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели5.6K

Мне в руки попался файл с расширением .sh и, конечно же, его пришлось изучить. Открываю файл — первая половина более-менее читаемая, а дальше начинается классика: Base64, ROT13 и еще немного Base64. Вроде ничего страшного. Декодируем, смотрим результат, радуемся жизни. Но не тут-то было. Автор скрипта решил сделать небольшой квест в стиле: А что если положить один скрипт внутрь другого скрипта, а потом еще один внутрь него?

Читать далее

Когда Laravel Validator становится узким местом при импорте 50 000 строк

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели6.3K

PHP 7.4 / Laravel 8 / PostgreSQL 13

Проблема: импорт 50 тысяч строк занимал около 45 секунд.
Первое подозрение: база данных, INSERT, UPSERT, индексы, размер batch и количество запросов.
Реальность: бОльшая часть времени уходит на валидацию.

Мы начали разбираться, почему проверка нескольких десятков обычных полей на большом массиве данных оказалась значительно дороже самой записи в PostgreSQL. В итоге удалось сократить время валидации с 42,5 секунды до 0,65 секунды, а длительность всего job — примерно с 45 до 4 секунд.

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

Читать далее

Как на ровном месте сэкономить 1000+ ядер, или Куда на самом деле уходили 80% CPU

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели15K

Всем привет, меня зовут Миша, и я бэкенд‑разработчик в платформе Яндекс Еды. Я уже рассказывал, как мы анализировали наш PHP‑монолит и вынесли из него процессинг заказов, и с тех пор роль этого легаси заметно уменьшилась. Заодно туда стали писать гораздо меньше нового кода, релизы стали реже, и он спокойненько себе работал, не привлекая лишнего внимания. 

Так оно бы и продолжалось, но тут случилась повышенная нагрузка и необходимость зарезервировать побольше мощностей для беспроблемной обработки повышенного спроса. Монолит справился на отлично, но самое интересное случилось потом: возвращая выделение ресурсов к прежним значениям, я случайно обратил внимание, что RPS в пиковые вечерние часы как‑то подозрительно совпадает с количеством ядер CPU, выделенных на весь монолит.

Количество выделенных ядер, конечно, ещё ничего не означает, поэтому я полез смотреть реальное потребление процессорного времени, сложив CPU usage по всем подам. С помощью нехитрой арифметики я обнаружил, что 100% загрузки одного ядра приходятся на 2,5 RPS. Какое‑то время я находился в состоянии глубокого изумления, после чего решил, что это никуда не годится, и отправился в увлекательное приключение на 20 минут. 

Немного спойлеров: дело оказалось далеко не только в PHP. 

Читать далее

Пользователь придумал пароль из 100 символов. От 28 из них ваша проверка не зависит

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели14K

Тикет пришёл от разработчика, который писал импорт учёток из старой системы. Формулировка была такая: «кажется, у нас ломается верификация, но ломается она в плюс — подходят пароли, которых не было».

Ломалось не у него. Так работает bcrypt, и работает уже двадцать семь лет.

Читать далее

Как записать ЛИД в Битрикс24 (заявка с сайта и подобное) через входящий вебхук на PHP

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели6.7K

Для простой серверной интеграции с Битрикс24 далеко не всегда требуется полноценная OAuth 2.0-авторизация.

Если задача — из внешнего сервиса создать контакт, проверить существующего клиента и записать лид в CRM, это можно сделать через входящий вебхук Битрикс24 и обычный PHP.

Я использую такую схему в интеграциях, когда внешняя система отправляет данные на наш сервер, а сервер уже решает, что именно нужно создать в CRM.

Читать далее

Пакуем PHP в PHP, чтобы запаковать в JS, чтобы обернуть в HTML

Время на прочтение3 мин
Охват и читатели7.1K

Прочтя недавний перевод про запаковку БД в exe, решил рассказать об идеи, которую реализовал лет 6 назад в своем домашнем проекте. Сам проект недоделал, но речь в статье об архитектуре файлов и их запаковке.

Читать далее

Как я год загружал фото в Битрикс24 и собрал все грабли файлового API

Уровень сложностиСложный
Время на прочтение12 мин
Охват и читатели8.7K

Работа с файлами в REST API Битрикс24 — та задача, где документация заканчивается ровно там, где начинаются проблемы. Официальные примеры показывают, как загрузить один файл в одно поле. А дальше выясняется, что у crm.item.update и crm.deal.update разные несовместимые форматы, что вложенный base64 через http_build_query уходит в никуда, а сервер при этом честно отвечает «result».

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

Собрал всё в один разбор — шесть подходов с кодом и восемь граблей:

два формата файлового значения, которые нельзя смешивать, и почему при смешении затираются уже прикреплённые файлы;

тихий провал: HTTP 200, в ответе result, поле не обновилось;

useOriginalUfNames=Y, без которого UF_CRM_* молча игнорируются;

downloadUrl приходит с пустым auth= и без подстановки токена не скачивается, а при протухшем токене вместо файла отдаётся HTML-страница с кодом 200;

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

В конце — таблица «что брать под какую задачу» и чеклист граблей. Двадцать блоков кода, всё из боевых проектов.

Читать далее

Автогенерация типов показала, что проблема была не в типах

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели6.9K

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

Статья не про саму автогенерацию — с ней всё понятно, про неё и без меня написано достаточно. Мы внедрили генерацию типов из OpenAPI, и она вытащила наружу то, что с генерацией напрямую не связано: кто не хочет писать комментарии, почему у одной сущности два имени и почему у нас падал dev. По сути — про команду, эго и умение договариваться.

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

Читать далее

Публичный API у генератора QR-кодов: без ключей, лимитер на файлах и грабля Apache

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели5.6K

У моего генератора QR-кодов листами появился публичный API: POST с JSON, в ответ сразу готовый PDF, до 1500 кодов за запрос, без регистрации и ключей. Внутри рассказ, почему я не завел ни ключи, ни Redis, как работает лимитер на файлах с flock и fail-open, и на какой грабле Apache POST молча превращался в GET.

Читать далее

Ближайшие события

Пишем свой PHP-экстеншен на Rust

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели6.2K

Когда речь заходит о разработке PHP-расширений, многие сразу представляют C, Zend API и сложную систему сборки. Но сегодня есть более удобный путь. С помощью ext-php-rs можно создавать расширения на Rust, используя привычные инструменты Cargo и практически не сталкиваясь с низкоуровневыми деталями.

В этой статье мы с нуля напишем собственный PHP-экстеншен, подключим его к PHP, разберём, как ext-php-rs связывает Rust с Zend API, а затем посмотрим, в каких задачах такой подход действительно даёт прирост производительности, а где этого ждать не стоит.

Читать далее

Автоматическая установка Wordpress на чистый сервер Ubuntu или Debian

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели5.3K

Ставить WordPress руками — занятие на полтора часа: веб‑сервер, PHP с десятком расширений, база данных, конфиг Nginx, права на файлы, лимиты загрузки, сертификат. Я устал повторять этот ритуал и собрал скрипт, который делает всё сам и спрашивает только то, что действительно зависит от меня.

Итог, к которому мы придём: работающий сайт с настроенной админкой, ЧПУ‑ссылками, русской локализацией, при желании — с сертификатом Let’s Encrypt, phpMyAdmin и защитой от подбора паролей. Все доступы будут лежать в одном файле на сервере.

Читать далее

OAuth 2.0 в amoCRM REST API на PHP простым языком: получение, хранение и обновление токенов

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели5.6K

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

Основной вопрос возникает раньше:

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

1-2 года назад я реализовывал такую интеграцию на PHP. Токены хранили в MySQL, а работу с OAuth разбили на несколько отдельных файлов.

Сейчас решил восстановить общую архитектуру этой реализации.

Если убрать детали, OAuth-интеграция выглядит довольно просто:

Authorization Code → Access Token + Refresh Token → сохранение в БД → запросы к REST API → обновление токенов → повторное сохранение в БД.

Код авторизации берется в AmoCRM:

Читать далее

100% покрытия не поймали единственный баг, который был важен

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели7.2K

У виджета было 92 теста и 100% построчного покрытия. Потом я открыл его в маленьком окне терминала, и шапка таблицы уехала за верхнюю границу экрана.

Разбор трёх багов, которые нашлись при разработке пакета поверх экспериментального компонента symfony/tui: одного своего, который не поймало полное покрытие, и двух чужих — их исправления смержены в ядро Symfony. Плюс третий, найденный уже после того, как его починили без меня, — таб в ячейке ломал выравнивание всей таблицы.

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

Читать далее

Как сайт клиента захватил японский магазин дронов и как мы это исправили

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели7K

Суббота, клиент вернулся из отпуска, открыл свой сайт и написал мне: «сайт лежит, вижу только белый экран, что случилось?». Код ответа при этом 200, мониторинг зелёный, хостинг жив, база данных на месте.

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

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

А ещё честно расскажу, где мы сами ошиблись. Одна ошибка стоила ещё десяти часов спама в Google уже после того, как мы решили, что всё закончилось.

В конце — 5 способов за 5 минут проверить ваш собственный сайт.

Читать далее

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

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели4.9K

Привет, Хабр!

Меня зовут Михаил Емельянов, я ведущий разработчик в НЛМК ИТ. Команда, в которой я состою, занимается разработкой и поддержкой различных корпоративных информационных систем на базе Битрикс24.

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

- Юридические нюансы: обработка персональных данных по требованиям 152‑ФЗ и внутренних политик безопасности. Стороннему сервису не всегда можно передать всё, что нужно, а иногда это прямо запрещено.

- Стоимость: даже одно недельное мероприятие обходилось достаточно дорого.

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

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

Читать далее

Генератор QR‑кодов листами на PHP: детерминированное ядро и пять граблей по дороге

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели6.6K

Этой весной мне понадобился лист QR‑кодов с подписями: по коду на каждую позицию, чтобы скачать PDF, распечатать и разрезать. Онлайн‑генераторы делают коды по одному или просят подписку за пакет, так что я написал свой сервис на PHP 8.2. В посте про то, что интереснее разработчику: чистое детерминированное ядро с golden‑тестами байт‑в-байт, кириллические домены и punycode, кириллица, которую TCPDF молча теряет в SVG, артикулы в виде 4.6E+12 из Excel, “прозрачный” PNG с маджентовым фоном и самописный EAN-13 с оракулом в тестах.

Читать далее
1
23 ...