Uwaga: To jest pytanie referencyjne dotyczące obsługi zakresu zmiennych w PHP. Zamknij dowolne z wielu pytań pasujących do tego wzoru jako duplikat tego.
Co to jest „zakres zmienny” w PHP? Czy zmienne z jednego pliku .php są dostępne w innym? Dlaczego czasami otrzymuję błędy „niezdefiniowana zmienna” ?
Odpowiedzi:
Co to jest „zakres zmienny”?
Zmienne mają ograniczony „zakres” lub „miejsca, z których są dostępne”. To, że napisałeś
$foo = 'bar';
kiedyś gdzieś w aplikacji, nie oznacza, że możesz odwoływać się$foo
z dowolnego miejsca w aplikacji. Zmienna$foo
ma określony zakres, w którym jest prawidłowa i tylko kod z tego samego zakresu ma dostęp do zmiennej.Jak zdefiniowany jest zakres w PHP?
Bardzo proste: PHP ma zakres funkcji . To jedyny rodzaj separatora zakresu, który istnieje w PHP. Zmienne wewnątrz funkcji są dostępne tylko wewnątrz tej funkcji. Zmienne poza funkcjami są dostępne gdziekolwiek poza funkcjami, ale nie wewnątrz żadnej funkcji. Oznacza to, że w PHP jest jeden specjalny zakres: globalny zasięg . Każda zmienna zadeklarowana poza jakąkolwiek funkcją mieści się w tym zasięgu globalnym.
Przykład:
$foo
jest w zasięgu globalnym ,$baz
w zasięgu lokalnymmyFunc
. Tylko kod wewnątrzmyFunc
ma dostęp$baz
. Dostęp ma tylko kod z zewnątrz . Żaden nie ma dostępu do drugiego:myFunc
$foo
Zakres i dołączone pliki
Granice plików nie oddzielają zakresu:
a.php
b.php
Te same zasady mają zastosowanie do
include
kodu d, co do każdego innego kodu: tylkofunction
oddzielny zakres. Ze względu na zakres możesz pomyśleć o dołączeniu plików, takich jak kopiowanie i wklejanie kodu:c.php
W powyższym przykładzie,
a.php
został zawarty w środkumyFunc
, wszystkie zmienne wewnątrza.php
mają tylko lokalny zasięg funkcji. To, że wydają się być w zasięgu globalnym,a.php
niekoniecznie oznacza, że tak jest, w rzeczywistości zależy to od kontekstu, w którym kod jest zawarty / wykonywany.A co z funkcjami wewnątrz funkcji i klas?
Każda nowa
function
deklaracja wprowadza nowy zakres, to takie proste.(anonimowe) funkcje wewnątrz funkcji
zajęcia
Do czego służy luneta?
Radzenie sobie z problemami z zakresem może wydawać się irytujące, ale ograniczony zakres zmiennych jest niezbędny do pisania złożonych aplikacji! Gdyby każda zadeklarowana zmienna była dostępna z dowolnego miejsca w aplikacji, przechodziłbyś przez wszystkie zmienne bez rzeczywistego sposobu na śledzenie, co się zmienia. Jest tylko tyle sensownych nazw, które możesz nadać swoim zmiennym, prawdopodobnie będziesz chciał użyć zmiennej "
$name
" w więcej niż jednym miejscu. Gdybyś mógł mieć tę unikalną nazwę zmiennej tylko raz w swojej aplikacji, musiałbyś uciekać się do naprawdę skomplikowanych schematów nazewnictwa, aby upewnić się, że zmienne są unikalne i że nie zmieniasz niewłaściwej zmiennej z niewłaściwego fragmentu kodu.Przestrzegać:
Gdyby nie było zakresu, co zrobiłaby powyższa funkcja? Skąd się
$bar
bierze? Jaki ma stan? Czy jest w ogóle zainicjowany? Czy za każdym razem musisz sprawdzać? Tego nie da się utrzymać. Co prowadzi nas do ...Przekraczanie granic zakresu
Właściwy sposób: przekazywanie i wychodzenie zmiennych
Zmienna
$bar
jawnie wchodzi do tego zakresu jako argument funkcji. Wystarczy spojrzeć na tę funkcję, aby było jasne, skąd pochodzą wartości, z którymi ona pracuje. Następnie jawnie zwraca wartość. Wzywający ma pewność, że wie, z jakimi zmiennymi funkcja będzie współpracować i skąd pochodzą jej wartości zwracane:Rozszerzenie zakresu zmiennych na funkcje anonimowe
Funkcja anonimowa jawnie obejmuje
$foo
z otaczającego zakresu. Zauważ, że to nie to samo, co zasięg globalny .Zły kierunek:
global
Jak wspomniano wcześniej, zasięg globalny jest nieco wyjątkowy, a funkcje mogą jawnie importować z niego zmienne:
Ta funkcja używa i modyfikuje zmienną globalną
$foo
. Nie rób tego! (Chyba że naprawdę naprawdę naprawdę wiesz, co robisz, a nawet wtedy: nie rób tego!)Wszystko, co widzi wywołujący tę funkcję, to:
Nic nie wskazuje na to, że ta funkcja ma jakiekolwiek skutki uboczne , ale tak jest. Bardzo łatwo staje się to zagmatwanym bałaganem, ponieważ niektóre funkcje ciągle się modyfikują i wymagają pewnego stanu globalnego. Chcesz, aby funkcje były bezstanowe , działały tylko na swoich wejściach i zwracały zdefiniowane dane wyjściowe, niezależnie od tego, ile razy je wywołasz.
W miarę możliwości należy unikać używania zakresu globalnego; z całą pewnością nie powinieneś „wyciągać” zmiennych z zasięgu globalnego do zasięgu lokalnego.
źródło
global
, więc powiedz nam, kiedy powinniśmy użyćglobal
? I proszę wyjaśnij (trochę), co to jeststatic
..?global
. To zawsze jest złe. Przekazywanie parametrów funkcji jest prawidłowe.static
jest dobrze wyjaśniony w instrukcji i nie ma wiele wspólnego z zakresem. W skrócie można ją traktować jako „globalną zmienną o określonym zakresie”. Rozwijam nieco jego użycie tutaj kunststube.net/static .include_once
i prawdopodobnierequire_once
powinien być gdzieś dodany; tylko mówię. OP zagłosował również za ponownym otwarciem swojego pytania. Czy ich post byłby szczególnym przypadkiem i co z tym zrobić?Chociaż do zmiennych zdefiniowanych w zakresie funkcji nie można uzyskać dostępu z zewnątrz, nie oznacza to, że nie można używać ich wartości po zakończeniu tej funkcji. PHP ma dobrze znane
static
słowo kluczowe, które jest szeroko stosowane w PHP zorientowanym obiektowo do definiowania statycznych metod i właściwości, ale należy pamiętać, żestatic
może być również używane wewnątrz funkcji do definiowania zmiennych statycznych.Co to jest „zmienna statyczna”?
Zmienna statyczna różni się od zwykłej zmiennej zdefiniowanej w zakresie funkcji tym, że nie traci wartości, gdy wykonanie programu opuszcza ten zakres. Rozważmy następujący przykład użycia zmiennych statycznych:
Wynik:
Gdybyśmy zdefiniowali
$counter
bez,static
to za każdym razem powtarzana wartość byłaby taka sama, jak$num
parametr przekazywany do funkcji. Użyciestatic
pozwala zbudować ten prosty licznik bez dodatkowego obejścia.Przypadki użycia zmiennych statycznych
Wydziwianie
Zmienna statyczna istnieje tylko w zakresie funkcji lokalnej. Nie można uzyskać do niego dostępu poza funkcją, w której został zdefiniowany. Możesz więc być pewien, że zachowa swoją wartość niezmienioną do następnego wywołania tej funkcji.
Zmienna statyczna może być zdefiniowana tylko jako wartość skalarna lub wyrażenie skalarne (od PHP 5.6). Nadanie mu innych wartości nieuchronnie prowadzi do niepowodzenia, przynajmniej w momencie pisania tego artykułu. Niemniej jednak możesz to zrobić tylko w następnym wierszu swojego kodu:
Wynik:
Funkcja statyczna jest w pewnym sensie „współdzielona” między metodami obiektów tej samej klasy. Łatwo to zrozumieć, przeglądając następujący przykład:
Działa to tylko z obiektami tej samej klasy. Jeśli obiekty pochodzą z różnych klas (nawet wzajemnie się rozszerzają), zachowanie zmiennych statycznych będzie zgodne z oczekiwaniami.
Czy zmienna statyczna to jedyny sposób na zachowanie wartości między wywołaniami funkcji?
Innym sposobem zachowania wartości między wywołaniami funkcji jest użycie domknięć. Zamknięcia zostały wprowadzone w PHP 5.3. Krótko mówiąc, pozwalają one ograniczyć dostęp do pewnego zestawu zmiennych w zakresie funkcji do innej funkcji anonimowej, która będzie jedynym sposobem uzyskania do nich dostępu. Bycie w zamknięciu zmiennych może imitować (mniej lub bardziej skutecznie) koncepcje OOP, takie jak „stałe klasy” (jeśli zostały przekazane w domknięciu przez wartość) lub „właściwości prywatne” (jeśli zostały przekazane przez odniesienie) w programowaniu strukturalnym.
Ta ostatnia faktycznie pozwala na użycie domknięć zamiast zmiennych statycznych. O tym, czego użyć, zawsze decyduje programista, ale należy wspomnieć, że zmienne statyczne są zdecydowanie przydatne podczas pracy z rekurencjami i zasługują na uwagę programistów.
źródło
Nie opublikuję pełnej odpowiedzi na to pytanie, ponieważ istniejące i podręcznik PHP świetnie sobie z tym radzą.
Ale jeden przedmiot, który został brakowało że od superglobals , w tym powszechnie stosowane
$_POST
,$_GET
,$_SESSION
, itd. Te zmienne są tablice, które są zawsze dostępne, w każdym zakresie, bezglobal
deklaracji.Na przykład ta funkcja wydrukuje nazwę użytkownika uruchamiającego skrypt PHP. Zmienna jest dostępna dla funkcji bez żadnego problemu.
Ogólna zasada „globalne są złe” jest zwykle zmieniana w PHP na „globalne są złe, ale superglobale są w porządku”, o ile nie nadużywa się ich. (Wszystkie te zmienne są zapisywalne, więc można ich użyć, aby uniknąć wstrzyknięcia zależności, gdybyś był naprawdę okropny).
Nie ma gwarancji, że te zmienne będą obecne; administrator może wyłączyć niektóre lub wszystkie z nich za pomocą
variables_order
dyrektywy wphp.ini
, ale nie jest to typowe zachowanie.Lista obecnych superglobali:
$GLOBALS
- Wszystkie zmienne globalne w bieżącym skrypcie$_SERVER
- Informacje o serwerze i środowisku wykonawczym$_GET
- Wartości przekazane w ciągu zapytania adresu URL, niezależnie od metody HTTP użytej w żądaniu$_POST
- Wartości przekazane w żądaniu HTTP POST z typami MIMEapplication/x-www-form-urlencoded
lubmultipart/form-data
$_FILES
- Pliki przekazane w żądaniu HTTP POST zmultipart/form-data
typem MIME$_COOKIE
- Pliki cookie przekazane wraz z bieżącym żądaniem$_SESSION
- Zmienne sesji przechowywane wewnętrznie przez PHP$_REQUEST
- Zazwyczaj połączenie$_GET
i$_POST
, ale czasami$_COOKIES
. Treść jest określona przezrequest_order
dyrektywę wphp.ini
.$_ENV
- Zmienne środowiskowe bieżącego skryptuźródło