SEO friendly URLs

Gjatë zhvillimit të aplikacioneve në PHP, URL-të dijnë të bëhen mjaft komplekse. Shembull:

1 http://localhost/test/index.php?cmd=produkti&id=3

Një URL e tillë do të rezultonte nëse aplikacioni ynë është ruajtur në C:\wamp\www\test.

Me anë të virtual hosts, mund ta eliminojmë fare emrin e folderit test, ashtu që linku i ri do të jetë:

1 http://localhost/index.php?cmd=produkti&id=3

Në vend të localhost mund të jetë ndonjë domain name, nëse aplikacionin e kemi vendosur në remote host, si psh:

1 http://www.onlineshop.com/index.php?cmd=produkti&id=3

Edhe pse u shkurtua pak, URL-ja ende është mjaft komplekse dhe e palexueshme.

Në aspektin e SEO (Search Engine Optimization), URL-të e formuara në mënyrë të këtillë kanë vlerë më të vogël se URL statike, si psh:

1 http://www.onlineshop.com/produkti/3

Për relizim të përkryer të SEO friendly URL, edhe numri në fund duhet të zëvendësohet me slug, pra me fjalë që përmban emërtimin e produktit, në këtë rast. Psh:

1 http://www.onlineshop.com/produkti/cokolade-milka

Por, kjo kërkon një procedurë më të ndërlikuar, që do të shqyrtohet në kapitujt e mëvonshëm.

Pjesa ?cmd=produkti&id=3 quhet query string, dhe më së miri është që në URL-të e aplikacionit tonë të mos figurojnë fare, nëse është e mundur.

mod_rewrite.so

Për të manipuluar me URL-të në mënyrë që atyre t’ua japim dukjen e URL-ve të faqeve statike, duhet të shërbehemi me modulin rewrite_module të Apache.

Këtë e arrijmë në WAMP, duke zgjedhur menunë:

1 Apache - Apache modules - rewrite_module

Kjo realizohet edhe duke e edituar httpd.conf, me heqjen e shenjës # para rreshtit:

1 #LoadModule rewrite_module modules/mod_rewrite.so

Pas heqjes së #, e ristartojmë serverin me Restart All Services në WAMP.

.htaccess

Për momentin, nuk ka ndonjë ndryshim në fuksionimin e aplikacionit tonë. Deri te ndryshimi do të vijmë duke e shtuar një fajll të quajtur .htaccess në folderin kryesor të aplikacionit tonë. Do të shërbehemi me këtë .htaccess, që është “huazuar” nga CodeIgniter:

1 RewriteEngine on
2 RewriteCond $1 !^(index\.php|favicon.ico|assets|robots\.txt)
3 RewriteRule ^(.*)$ /index.php/$1 [L] 

Kodi në rrestin 1 e aktivizon RewriteEngine.

Kodi në rreshtin 2 do të mundësojë që me rastin e thirrjes së cilitdo fajll në aplikacionin tonë, (përveç kur thirren: index.php, favicon.ico, robots.txt dhe folderit assets), Apache do ta thërrasë fajllin index.php.

Pra, nëse shkruajmë psh:

1 http://localhost/kontakti.php
2 
3 http://localhost/login
4 
5 http://localhost/produktet/produkti.php

në të gjitha rastet, Apache do ta servojë fajllin index.php.

Nëse kërkohet ndonjë fajll nga folderi /assets, atëherë do të ofrohet fajlli i kërkuar, e jo index.php. Psh.

1 http://localhost/assets/style.css

Me këtë do të lexohet përmbajtja e style.css drejtëpërsëdrejti.

Kodi në rreshti 3 do të mundësojë që çfarëdo që kemi shkruar në URL pas domainit, t’i bashkangjitet fajllit index.php, duke e ndarë me shenjën /. Pra, nëse kemi shkruar:

1 http://localhost/kontakti

kjo do të përkthehet si:

1 http://localhost/index.php/kontakti

Me këtë ndryshim, ende nuk kemi arritur asgjë, përveç asaj se tash nuk del raporti se faqja nuk është gjetur (Page not found).

Në strukturën e fajllave të aplikacionit tonë, askund nuk gjendet folderi /kontakti, dhe pa Rewrite të aktivizuar, Web serveri do të lajmëronte se ajo faqe/folder nuk ekziston.

Pra, edhepse kemi kërkuar “folderin” kontakti, neve na është ofruar fajlli index.php.

Prej këtu, ne duhet ta vendosim logjikën e analizës së URL-së në index.php në mënyrë që atje të vendoset çka të ndodhë kur vizitori e klikon një link të aplikacionit tonë.

Leximi nga superglobali $_SERVER

Superglobali $_SERVER përmbajnë variabla të ndryshme të cilat tregojnë parametra të ndryshëm dinamikë të serverit. Psh.:

  • Cili URL është kërkuar,
  • Cila skriptë është duke u ekzekutuar,
  • Prej cilit IP po qaset një vizitor, etj.

Të gjitha këto informata mund t’i marrim me funksionin phpinfo(). Neve na intereson vetëm kjo pjesë nga lista e phpinfo():

REQUEST_URI: /kontakti

SCRIPT_NAME: /index.php

PATH_INFO: /kontakti

E shohim se REQUEST_URL dhe PATH_INFO na ka dhënë informatën e njëjtë, por varësisht nga konfigurimi i serverit, mund dhe të mos e japin, gjegjësisht njëra mund të jetë e zbrazët fare. Prandaj, për të vendosur cilën do ta përdorim, së pari duhet të testohet serveri. Ne po e përdorim PATH_INFO. Kjo vlerë në aplikacion lexohet me:

1 $_SERVER['PATH_INFO']

URL-ja mund të ketë më tepër segmente, psh:

  • /produkti/1
  • /produkti/cokolade-milka
  • /produkti/cololade-milka/edit

Për këtë shkak, ne duhet fillimisht ta zbërthejmë URL-në (pjesën pas domainit), në segmente. Kjo arrihet me explode, funksion i cili e ndan një string duke u bazuar në ndonjë karakter të zgjedhur, dhe të gjitha fragmentet e stringut i ruan si elemente të vargut (array).

Në browser psh e shënojmë URL-në: http://kursi.app/produkti/edit/5. Pastaj e analizojmë në skriptë:

1 $url = explode("/", $_SERVER['PATH_INFO']);

Variabli $url është në fakt një varg njëdimensional, i cili ka aq elemente sa segmente ka URL-ja. Në rastin /produkti/cololade-milka/edit, var_dump() do të na i tregojë segmentet si vijon:

1 array (size=4)
2   0 => string '' (length=0)
3   1 => string 'produkti' (length=8)
4   2 => string 'edit' (length=4)
5   3 => string '5' (length=1)

E shohim se segmenti 1 jep fjalën “produkti”, segmenti 2 fjalën “edit” dhe në fund, segmenti 3 e jep numrin 5.

router

Duke u bazuar në vlerat e fituara, pra të segmenteve të URL-së, ne e ndërtojmë router-in e aplikacionit tonë.

Detyra e routerit do të jetë që t’i lexojë segmentet e URL-së, dhe në bazë të atyre të përcaktojë se cilën skriptë do ta ekzekutojë, gjegjësisht ta inkludojë në index.php.

Siç cekëm, $url[1] tregonte segmentin e parë, për neve më kryesorin të URL-së. Duke e shfrytëzuar atë, e ndërtojmë një router rudimentar.

 1 <?php
 2 $url = explode("/", $_SERVER['PATH_INFO']);
 3 if (!empty($url[1]))
 4 	{
 5 	$cmd = filter_var($url[1], FILTER_SANITIZE_STRING);
 6 	
 7 	switch ($cmd)
 8 		{
 9 			case 'login':
10 				require('login.php');
11 				break;
12 			case 'check':
13 				require('check.php');
14 				break;	
15 			case 'produkti':
16 				require('produkti.php');
17 				break;							
18 			case 'kontakti':
19 				require ('kontakti.php');
20 				break;
21 			case 'signup':
22 				require ('regjistrimi.php');
23 				break;							
24 			default:
25 				echo "<p>Nuk ekziston kjo faqe!</p>";
26 		}
27 	}
28 else
29 	{
30 	require("home.php");
31 	}
32 ?>

Nëse tash e shikojmë kronologjikisht si janë ndërtuar URL-të përgjatë kursit, do të shohim se si ato po bëhen gjithnjë e më kompakte dhe më të lexueshme:

1 http://localhost/test/index.php?cmd=produkti&id=3
2 http://localhost/index.php?cmd=produkti&id=3
3 http://kursi.app/index.php?cmd=produkti&id=3
4 http://kursi.app/?cmd=produkti&id=3
5 http://kursi.app/produkti/3

Për leximin e segmentit të dytë do të përdoret $url[2], për të tretin $url[3], e kështu me radhë.