Scris pe

Despre Lambda si Closure in PHP

lambda

Lambda-urile si closure-urile sunt concepte realtiv noi in PHP, au ajuns in limbaj de la versiunea 5.3. Ambele iti dau functionalitati noi si abilitatea de a refactoriza cod vechi pentru a-l face mai curat si mai intuitiv. Totusi, cred ca multi developeri nu au cunostinte despre aceste concepte si nu prea inteleg ce fac ele cu adevarat.

In aceasta postare voi explica putin despre functiile lambda si despre closures, voi da cateva exemple concrete ca sa va arat functionalitatea si puterea lor in PHP-ul modern.

Ce este un Lambda?

Lambda este defapt o functie anonima care poate sa fie asignata unei variabile sau sa fie pasata altei functii ca si un argument. Daca esti familiar cu alte limbaje de programare gen Javascript sau Ruby ar trebui deja sa fi familiar cu functiile anonime.

Functiile anonime

O functie anonima este pur si simplu o functie fara nume. De exemplu, pentru a creea o functie normala, scrii codul asa:

// Functie normala
function greeting () {
  return "Hello world";
}

OFFTOPIC – George mi-a atras atentia ca sa nu mai scriu cod in romana cand dau exemple :)). O sa incerc sa scriu doar comentariile in romana ca sa intelegeti.

Cu o astfel de functie o putem apela asa:

echo greeting();
// Printeaza "Hello world"

O functie anonima am zis ca nu are nume, deci o putem defini asa:

// Functie anonima
function () {
  return "Hello world";
}

Folosind lambda-urile

Pentru ca o astfel de functie nu are nume, nu o putem apela ca pe o functie normala. In schimb, trebuie sa o atribuim unei variabile sau sa o pasam altei functii ca si un argument.

// Functie anonima
// atribuita unei variabile
$greeting = function () {
  return "Hello world";
}

// Apelam functia
echo $greeting();
// Printeaza "Hello world"

Deci ca sa folosim o functie lamba, o asignam unei variabile si apelam acea variabila ca o functie.

De asemenea putem sa o atribuim cum am zis unei alte functii:

// Pasam o lambda unei alte functii
function shout ($message){
  echo $message();
}

// Apeleaza functia
shout(function(){
  return "Hello world";
});

De ce ai vrea sa folosesti o lambda?

Functiile lambda sunt folositoare pentru ca sunt sa zic asa functii de unica folosinta (intr-un fel). De multe ori ai nevoie de o functie sa faci o treaba, dar nu ar avea sens sa o definesti in scopul global sau chiar sa o faci disponibila in codul mare. In schimb sa ai o functie normala care o folosesti doar odata si dupa sta nefolosita, ai putea sa folosesti lambda.

Desigur, si in versiunile mai vechi aveam un artificiu prin care puteam face o imitatie de lambda.

// Folosim create_function
$greeting = create_function('', 'echo "Hello World!";');

// Apelam functia
$greeting();

Ce este un Closure?

Un closure este practic tot un lambda, dar care poate sa apeleze variabile si din afara scopului ei insasi.

// Avem un user
$user = "Philip";

// Facem un closure
$greeting = function() use ($user) {
  echo "Hello $user";
};

// Salutam userul
$greeting(); // Printam "Hello Philip"

Cum se poate vedea mai sus, o Closure poate apela variabila $user chiar daca este definita in afara functiei, pentru ca a fost definita in clauza use a definitiei.

Daca ar fii sa modificam variabila $user in closure, nu ar afecta variabila originala. Ca sa updatam variabila originala, putem sa ii putem un & in fata si asta inseamna ca folosim o referinta la variabila originala:

// Setam counterul
$i = 0;
// Marim counterul in scopul aceste functii
$closure = function () use ($i){ $i++; };
// Rulam functia
$closure();
// Counterul original nu s-a schimbat
echo $i; // Printeaza 0

// Resetam counterul
$i = 0;
// Marim counterul in scopul aceste functii
// dar il pasam ca si referinta
$closure = function () use (&$i){ $i++; };
// Rulam functia
$closure();
// Counterul original s-a schimbat
echo $i; // Printeaza 1

Closure-urile sunt de asemenea folositoare cand folosim functii PHP care accepta un callback cum ar fi array_map, array_filter, array_reduce sau array_walk.

Functia array_walk accepta un array si il trece printr-o functie callback.

// Un array cu nume
$users = array("John", "Jane", "Sally", "Philip");

// Pasam array-ul la array_walk
array_walk($users, function ($name) {
  echo "Hello $name
";
});
// Printeaza
// -> Hello John
// -> Hello Jane
// -> ..

Din nou, putem modifica date din afara closure-ului.

// Un multiplicator
$multiplier = 3;

// Array de numere
$numbers = array(1,2,3,4);

// Folosim array_walk ca sa iteram
// prin lista si sa multiplicam.
array_walk($numbers, function($number) use($multiplier){
  echo $number * $multiplier;
});

In exemplul de mai sus, nu ar face sens ca sa faci o functie doar pentru a multiplica 2 numere. Daca ai face cate o functie pentru un lucru ca acesta, poate in viitor cand te vei uita peste cod te vei gandi de ce te-ai chinuit sa faci o functia accesibila global daca e folosita intr-un singur loc. Folosind un closure ca un callback, putem folosi functia odata si sa uitam de ea.

Folosinta in lumea reala

Deci am invatat ca functiile Lambda si Closure sunt functii anonime care pot fi folosite si apoi uitate si sunt foarte folositoare cand folosim un callback.

Un exemplu popular este folosirea unor astfel de functii in routarea requesturilor in frameworkurile moderne. In Laravel de exemplu, definim o ruta astfel:

Route::get('user/(:any)', function($name){
  return "Hello " . $name;
});

Codul de mai sus doar creeaza un match pentru un URL de genul /user/phillip si returneaza salutul.

This is a very basic example, but it highlights how a Closure can be utilised in a very useful situation.

Este un exemplu foarte simplu dar arata cum un closure poate fi utilizat intr-o situatie folositoare.

Concluzie

Sper ca am explicat cat pot eu de bine ce sunt Lambda si Closure.

Lambdas si Closures par sa fie termeni foarte complicati pentru cei care abia invata programare. Totusi, nu e chiar atat de complicat. Ambele sunt doar functii anonime care sunt folositoare pentru lucruri care le faci odata si nu are rost sa definesti o functie normala.

Lambdas si Closures sunt destul de noi in PHP si nu se aseamana neaparat cu alte limbaje 100%. Daca esti familiar cu Javascript, vei vedea ca se folosesc super des. Mai mult, vei gasi foarte multe exemple in jQuery. Odata ce vei recunoaste sablonul, o sa vezi ca face codul mult mai citibil pentru ca vezi din prima ce face o functie si nu mai stai sa cauti o simpla functie mica. Dupa exercitiu vei incepe sa indragesti lambda-urile si closure-urile!

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

Acest site folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.

Copyright © 2024 toate drepturile
nu sunt
rezervate. Faceti ce vreti, e o tara libera.
Cred ca nu mai are rost sa zic, dar tema e facuta de mine cu Tailwind CSS. Gasesti codul sursa aici.
Inca folosesc WordpPess 🧡. Tema e insa custom Laravel 😎.