sieci komputerowe, cisco, webmastering, php, css, xhtml, javascript, google, linux, windows server

Referencje w PHP

Kategorie: Webmastering PHP | 1 stycznia 2007 15:36 | Odsłon: 3744 | Komentarzy: 3 | Permalink

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.

Wpisy o podobnej tematyce

miron

22 stycznia 2007 14:57
Jeśli już się tak brać za optymalizacje, to warto również zoptymalizować pętle for :p
Po za tym w tym przykładzie, czy nie czytelniej będzie mimo wszystko coś takiego:

miron

22 stycznia 2007 14:58
komentarze są coś niedopracowane. W każdym razie zamiast foreach użyć:
$array = str_replace(2,0,$array);

daniel1302

25 lutego 2008 16:32
Ale przecież to jest przykład

Dodaj komentarz

Token

Statystyka
Ładowanie...