W tym artykule postaram się przybliżyć Wam pewne ciekawe możliwości, które oferuje język interpretowany, jakim jest PHP. Umożliwia on mianowicie korzystanie z czegoś w stylu zmiennych „dynamicznych”. Pozwala także na dynamiczne tworzenie nazw funkcji, co może być czasem bardzo przydatne.

Autor: antyqjon

Zmienne nazwy zmiennych

Zacznijmy od zmiennych. Jaka jest „zwykła” zmienna, to każdy widzi, coś w stylu $zmienna i po sprawie. Mamy sobie zmienną, ona gdzieś sobie jest w pamięci, może ma jakąś wartość i to by było na tyle.

Jeżeli jednak mamy zmienną, której wartość jest typu łańcuchowego (string, czyli po prostu tekst), to możemy zrobić coś sprytnego. Przykład poniżej:

<?php 
$zmienna = 'pajaczek';           // ukłon w stronę firmy, no nie! 
$$zmienna = 'pajaczek rzadzi!';  // i tu się dzieje coś ważnego 
echo $pajaczek;                  // skrypt wypisuje 'pajaczek rzadzi!' 
?> 

Co też w poniższych 3 linijkach się podziało? Najpierw zadeklarowaliśmy sobie całkiem jawnie zmienną tekstową. Potem tworzymy „dynamiczną” zmienną, której nazwa jest taka, jak zawartość zmiennej, którą tym razem napisaliśmy z dwoma dolarami, a nie z jednym.

Nazwa zmiennej poprzedzona dwoma znakami dolara to już nie jest ta sama zmienna – to nowa zmienna. W związku z tym tworzy się nam nowa zmienna – $pajaczek. Do zmiennej tej przypisujemy tekst (w momencie jej tworzenia).
A już na końcu wypisujemy zawartość tej zmiennej.

Zastosowanie

Takiej konstrukcji możemy użyć pisząc coś w rodzaju „patcha” dla skryptów pisanych pod stare wersje PHP (dla przypomnienia: od wersji 4.2.0 dyrektywa register_globals jest domyślnie wyłączona, co powoduje, że zmienne przekazywane w adresie URL, formularzach czy pikach cookie nie są rejestrowane w globalnej przestrzeni nazewniczej).

Napisałem „patch” w cudzysłowiu, bowiem to ustawienie ma na celu poprawę bezpieczeństwa skryptu. Kod poniżej ma na celu tylko przystosowanie starych skryptów do współpracy z nowym PHP.

<?php 
foreach ($HTTP_GET_VARS as $key => $value) 
    $$key = $value; 

foreach ($HTTP_POST_VARS as $key => $value) 
    $$key = $value; 

foreach ($HTTP_COOKIE_VARS as $key => $value) 
    $$key = $value; 

foreach ($HTTP_SERVER_VARS as $key => $value) 
    $$key = $value; 
?> 

Konstrukcja ta tworzy zmienne o nazwach takich, jak klucze odpowiednich tablic. Czyli jeżeli mamy element tablicy np. $HTTP_GET_VARS[‚akcja’] to powyższy skrypt utworzy zmienną o nazwie $akcja i wartości takiej, jaką ma ten element tablicy. Poza tym cały czas mamy dostęp do tych tablic, skrypt tylko jakby „kopiuje” nazwy zmiennych z kluczy do globalnej przestrzeni nazw.

Zmienne nazwy funkcji

A teraz podobna historia, ale jak to w bajkach bywa, ktoś coś po drodze pokręci, ktoś doda swoje 3 grosze i mamy zupełnie co innego A mianowicie jak użyć zmiennej tekstowej jako nazwy funkcji? Może najpierw kod przykładu, a potem wyjaśnienia.

<?php // wybierz jeden z rodzajów kodowania hasła 
$encoder = 'md5'; // mocne md5 (tzw. haszowanie hasła) 
// $encoder = 'str_rot13'; // banalna w rozszyfrowaniu zamiana pewnych liter 
// $encoder = 'gaderypoluki'; // tak samo prosta metoda (może i harcerska ;)) 

function gaderypoluki ($tekst) 
{ 
    // zamienia litery wedlug schematu: g<->a, d<->e itp... 
    return strtr($tekst, 'gaderypoluki', 'agedyropulik'); 
} 

$haslo = 'takie tam haslo'; 
print $encoder($haslo); // w zależności od tego, jaką funkcję wybraliśmy na początku skryptu, dostaniemy inny efekt 
                        // dla md5() będzie to d501062a68234643bc4c76cb50b89c74 
                        // dla str_rot13() gnxvr gnz unfyb 
                        // dla gaderypoluki() tgikd tgm hgsup 
?> 

Najpierw zadeklarowaliśmy sobie zmienną, która zawiera nazwę funkcji kodującej hasło. Potem definiujemy funkcję gaderypoluki(), która też jest swego rodzaju prostym szyfrem.
W końcu używamy którejś z funkcji (której nazwa znajduje się w zmiennej $encoder) do zakodowania hasła. Wywołanie tej funkcji to po prostu nazwa zmiennej, która zawiera nazwę funkcji, potem nawias otwierający, argument(y) i nawias zamykający.

Mam nadzieję, że nie zamotałem bardziej, niż było to możliwe Życzę powodzenia w wykorzystywaniu wskazówek takich jak ta!