This post comes from the first version of this blog.
Please send me an email if anything needs an update. Thanks!

Kiedy programuję aplikacje z wykorzystaniem różnego rodzaju frameworków, zawsze zastanawiam się, jak to jest, że ich twórcy potrafią wymyślić rozwiązania, dzięki którym codziennie oszczędzamy cenny czas. Na pewno jest to doświadczenie, na pewno swój wkład ma także talent danego programisty, ale istotną częścią jest także dogłębna znajomość języka programowania, w którym rzeczony framework jest tworzony. W dzisiejszym wpisie chciałbym się z Wami podzielić ciekawym trikiem, jaki pozwala frameworkom na znaczne uproszczenie korzystania z danych przekazanych do widoku.

Fotografia: Robert Agthe, CC-BY-SA.

PHP: Zmienne przekazane do widoku.

Zazwyczaj, jeśli chcemy przekazać dane do widoku, to zależnie od frameworka dodajemy je do swojego rodzaju kontenera, który dla uproszczenia można przyrównać do zwykłego array'a. Oczywiście zazwyczaj jest to opakowane w jakąś klasę, czy inną strukturę danych, aczkolwiek idea pozostaje ta sama - relacja identyfikator => zasób. Przyjmijmy pewną prototypową implementację [na wzór CakePHP]:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$this->set('recordId', 59);
$this->set('data', array(
	'record1' => array(
		'id' => 2,
		'name' => 'Tommy',
		'order' => 46,
		),
	'record2' => array(
		'id' => 3,
		'name' => 'Qwerty',
		'order' => 79,
		),
	));
$this->set('str', 'Long string to display.');

Zapisaliśmy dane do kontenera, teraz wypadałoby je jakoś odczytać. Jeśli macie jakiekolwiek doświadczenie z frameworkami, na pewno zauważyliście, że w widoku będzie można to wykorzystać np. tak:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<h1><?php echo $recordId; ?></h1>
<table>
	<?php foreach($data as $key => $val): ?>
	<tr>
		<td><?php echo $val['id']; ?></td>
		<td><?php echo $val['name']; ?></td>
		<td><?php echo $val['order']; ?></td>
	</tr>
	<?php endforeach; ?>
</table>
<span><?php echo $recordId; ?></span>

Zaraz, zaraz - używamy zmiennych, ale skąd one się wzięły? Statystycznego programistę nie interesuje, skąd biorą się narzędzia, z jakich korzysta - ważne, żeby działały. Tutaj jednak warto poznać mechanizm, jaki za tym stoi. W ten sposób możemy oszczędzić sobie o wiele więcej czasu w zupełnie niepowiązanych przypadkach.

PHP: Funkcja extract().

Za całą "magię" odpowiada jedna mała, aczkolwiek bardzo użyteczna funkcja extract(). Jej działanie zostało bardzo krótko i prosto wyjaśnione w manualu PHP:
Ta funkcja służy do importowania zmiennych z tablicy do bieżącej tablicy symboli. Pobiera jako parametr tablicę asocjacyjną tablica_zmiennych i traktuje klucze jako nazwy zmiennych a wartości jako wartości tych zmiennych. Dla każdej pary klucz/wartość w bieżącej tablicy symboli będzie stworzona zmienna, zależna od parametrów typ_ekstrakcji i prefiks.
Oznacza to, że otrzymamy zestaw zmiennych odpowiednich do zawartości przekazanej tablicy. Biorąc pod uwagę nasz przykład [nadal CakePHP], zobaczmy, jak zadziała następujący kod:
1
2
3
4
extract($this->viewVars);
var_dump($recordId);
var_dump($data);
var_dump($str);

Wynik:

int(59)
array(2) {
  ["record1"]=>
  array(3) {
    ["id"]=>
    int(2)
    ["name"]=>
    string(5) "Tommy"
    ["order"]=>
    int(46)
  }
  ["record2"]=>
  array(3) {
    ["id"]=>
    int(3)
    ["name"]=>
    string(6) "Qwerty"
    ["order"]=>
    int(79)
  }
}
string(23) "Long string to display."

Co dowodzi, że wynik działania funkcji jest taki, jakbyśmy oczekiwali. Przy okazji - warto zapoznać się z opisem typów ekstrakcji, ponieważ czasem mogą one nam trochę napsuć krwi, jeśli nadpiszemy sobie jakieś przydatne zmienne w danym zasięgu.

Być może jednak już tą funkcję znacie i używaliście jej w innych przypadkach? Jeśli tak, to będę wdzięczny za opis sytuacji i tego, w jaki sposób funkcja extract() ułatwiła Wam życie programisty. ;] Do zobaczenia w niedzielę!