LazyCollections и PHP генераторы. Как применять на практике

Поделиться
HTML-код
  • Опубликовано: 29 сен 2024
  • Этот ролик посвящен PHP генераторам и LazyCollection. На примере посмотрим как генераторы могут оптимизировать работу памяти. Уделим внимание где используются генераторы в laravel, как нам их удобно использовать и когда.
    #LazyCollections#PHP#laravel#cutcode
    ---------------------------------------------------------------------------------
    🚀📹👨‍🏫 Как насчет прокачки своих навыков с помощью наших обучающих видеокурсов по web-разработке? Переходи на мой сайт 👇
    learn.cutcode....
    ❗️❗️❗️Присоединяйся к нашему комьюнити в телеграм - там и советом помогут и много интересного - goo.su/dsGP7PI
    ---------------------------------------------------------------------------------
    Всех поклонников laravel я приветствую на канале CutCode! Сегодня мы поговорим про PHP генераторы. Про это страшное слово vield и снова реализуем пример, который делают все и каждый в обучающих роликах и статьях. С огромным массивом, который сформирован функцией Range. Но друзья я вас обманываю и на самом деле мы этим заниматься не будем. Есть тысячи уже роликов о генераторах и их чудесном влиянии на память. Все они в рамках примера с массивом, построенным на функции Range. То же самое и про статьи, и про саму документацию. И все вы уже много раз это видели. А кто не видел рекомендую посмотреть или почитать. Но думаю в итоге после изучения вы останетесь довольны - все понял. Но где применять, когда применять все еще знать не будете. И спустя пару часов вовсе о них забудете. Поэтому мы чуток их суть обсудим, буквально парой предложений, но поговорим о конкретном применении. Где они используются в laravel, как нам их удобно использовать и когда. Ну что ж, погнали!
    Друзья проблемка. Нам скажем нужно повзаимодействовать с моделями и на их основе что-то посчитать к примеру. И нужны именно модели с кастами и прочим. У нас есть сущность - мы забираем все записи - в данном случае там 10к записей. Сам процесс мы делаем где-нибудь в консольной команде по расписанию и что-то в какой-то сущности высчитывая. В итоге такой запрос у нас на выходе сформируют коллекцию из десяти тысяч моделей. Обратите внимание сколько памяти нам под это потребовалось - аж 30 мегабайт. А здесь только 10к записей. Если говорить о SQL запросах и query builder, то нам на помощь может прийти метод cursor. Давайте им воспользуемся вместо All, а далее углубимся в сам метод. И здесь мы увидим что работает он как раз на генератора вот наш любимый vield. А помогает ему не просто коллекция а Lazy коллекция.
    ---------------------------------------------------------------------------------
    📹 делитесь этим видео с друзьями:
    • LazyCollections и PHP ...
    🔔 подпишитесь на RUclips-канал: www.youtube.co...
    📼 Курс по Laravel с нуля:
    • Курс по Laravel 8 обуч...
    НАЗВАНИЕНАЗВАНИЕНАЗВАНИЕ
    ---------------------------------------------------------------------------------
    🔗 наш сайт: cutcode.dev/?u...
    📱 Наш telegram-канал: t.me/laravel_c...

Комментарии • 18

  • @voxtens
    @voxtens 11 месяцев назад +7

    по идее после цикла while нужно добавить fclose($handle);

  • @irivka8344
    @irivka8344 9 месяцев назад

    А если нужно например вернуть модель виз рилейшн? Вроде бы курсор так не может, так какой вариант решает такой кейс?

  • @sufir
    @sufir 11 месяцев назад +3

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

    • @borisn879
      @borisn879 11 месяцев назад

      Не знаю. В некоторых фреймворках есть подход с batch - указать, сколько дергать элементов за 1 раз. Например, вытаскивать по 100 клиентов. Тогда можно соблюсти баланс расхода памяти и обращений к БД.

    • @SergeyFedosovfso
      @SergeyFedosovfso 11 месяцев назад +2

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

    • @eb6006
      @eb6006 11 месяцев назад

      Интересный ты вопрос написал, тоже стало любопытно, как это конкретно работает

    • @borisn879
      @borisn879 11 месяцев назад

      @@SergeyFedosovfso Вы имеете в виду ORM Doctrine + PostgresQL? К СУБД можно через DAO, AR, ORM обращаться. Сама Доктрина умеет с любой СУБД $qb->getQuery()->toIterable().

    • @pnoper
      @pnoper 11 месяцев назад +12

      Нет. Наоборот, запрос будет только один.
      К примеру, в базе есть 1000 записей и надо по ним по всем пройтись.
      Вариант 1. Table::all() = 1 запрос к базе = получаем коллекцию с 1000 объектов моделей в памяти
      Вариант 2. Table::query()->lazy(200) = 5 запросов = коллекция из 200 объектов в памяти
      Вариант 3. Table::query()->cursor() = 1 запрос = lazy-коллекция с 1 объектом в памяти
      При работе через курсор из базы одним запросом вытаскиваются все данные, но не создаются объекты моделей. Сама модель создаётся только в момент, когда она запрашивается при проходе через коллекцию.
      С курсорами есть пара минусов:
      1. нет возможности подтянуть одним запросом все связи для моделей. И вот тут уже будет куча запросов к базе, если будут обращения к связям.
      2. если надо обработать очень много записей из базы. Т.к. одним запросом вытаскиваются все данные, то они так же могут не уместиться в памяти.
      Получается, что вариант 2 (chunk или lazy) - золотая середина. И связи подтянуть можно и памяти можно сэкономить по сравнению с первым вариантом. А так всё очень зависит от конкретной ситуации.

  • @rustamergashev7278
    @rustamergashev7278 11 месяцев назад

    👍

  • @ЯковЛазоренко
    @ЯковЛазоренко 9 месяцев назад +1

    Слово yield правильно произноситься как "йелд"

  • @eb6006
    @eb6006 11 месяцев назад +1

    Ах автор как же ты молотишь функциями и замыканиями! Обалдеть. Как заведенный.

    • @CutCodeRu
      @CutCodeRu  10 месяцев назад

      тренировки