OneCode
1.4K subscribers
628 photos
59 videos
3 files
524 links
Full Stack на PHP, Laravel и всё, что с этим связано.
YouTube: https://www.youtube.com/@onecode_blog
Download Telegram
Совет дня от дядюшки Макса

При использовании транзакций и блокировок в работе с базой данных старайся получать записи в одинаковом порядке для избежания взаимной блокировки (Deadlock).

Например, мы разрабатываем кошелек, где у пользователей есть финансовые счета (accounts). Пользователь может совершать разные операции со счётом: пополнять (deposit), переводить другому пользователю (transfer) или выводить средства со счёта (payout).

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

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

Пример ошибки: в одной транзакции мы сначала получили и заблокировали счёт (account), а потом получили и заблокировали пополнение (deposit). В другой транзакции мы сделали тоже самое, но наоборот - сначала заблокировали deposit, а потом account. Если обе транзакции запустятся одновременно, то одна сначала заблокирует счёт, а вторая пополнение, затем первая попытается заблокировать пополнение, но оно уже заблокировано второй транзакцией, которая в этот момент пытается заблокировать счёт, который в свою очередь уже заблокирован первой транзакцией.

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

Документация на примере PostgreSQL:
https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-DEADLOCKS

Ставь лайк, если полезно 👍 делись своим опытом в комментариях!

#db #deadlock #tip
👍14
В Laravel при использовании модели можно передать массив идентификаторов (ID) в метод
find
, чтобы выполнить запрос
where in
к базе данных.

#laravel #tip
👍7
Спасибо за лайки! Вот так бы всегда 😃

Как обещал прикладываю простой пример использования нашей функции fingerprint, которая возвращает подпись массива.

Смысл примера:
- У нас есть посты в блоге (как обычно =))
- Приходит запрос за списком постов (GET api/posts)
- В запросе могут быть параметры (категория, поиск, страница пагинации)
- Мы хотим кешировать результаты предыдущих запросов, чтобы не тревожить базу по пустякам
- Но нам нужен ключ для кеша, который зависит от параметров в запросе (категория, страница и поиск)
- Поэтому мы берём массив параметров из запроса (по сути - фильтров) и формируем из них подпись при помощи нашей функции
- Как вы помните, fingerprint сначала сортирует массив по ключам, поэтому результат всегда будет одинаковый НЕ зависимо от порядка элементов в массиве.

Поэтому наш «отпечаток пальца» помогает нам сформировать ключ для кэша ($key) именно под этот запрос.

Надеюсь пример понятен. Если что обсуждаем вопросы в комментариях. Лайк! 🤝

#tip
👍13
Хай, гайз! Делюсь с вами еще одной фишкой из старого проекта.


Что имеем
1. Обычное html-поле
select[type="country_id"]
со списком стран.
2. Проект на Laravel + Livewire-компонент с формой для пользователя.
3. Шаблон на старом добром
Bootstrap 4 + jQuery
(купленый шаблон).

Задача
1. Определять страну пользователя по IP-адресу.
2. Автоматически выбирать эту страну в
select
в нашем компоненте.
3. Если страна у пользователя уже выбрана ранее, то ничего делать не нужно.

Решение
1. При загрузке страницы делаем GET-запрос на сервис
ipinfo.io
для определения страны пользователя по его IP (бесплатный тариф до 50к запросов в месяц).
2. Если удалось получить страну, то устанавливаем её код (например RU) в качестве значения для соответсвующего свойства нашего Livewire-компонента (благо в базе ID стран - это их ISO-коды)
3. Магия Livewire автоматически выбирает эту страну в селекте благодаря реативности через
wire:model="country_id"
.

Профит! И лайк 🤗

#laravel #livewire #tip
👍10
Адаптивное видео (пропорции)

Продолжаем тему вёрстки. Иногда нам нужно сделать адаптивное видео (или другой элемент с соблюдением пропорции - отношение ширины к высоте).

У этой задачи есть классическое решение - использовать абсолютное позиционирование и верхний внутренний отступ (например padding-top: 56.25%).

Однако не многие знают (мы теперь знаем!), что есть CSS-свойство aspect-ratio, которое как раз решает эту задачу очень просто 👇

https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio

Кстати, Tailwind конечно имеет удобные классы для работы с этим свойством, например aspect-video - и адаптивное видео 16/9 готово! Так просто 😃 На сайте можно подвигать видео за ползунок справа от него и убедиться, что оно адаптивное 👇

https://tailwindcss.com/docs/aspect-ratio

Поддержка браузерами в принципе НЕ плохая - 86%. Все версии браузеров, выпущеные с 2021 года поддерживают:

https://caniuse.com/?search=aspect-ratio

Будем иметь ввиду!

#html #css #tailwind #tip
👍10
Хелперы для вывода даты и времени

Часто на проекте нужно выводить дату или время в определённом формате.

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

Если в будущем придёт задача изменить формат, то придётся:
- Искать все места в проекте.
- Менять вручную и тестировать.
- Надеяться, что ничего не пропустил.

Поэтому я сразу помещаю логику форматирования даты/времени в функции-хелперы (на скрине).

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

Пример использования:

{{ __datetime($order->created_at) }}
{{ __date($order->created_at) }}
{{ __time($order->created_at) }}


Планирую создать отдельный telegram-канал с такими полезными советами, примерами моего кода, короткими практическими видео и лайфхаками из моего личного опыта.

Лайк?

#laravel #tip #date #time #helpers
👍34