Mam trochę znajomości języka C ++ i wiem, że wskaźniki są tam często używane, ale zacząłem patrzeć na kod open source PHP i nigdy nie widzę kodu używającego referencji w metodach.
Zamiast tego kod zawsze używa wartości zwracanej zamiast przekazywać odwołanie do zmiennej do metody, która następnie zmienia wartość tej zmiennej i po prostu ją zwraca.
Czytałem, że używanie referencji zużywa mniej pamięci, więc dlaczego nie są używane w PHP?
return array($foo, $bar);
ilist($A, $B) = foobar();
Odpowiedzi:
Twoje twierdzenie, że referencje są rzadko używane, jest nieprawidłowe. Jak już wspomniano inni, istnieje mnóstwo natywnych funkcji, które korzystają z referencji, godnymi uwagi przykładami są funkcje sortowania tablic i
preg_match()
/preg_match_all()
. Jeśli używasz którejkolwiek z tych funkcji w kodzie, używasz również odwołań.Przechodząc dalej, odniesienia w PHP nie są wskaźnikami. Ponieważ pochodzisz ze środowiska C ++, rozumiem zamieszanie, ale odniesienia do PHP są zupełnie inną bestią, są aliasami do tablicy symboli . Wszelkie przyrosty wydajności, których można się spodziewać po referencjach w C ++, po prostu nie dotyczą referencji w PHP.
W rzeczywistości w większości scenariuszy przekazywanie przez wartość jest szybsze i wymaga mniej pamięci niż przekazywanie przez odniesienie. Zend Engine, rdzeń PHP, wykorzystuje mechanizm optymalizacji kopiowania przy zapisie , który nie tworzy kopii zmiennej, dopóki nie zostanie zmodyfikowana. Przekazywanie przez odwołanie zwykle przerywa wzorzec kopiowania przy zapisie i wymaga kopii, niezależnie od tego, czy zmodyfikujesz wartość, czy nie.
Nie bój się używać referencji w PHP, kiedy jest to konieczne, ale nie rób tego tylko jako próbę mikrooptymalizacji. Pamiętajcie, przedwczesna optymalizacja jest źródłem wszelkiego zła .
Dalsza lektura:
źródło
f($obj)
biorąc pod uwagęfunction f($x) { $x = new X; }
,$obj
odnosi się do innego obiektu niż przed wywołaniemf()
. Ponieważ jednak obiekty nie są przekazywane przez odwołanie, $ obj nie jest modyfikowany, jeśli miałbyś to zrobić za pomocą PHP. W ten sposób PHP robi to samo co Java.PHP już wykonuje operacje kopiowania przy zapisie, w których nie tworzy nowej wartości, dopóki czegoś nie zmienisz, więc nie ma dużo pamięci zaoszczędzonej przez użycie referencji. Może to nawet zepsuć niektóre rzeczy, które PHP robi wewnętrznie, aby zmniejszyć zużycie pamięci, a nawet pogorszyć sytuację.
Dodaj do tego fakt, że referencje sprawiają, że ogólnie rzecz biorąc jest to zbyt magiczne. Domyślną wartością, a więc tym, czego oczekuje większość ludzi, jest przekazywanie wartości; kiedy przechodzę
$i
do funkcji, ogromnie komplikuje to, że trzeba dbać o to, czy ta funkcja w tajemniczy sposób zmienia się$i
na coś zupełnie innego, a tym samym na wszelki wypadek tworzy kopie obronne. (Może już modyfikować,$i
jeśli wartość jest obiektem, ale moim zdaniem nie powinna.)Zasadniczo uważam, że przekazywanie przez odniesienie jest przydatne tylko w przypadku parametrów „wyjściowych”, czyli zmiennych, których oczekuję wrócić z funkcji niż piłkę, a la
preg_match
„ów&$matches
. Nawet w przypadku funkcji, które wyraźnie modyfikują przekazywany obiekt, na przykładsort
lubarray_pop
, co wydaje się nieco nieprzyjemne ... ale z tym utknęliśmy.źródło
PHP jest językiem zorientowanym na sieć.
Strony internetowe są wyświetlane szybko i powinny być lekkie.
Zwykle program PHP żyje ułamek sekundy i zużywa kilkaset kilobajtów pamięci.
Nie ma sensu takie optymalizacje.
źródło
Niektóre powody w locie:
źródło
Myślę, że to tylko wybór twórców, nie mający nic wspólnego z językiem. Dużo kodu PHP (wbudowanego i nie) używa referencji. Spójrz na funkcje tablic w PHP, wiele z nich używa referencji.
preg_match
używa referencji.Myślę, że jednym z powodów, dla których programiści nie używają referencji, jest to, że może to być mylące. Wywołujesz funkcję, a jedna ze zmiennych może (ale nie musi) zostać zaktualizowana, ponieważ była referencją. Podczas debugowania może nie być jasne, dlaczego wartość
$x
jsut zmieniła się magicznie.źródło
Podstawowym problemem związanym z tym pytaniem jest założenie, że jest to również powszechne w C ++. To nie jest Nie lubimy parametrów wyjściowych i używamy ich w jak najmniejszym stopniu - są one naprawdę powszechne w interfejsach API w stylu C.
źródło
Znam wiele funkcji php, które to robią. Spójrz na
preg_match()
przykład.$matches
zostanie przekazany przez odniesienieJeśli chcesz napisać dla siebie funkcję, która pobiera argumenty przez odwołanie, użyj następującej składni
$ a i $ b są przekazywane przez odniesienie $ c jest przekazywane przez wartość.
źródło