@@ -1840,6 +1840,46 @@ public function __call(string $name, array $args): mixed
18401840 /**
18411841 * @template T of Collection
18421842 *
1843+ * Iterate and call DB every N times, every time get full items but yield item one by one, stop when no more items.
1844+ * This method can ensure no long connection to DB. You only need one level foreach to get every item.
1845+ *
1846+ * @param int $length
1847+ * @param class-string<T>|null $class
1848+ * @param array $args
1849+ *
1850+ * @return Generator<Collection<T>>
1851+ */
1852+ public function iterateBatched (int $ length , ?string $ class = null , array $ args = []): \Generator
1853+ {
1854+ $ offset = 0 ;
1855+
1856+ while (true ) {
1857+ $ query = clone $ this ;
1858+ $ query ->offset ($ offset )->limit ($ length );
1859+
1860+ $ items = $ query ->all ($ class , $ args );
1861+
1862+ $ count = 0 ;
1863+
1864+ foreach ($ items as $ item ) {
1865+ $ count ++;
1866+ yield $ item ;
1867+ }
1868+
1869+ if ($ count === 0 || $ count < $ length ) {
1870+ break ;
1871+ }
1872+
1873+ $ offset += $ length ;
1874+ }
1875+ }
1876+
1877+ /**
1878+ * @template T of Collection
1879+ *
1880+ * Iterate and return chunks of items, every chunk will one time return full items.
1881+ * You need 2 level foreach to get every item.
1882+ *
18431883 * @param int $length
18441884 * @param class-string<T>|null $class
18451885 * @param array $args
@@ -1873,11 +1913,15 @@ public function iterateChunks(int $length, ?string $class = null, array $args =
18731913 /**
18741914 * @template T of Collection
18751915 *
1916+ * Iterate and call DB N times, every time get innter iterator and yield items one by one, stop when no more items.
1917+ * This method will not offset or paginated, it will always start from 0.
1918+ * You must change the item state in the loop to avoid infinite loop.
1919+ *
18761920 * @param int $length
18771921 * @param class-string<T>|null $class
18781922 * @param array $args
18791923 *
1880- * @return Generator<Collection<T> >
1924+ * @return Generator<T >
18811925 */
18821926 public function iterateWhile (int $ length , ?string $ class = null , array $ args = []): \Generator
18831927 {
@@ -1900,6 +1944,41 @@ public function iterateWhile(int $length, ?string $class = null, array $args = [
19001944 }
19011945 }
19021946
1947+ /**
1948+ * @template T of Collection
1949+ *
1950+ * Iterate and call DB N times, every time get full items and yield items one by one to prevent long connections,
1951+ * stop when no more items.
1952+ * This method will not offset or paginated, it will always start from 0.
1953+ * You must change the item state in the loop to avoid infinite loop.
1954+ *
1955+ * @param int $length
1956+ * @param class-string<T>|null $class
1957+ * @param array $args
1958+ *
1959+ * @return Generator<T>
1960+ */
1961+ public function iterateBatchWhile (int $ length , ?string $ class = null , array $ args = []): \Generator
1962+ {
1963+ $ query = clone $ this ;
1964+ $ query ->offset (0 )->limit ($ length );
1965+
1966+ while (true ) {
1967+ $ items = $ query ->all ($ class , $ args );
1968+
1969+ $ count = 0 ;
1970+
1971+ foreach ($ items as $ item ) {
1972+ $ count ++;
1973+ yield $ item ;
1974+ }
1975+
1976+ if ($ count === 0 || $ count < $ length ) {
1977+ break ;
1978+ }
1979+ }
1980+ }
1981+
19031982 /**
19041983 * @template T of Collection
19051984 *
0 commit comments