Ответы пользователя по тегу 1С-Битрикс
  • Как обработать запрос не получая ошибку по таймауту?

    @qbudha
    Чых-пыхдевелопер
    Вы правильно предположили, что нужен итератор. В PHP есть такая штука, как генератор, одна из разновидностей.
    Вот, если использовать его, то можно в принципе попробовать уложиться в лимит по памяти.
    На своих проектах для полного прохода по записям в БД использую, что-то типа такого:
    public function getEntitiesByBatch(int $limit): \Generator
        {
            $expr = $this->createQueryBuilder('s');
            $predicates = $expr->expr()->andX();
            $predicates->add($expr->expr()->isNotNull('s.field1'));
            $predicates->add($expr->expr()->isNotNull('s.field2'));
            $accountState = $expr->expr()->eq('a.field3', 'true');
    
            $qb = $this->createQueryBuilder('s')
                ->where($predicates)
                ->join('s.account', 'a')
                ->where($accountState)
            ;
    
            $batches = ceil($qb->select('count(s.id)')->getQuery()->getSingleScalarResult() / $limit);
    
            for ($batch = 1; $batch <= $batches; ++$batch) {
                yield $this->createQueryBuilder('s')
                    ->where($predicates)
                    ->join('s.account', 'a')
                    ->where($accountState)
                    ->setFirstResult($batch * $limit - $limit)
                    ->setMaxResults($limit)
                    ->getQuery()
                    ->toIterable() // тут можно возращать просто массив, но мне нужен итерируемый объект
                ;
            }
        }


    Upd 1 А сорян, у вас тут битрикс, может у него есть какие-то дефолтные способы хз. Но общий смысл генераторов от этого не сильно меняется:)

    Upd 2 И да, этот код работает в консольном скрипте.
    Ответ написан
    Комментировать