Referencje w PHP
Najczęściej, myśląc o funkcjach mamy na myśli "zwykłe" funkcje wg. schematu:
function funkcja($argument1, $argument2) {
/*
* Cialo funkcji
*/
return $zwracana_wartosc
}
$zmienna=funkcja($a1,$a1);
Do większości funkcji schemat ten jest wystarczający, jednakże w przypadku, gdy funkcja musi przetworzyć duża ilość danych, wydajniej (czasowo i pamięciowo) jest przekazać do niej referencję do argumentu, bowiem w powyższym schemacie, gdy wywołujemy tą funkcję przekazując jej jakieś zmienne są one powielane (w pamięci tworzone są ich kopie).
Ogólnie rzecz biorąc przekazywanie argumentów przez referencję wygląda tak:
function funkcja(&$argument) { // zwroc uwage na & przed argumentem
/*
* Cialo funkcji
* (z racji, ze funkcja operuje poprzez referencje
* do zmiennej nie trzeba stosowac return)
*/
}
funkcja($zmienna);
Jest to dość ogólny schemat, w celu "zobaczenia" tego w praktyce proponuję przykład:
functioncode przypiszdwa(&$arg) {
$arg="dwa";
}
$arg="jeden";
przypiszdwa($arg);
print $arg;
Powyższy kod spowoduje wypisanie słowa "dwa". Jak widać funkcja nie zwraca wartości poprzez return, a jedynie wykonuje określone akcje, wykorzystując przekazane referencje do zmiennych.
Na powyższym przykładzie nie zauważymy może znaczących różnic w szybkości działania tego skryptu, ale wyobraźmy sobie funkcję która np. zamienia określone znaki w tekście, do której przekazujemy bardzo długi tekst - dzięki przekazaniu referencji do funkcji nie ma potrzeby powielania tego tekstu w pamięci.
Istotną sprawą jest to, że w przypadku gdy funkcja jako argument pobiera referencję, nie wolno nam podać "gołej" wartości, w naszym przykładzie nie wolno napisać np. przypiszdwa("jeden"), ponieważ zwróci to błąd.
Drugim ciekawym aspektem mechanizmu referencji w PHP jest to, że funkcja może zwracać referencję do zmiennej. Wygląda to tak:
function &funkcja($argument) {
/*
* Cialo funkcji
*/
return $zwracana_zmienna; // a konkretniej to referencja do niej
}
$zmienna=funkcja($a1);
Podobnie jak w przypadku przekazywania argumentów przez referencję, tak i tutaj (zakładając, że funkcja generuje bardzo duże ilości danych) możemy uzyskać wzrost wydajności, bowiem i tutaj zwracana przez funkcję wartość nie jest powielana.
Ciekawym zastosowaniem referencji, acz rzadko opisywanym jest użycie ich w pętli foreach. Rozwiązanie to pozawala nam na łatwe i czytelne operowanie na elementach tablicy. Teoretycznie wygląda to tak:
foreach($array as $key => &$value) {
/*
* Cialo petli, wszystkie operacje, ktore wykonamy na zmiennej $value
* spowoduja zmiany tego konkretnego elementu tablicy
*/
}
Rozwiązanie z referencjami w pętli foreach pozwala nam przede wszystkim na bardzo łatwe manipulowanie elementami tablic asocjalnych.
Teraz pokaże jak bardzo referencję upraszczają składnię i sprawiają, że zapis jest czytelniejszy. Rozwiązanie z użyciem zwykłej pętli for zostanie zastąpione przez pętlę foreach z użyciem referencji. Przykładowy kod zamiany wszytkich elementów w tablicy, które są równe dwa na zero przy użyciu for:
$array=array(1,2,1,4,2,3,5,2,4,3,2,7,2,9);
print_r($array);
print "<br/>";
for($i=0;$i<sizeof($array);$i ) {
if($array[$i]==2) {
$array[$i]=0;
}
}
print_r($array);
Natomiast przy użyciu pętli foreach z referencjami wygląda to tak:
$array=array(1,2,1,4,2,3,5,2,4,3,2,7,2,9);
print_r($array);
print "<br/>";
foreach($array as &$element) {
if($element==2) {
$element=0;
}
}
print_r($array);
Różnica subtelna, ale dostrzegalna. Prawdziwe korzyści stylistyczne stosowania pętli foreach z referencjami można dostrzec na bardziej rozbudowanych kodach.
Subskrybuj kanał RSS bloga
miron
Po za tym w tym przykładzie, czy nie czytelniej będzie mimo wszystko coś takiego: