Despre metoda chunck() in Laravel

iNoob | Stefanescu Mihai | 2020-10-11

Hai sa ne imaginam urmatoarea situatie: Avem un tabel dintr-o baza de date cu peste 10 000 de randurisi trebuie sa facem un update unei singure coloane. Si in mod evident trebuie sa facem asta in PHP, nu putem pur si simplu rula un query. Deci, facand asta putem intampina urmatoarele probleme...ori codul nostru va dura o eternitate si jumatate pana cand va rula, ori vom primi eroare de max execution time (adica a durat mult prea mult).

Spre bucuria noastra, Laravel a venit cu o solutie interesanta pentru aceasta problema.

Hai sa luam un exemplu concret:

$users = User::all();
foreach ($users as $user) {
  $o_valoare = ($user->un_camp > 0) ? 1 : 0;
  $user->update(['un_oarecare_camp' => $o_valoare]);
}

Bineinteles, daca avem un tabel cu 100 de randuri, sau 500, sau chiar 1000...nu avem probleme.Dar, ce se intampla cand avem 10000 de randuri? Sau poate chair 100000? In acest caz deja nu se mai pune problema de durata, ba chiar am putea ramane fara memorie (presupunand ca stocam aceste randuri intr-o avriabila).

Aici ne sare in ajutor laravel, venind cu o functie numita chunk() ce imparte datele in selecturi separate, cum face si pagination().

Hai sa vedem un exemplu:

User::chunk(100, function ($users) {
  foreach ($users as $user) {
    $o_valoare = ($user->un_camp > 0) ? 1 : 0;
    $user->update(['un_oarecare_camp' => $o_valoare]);
  }
});

Ce face de fapt aceasta functie? Ruleaza un loop ce selecteaza de fiecare data cand este rulata cate 100 de randuri, dupa care ruleaza update-ul din foreach. In acest mod nu mai avem problema de mai sus pentru ca lucram numai cu cate 100 de randuri, nu cu toate randurile din tabel.

Vreau sa va avertizez sa aveti grija la filtrarea rezultatelor:

User::where('status', 0)->chunk(100, function ($users) {
  foreach ($users as $user) {
    $user->update(['status' => 1]);
  }
});

Tehnic vorbind, chestia asta va functiona si nu va va data nici-o eroare, dar problema ar putea fi ca filtrezi utilizatorii cu status 0, si le schimbi statusul, iar la urmatoare rulare a lui chunk() datelor vor fi deja schimbate, ceea ce va avea efectul ca la sfarsit numai jumatate din date vor fi modificate. Ce va sfatuiesc eu? Sa nu updata-ti aceaqlsi camp dupa care faceti filtrarea.


Imi place ce faci aici
Daca iti place ce fac aici imi poti cumpara o cafea Buy Me a Coffee at ko-fi.com

Stefanescu Mihai
Programator de ~8 ani, am lucrat la proiecte din mai multe industrstrii, de la eCommerce la telecomunicatii la automatizari. In acest timp am folosi diferite tehnologii, de la PHP, MySQL, PostgreSql, RabbitMq, Redis, Memcached si altele.
       

Get in touch
Pentru nelamuriri, dubii, comentarii si chestii de pe suflet ne putem auzi pe Discord, Reddit sau poti deschide o discutie noua pe forum.

Posteaza un comentariu

Comentarii

Inca nu au fost postate comentarii, fii primul care posteaza un comentariu!

Club-ul este dedicat membrilor si ofera access la mai multe zone ale website-ului.

🗝ïļ Login 🌟 Register

🔖 Bookmarks ⊞
âœĻ Pentru a sustine aceasta comunitate am sa te rog sa te autentifici sau sa te inregistrezi!

🌊ïļ Discord ⊞

Folosim cookie-uri pentru a oferi functionalitatile critice ale aplicatiei Invata-Programare. Folosim cookie-uri si pentru a analiza traficul, pentru care e nevoie de consimtamantul dvs. explicit.

⮆ïļ