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)
private $_requestUri = null;
private $_post = null;
private $_get = null;
private $_cookie = null;
private $_paramAssoc = null;
private $_paramEnum = null;

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:

  • <= kontroler
  • <= akcja
  • <= nazwa parametru pierwszego
  • <= wartość parametru pierwszego
  • <= 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:

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

Gdybyśmy wypluli zawartość tablicy paramEnum:

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

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:

 // 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()

Implementacja

Przy tworzeniu instancji obiektu Request uruchamiany jest konstruktor

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), '/ ');
}

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

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;
		}
	}
}

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:

$this->getParam(0)

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

$this->getParam(1)

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

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

$this->getParam('kategoria')

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

$this->getParam('AGD')

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:

$this->getParam('strona', 1)

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

_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;
		}
	}
}

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.