Esmu novērojis, ka daudzi web izstrādātāji-iesācēji redirektus veic, nosūtot pārlūkam
redirektējošu <meta> tagu. Piemēram, kaut ko līdzīgu šim:

<meta http-equiv="Refresh" content="0;URL=http://www.example.org/example.php">

Visbiežāk šī rindiņa pārlūkam tiek nosūtīta pilnībā ignorējot HTML dokumenta
struktūru. Vai nu to nosūta vienu pašu, pilnībā aizmirstot par pareizu dokumenta
struktūru, vai arī tā tiek izdrukāta kaut kur <body> daļā. Lai gan visbiežāk it kā
viss strādās, un redirekts notiks, tomēr šī nav pareizā pieeja.

Galvenie mīnusi: lieka datu pārsūtīšana; nav garantija, ka redirekts vispār
notiks.

Pareizais veids

Izmantot PHP iebūvēto funkciju header(), lai nosūtītu pārlūkam

HTTP headeri Location, kas veic redirektu. Nešaubos, ka lielākā daļa jau izmanto šo
metodi, bet atļaušos atgādināt par pāris mazām, bet svarīgām niansēm.

Pirmkārt, jau pati koda rindiņa:

header('Location: http://www.example.org/example.php');

It kā viss ir labi, bet pamēģiniet šādu kodu:

<?php
$logged_in = false; // Vispār te būtu kods, kas nosaka, vai $logged_in ir true vai false
if ($logged_in !== true) {
 header('Location: http://www.example.org/login.php');
}
header('Location: http://www.example.org/sensitive_data.php');
?>

Protams, pārbaude vai $logged_in ir true būtu
jāveic arī iekš sensitive_data.php, bet tam šobrīd nepievērsīsim uzmanību.

Problēma ir, ka funkcija header() tiks izsaukta abas reizes, un pārlūkam
tiks nosūtīts tikai pēdējais no Location headeriem. Patiesībā
pārlūkam tiks nosūtīti pilnīgi visi potenciāli iespējamie headeri, kas varētu būt
kodā vēl pēc pirmā Location headera.

Risinājums ir vienkāršs: pēc redirektējošā header() vajag
pārtraukt skripta darbību.
To var izdarīt ar die() vai exit().

<?php
$logged_in = false;
if ($logged_in !== true) {
 header('Location: http://www.example.org/login.php');
 die();
}
header('Location: http://www.example.org/sensitive_data.php');
die();
?>

Vēl viena svarīga lieta, kas jāpiezīmē, ja tiek izmantotas sesijas, ka
reizēm, izmantojot šādu redirektēšanas metodi,
var netikt pieglabāti iepriekš skriptā izveidotie sesijas mainīgie. Lai cīnītos
ar šo potenciālo problēmu, tad pirms redirekta vajag izsaukt session_write_close()
funkciju, kas ierakstīts visus sesijus datus diskā (vai arī jebkur citur, ja izmantojat
session_set_save_handler() un pats savu sesijas datu glabāšanus metodi)
un noslēgs pašu sesiju.

Lai visu padarītu vēl ērtāk, tad šo redirektēšanu varam veikt ar
speciālu pašrakstītu funkciju. Nosauksim to, piemēram, par redirect_to().

<?php
function redirect_to($url) {

	if (empty($url)) {
	 	return false;
	}

	if (session_id() != '') {

	 	// Tikai ja sesija eksistē
	 	session_write_close();

	}

	header('Location: '.$url);
	die();

}
?>

Svarīga piezīme par header():
header() funkcija nestrādās, ja pārlūkam jau būs nosūtīts kaut
viens tags, simbols, tukšuma zīme vai jeb kas cits, kas nav header. Šis bieži
ir klupšanas akmens iesācējiem. HTTP pieprasījuma uzbūve ir tāda, ka vispirms klientam (pārlūkam)
tiek nosūtīti visi vajadzīgie headeri un tad tikai pats HTML (vai XML, RSS vai jeb kas cits).
Ir iespējams šo lietu apiet, PHP iestatījumos ieslēdzot output_buffering
direktīvu. Ieslēgts output buffering nozīmē, ka skripta izdotie tagi un citi simboli
pārlūkam tiks nosūtīti tikai paša skripta izpildes beigās, kas nozīmē, ka ja
skriptā būs kāds header(), tad tas noteikti tiks nosūtīts pārlūkam pirms jebkāda
outputa. Bet iesaku nesteigties rediģēt php.ini failu, bet gan labāk mēģināt
plānot kodu tā, ka visi iespējamie redirekti notiek tikai pirms HTML outputa.