Witam w serii artykułów opisujących implementację komponentów budujących zintegrowany system Prime.

Zacznij od przeczytania artykułu wstępnego jeśli tego nie zrobiłeś.

Z punktu widzenia użytkownika na początku pojawia się „żądanie„. Obsługą żądań zajmuje się komponent o nazwie „Request

Pola

Komponent posiada pola w których przechowuje wartości o żądaniu.

  1. Informacje o danych POST
  2. Informacje o danych GET
  3. Informacja o adresie żądania
  4. Informacja o ciasteczkach
  5. Informacja o parametrach adresu (coś podobnego do Zend’a)

[php]
private $_requestUri = null;
private $_post = null;
private $_get = null;
private $_cookie = null;
private $_paramAssoc = null;
private $_paramEnum = null;
[/php]

Info! Można zauważyć, że dla parametrów adresu przewidziane są dwa pola. Pole paramAssoc będzie przechowywało wartości w postaci tablicy asocjacyjnej. Natomiast paramEnum będzie przechowywało wartości w postaci numerycznej. Obrazując to na przykładzie:

Jeżeli zostanie wywołany taki adres:

http://www.mojastrona.pl/przegladanie/kategoria/nazwa/AGD/strona/1/

Dla nieobytych z rozwiązaniami Zend’a można to podzielić w taki sposób:

  • <przegladanie> <= kontroler
  • <kategoria> <= akcja
  • <nazwa> <= nazwa parametru pierwszego
  • <AGD> <= wartość parametru pierwszego
  • <strona> <= nazwa parametru drugiego
  • <1> <= wartość parametru drugiego

Tablice paramAssoc i paramEnum przechowują tylko nazwy i wartości parametrów z tym, że w taki oto sposób:

Gdybyśmy wypluli zawartość tablicy paramAssoc:

[php]
Array
(
[nazwa] => AGD,
[strona] => 1
)
[/php]

Gdybyśmy wypluli zawartość tablicy paramEnum:

[php]
Array
(
[0] => nazwa,
[1] => AGD,
[2] => strona,
[3] => 1
)
[/php]

Mam nadzieję, że widać na czym polega różnica. Po co to rozbicie? Za chwilę wyjaśnię.

Metody

Komponent oferuje dostęp do poniższych metod:

[php]
// Pobieranie adresu żądania
public function getUri()

// Pobranie parametru
public function getParam($param = null, $default = null)

// Pobranie wartości post
public function getPost($param = null, $default = null)

// Pobranie wartości get
public function getGet($param = null, $default = null)

// Pobranie informacji czy zostało wykonane żądanie POST
public function isPost()
[/php]

Implementacja

Przy tworzeniu instancji obiektu Request uruchamiany jest konstruktor

[php]
function __construct() {
$this->_requestUri = $_SERVER[’REQUEST_URI’];
$this->_post = $_POST;
$this->_get = $_GET;
$this->_cookie = $_COOKIE;

$this->_requestUri = trim(str_replace(’?’ . $_SERVER[’QUERY_STRING’], ”, $this->_requestUri), '/ ’);
}
[/php]

Nie ma tutaj nic bardzo magicznego. Do odpowiednich pól zapisywane są wartości z odpowiednich tablic. Jedyny bardziej skomplikowany kawałek kodu (linijka 7) polega na tym by z requestu usunąć parametry tzw „Query String” – czyli te parametry po znaku „?” w adresie. Mamy je zapisane w tablicy GET i nie są one nam w adresie potrzebne. Nie znaczy to, że są niedostępne w frameworku. Chodzi o to by komponent zrozumiał o jakie żądanie chodzi i właściwie sobie podzielił elementy.

Kolejną ciekawą metodą wartą wyjaśnienia jest getParam

[php]
public function getParam($param = null, $default = null) {
if ($param === null) {
return $this->_paramAssoc;
}

if (is_int($param)) {
if (isset($this->_paramEnum[$param])) {
return $this->_paramEnum[$param];
} else {
return $default;
}
} else {
if (isset($this->_paramAssoc[$param])) {
return $this->_paramAssoc[$param];
} else {
return $default;
}
}
}
[/php]

Pierwszym argumentem jest nazwa parametru. I teraz własnie wyjaśnię wykorzystanie osobnych tablic paramAssoc i paramEnum

Jeżeli żaden argument nie zostanie przekazany to metoda zwróci całą tablicę wszystkich parametrów. Jeżeli natomiast przekazany argument będzie liczbą całkowitą to zostanie pobrana wartość z tablicy paramEnum. W przeciwym wypadku z tablicy paramAssoc.

Drugi parametr służy do tego by zwrócić wartość domyślą jeśliby żądany parametr nie istniał.

Przykład:

[php]
$this->getParam(0)
[/php]

Zwróci w naszym przypadku wartość „nazwa”

[php]
$this->getParam(1)
[/php]

Zwróci w naszym przypadku wartość „AGD”

Jeżeli jednak zamiast wartości numerycznej zażądamy parametru po nazwie to:

[php]
$this->getParam(’kategoria’)
[/php]

Zwróci „AGD”

Używanie parametrów po nazwach jest zalecane gdyż nie wprowadza zamieszania i wiadomo na pewno którą wartość pobieramy. Wywołanie

[php]
$this->getParam(’AGD’)
[/php]

Zwróci NULL gdyż nie ma parametru o takiej nazwie. Jest to tylko wartość parametru kategoria.

Co w przypadku gdyby ktoś nie podał kategorii a chcemy aby system domyślnie coś pod ten parametr podstawił, żeby już nie trzeba było tego sprawdzać? Wtedy używamy drugiego argumentu:

[php]
$this->getParam(’strona’, 1)
[/php]

Jeżeli ktoś poda parametr „strona” to zostanie on użyty. W przypadku braku parametru „strona” zostanie zwrócona wartość 1.

Metody getGet oraz getPost działają w zasadzie identycznie jak getParam. Z tą różnicą, że przyjmują parametry jedynie jako nazwy (nie można ich pobierać w sposób numeryczny)

To w zasadzie tyle. Komponent posiada jeszcze kilka metod odpowiedzialnych za komunikację z komponentem „Request”, który będzie bohaterem kolejnego odcinka, ale nie będę ich tu przedstawiał gdyż nie są one istotne do zrozumienia działania komponentu.

Pełny kod źródłowy

[php]
<?php

/**
* Controls the request info including GET, POST, COOKIE and PARAMS
* @package Prime
* @version 1.0
* @author Quadric
* @copyright (c) 2009 Quadric
* @license http://quadric.goblix.pl/license.html
*/
class Request {

/**
* Contains Request URI
*/
private $_requestUri = null;
private $_post = null;
private $_get = null;
private $_cookie = null;
private $_paramAssoc = null;
private $_paramEnum = null;

/**
* Get Request URI and save into variable
*/
function __construct() {
// Grab data
$this->_requestUri = $_SERVER[’REQUEST_URI’];
$this->_post = $_POST;
$this->_get = $_GET;
$this->_cookie = $_COOKIE;

// Cleanup data
$this->_requestUri = trim(str_replace(’?’ . $_SERVER[’QUERY_STRING’], ”, $this->_requestUri), '/ ’);
}

public function getUri() {
return $this->_requestUri;
}

/**
* Get param by name or index. Having user/info/id/4 is posibly to get
* value of "id" param by getParam(’id’) is equal to '4′ or getParam(0) is
* equal to 'id’ or getParam(1) is equal to '4′ and getParam(’4′) is not a
* parameter. Optionally if param doesn’t is not perform a default value:
* while getParam(’b’) doesn’t exists getParam(’b’, 'Hello’) will return
* 'Hello’
* @param mixed $param Param name of Index
* @param mixed $default Use if param is not set0
* @return string Requested param value
*/
public function getParam($param = null, $default = null) {
if ($param === null) {
return $this->_paramAssoc;
}

if (is_int($param)) {
if (isset($this->_paramEnum[$param])) {
return $this->_paramEnum[$param];
} else {
return $default;
}
} else {
if (isset($this->_paramAssoc[$param])) {
return $this->_paramAssoc[$param];
} else {
return $default;
}
}
}

public function setParamEnum($param) {
$this->_paramEnum = $param;
}

public function setParamAssoc($param) {
$this->_paramAssoc = $param;
}

public function setParam($param, $value) {
$this->_paramEnum[] = $value;
$this->_paramAssoc[$param] = $value;
}

public function getPost($param = null, $default = null) {
if ($param === null) {
return $this->_post;
}

if (isset($this->_post[$param])) {
return $this->_post[$param];
} else {
return $default;
}
}

public function getGet($param = null, $default = null) {
if ($param === null) {
return $this->_get;
}

if (isset($this->_get[$param])) {
return $this->_get[$param];
} else {
return $default;
}
}

/**
* Zwraca info czy był POST
* @todo zrobić to lepiej
*/
public function isPost() {
if ( ! empty($_POST)) {
return true;
} else {
return false;
}
}
}
[/php]

Możesz użyć tej klasy i wywołać ją samodzielnie. Zobaczyć jak działa i jak się zachowuje.

Na koniec pytanie – zagadka: Czy pobieranie parametrów w postaci tablicy numerycznej ma w ogóle sens i jest przydatne? Czekam na komentarze w tej sprawie.

Pozdrawiam.