Funksionet

## Built-in functions

Funksionet janë tërësi programore për zgjidhjen e një problemi të caktuar. Mund të përdoren për:

  • ta llogaritur ndonjë vlerë,
  • për ta konstatuar/verifikuar ndonjë gjendje,
  • për ta kryer ndonje veprim, etj.

Ato janë vetë esenca e PHP-së, sikurse që është rasti edhe me gjuhët e tjera programore.

PHP posedon një numër të madh të funksioneve të integruara. Numri i saktë i tyre varet prej PHP ekstensioneve të instaluara; sa më shumë ekstensione - aq më shumë funksioneve i kemi në dispozicion.

Numrin e saktë të funksioneve të një instalimi konkret, mund ta shohim me këtë kod:

1 <?php
2 $f = get_defined_functions();
3 echo count($f['internal']);
4 ?>

Në këtë kompjuter, me WAMP të instaluar dhe vetëm disa ekstensione, numri është 1890. Me shtimin e eksensioneve të tjera, ky numër do të bëhet më i madh.

Edhe pse ky numër i funksioneve është jashtëzakonisht i madh dhe përfshin zgjidhje për situata të ndryshme, megjithatë ka raste kur na nevojitet një funksion i ri që do të kryejë një detyrë shumë specifike. Atëherë paraqitet nevoja për krijimin e një funksioni të ri, të ashtuquajturat “user-defined functions”.

Megjithatë, para se të fillojmë ta ndërtojmë një funksion të ri, është mirë të verifikojmë në PHP manual nëse një funksion që e kryen atë punë tashmë ekziston. Funksionet e integruara, përveç që do të ekzekutohen më shpejt, janë edhe më të sigurtë dhe përmbajnë më pak “bugs”.

Veç kësaj, duke kërkuar nëpër Web, mund të gjejmë funksione të gatshme, apo edhe biblioteka të tëra të funksioneve, me përdorimin e të cilave mund të zgjidhim probleme të ndryshme, pa pasur nevojë ta kuptojmë kodin e tyre, apo të ndërhyjmë.

User-defined functions

Gjatë kërkimit të gabimeve nëpër skriptat tona, shpeshherë e përdorim funksionin var_dump() për të na treguar vlerat e ndonjë variabli, rëndomë të atyre më kompleks siç janë vargjet.

Nëse skripta jonë automatikisht redirektohet në ndonjë faqe tjetër, ne nuk do të jemi në gjendje se çfarë rezultati na jep var_dump(). Për këtë arsye, pas var_dump(), shtojmë edhe die() ose exit. Funksionin die() e shtojmë edhe atëherë kur me qëllim dëshirojmë ta ndalim ekzekutimin e skriptës, në mënyrë që ta izolojmë vendin e gabimit më mirë. Shpesh ndodh që gabimi ka origjinën e ka krejt tjetërkund në krahasim me vendin ku raportohet, prandaj duke e ndalur programin në vende të ndryshme, ne arrijmë ta gjejmë burimin e problemit.

Nëse shpesh na nevojiten këto dy funksionet e cekura (var_dump() dhe die()), do të ishte mjaft e bezdishme që t’i shkruajmë gjithmonë nga fillimi. Për këtë arsye, mund ta krijojmë një funksion të ri për të na e lehtësuar punën.

1 function dd($arg, $message="") {
2 var_dump($arg);
3 die($message);
4 ?>

Këtë funksion e vendosim le të themi në fund të skriptës, edhepse vendndodhja e tij brenda skriptës nuk ka kurrfarë rëndësie, sepse është një tërësi në vete dhe ekzekutohet vetëm kur thirret në mënyrë eksplicite.

Tash, mund t’i analizojmë variablat me funksionin e ri dd(). Nëse për shembull duam ta dimë përmbajtjen e superglobalit $_POST, shkruajmë dd($_POST); ose dd($_POST, "test"); kur duam ta shoqërojmë edhe ndonjë mesazh.

1 <?php
2 dd($_POST);
3 
4 function dd($arg, $message="") {
5 var_dump($arg);
6 die($message);
7 ?>

Tash, pra, ekzekutohen dy funksione njëri pas tjetrit. Së pari var_dump() e tregon përmbajtjen e $_POST, e pastaj die() e ndërpren ekzekutimin e skriptës duke e dhënë mesazhin që e kemi shënuar si parametër të dytë te dd().

Nëse ky funksion na nevojitet edhe në skriptat tjera, mund ta kopjojmë përmbajtjen e tij dhe ta vendosim nëpër skripta. Mirëpo, nëse më vonë dëshirojmë ta bëjmë ndonjë ndryshim në funksion, do të duhet që ta editojmë çdo skriptë ku e kemi vendosur atë funksion.

Për këtë arsye, zgjidhja më praktike është që funksionin ta vendosim në një fajll të veçantë dhe ta bëjmë include në të gjitha skriptat ku na nevojitet.

funksionet.php

1 <?php
2 function dd($arg, $message="") {
3 var_dump($arg);
4 die($message);
5 ?>

skripta.php

1 <?php
2 include("funksionet.php");
3 dd($_POST);
4 ?>

Për aplikacionin tonë mund të nevojitet një numër i funksioneve të ndryshme, kështu që është mirë që ato t’i vendosim në një fajll të përbashkët, jo secilin veç e veç. Kështu do të kemi nevojë vetëm për një include.

Nëse megjithatë numri i funksioneve është i madh, pa nevojë do të inkludohej fajlli i madh, prandaj ne duhet t’i sistemojmë nëpër fajlla duke i grupuar. Bëjmë include vetëm atë fajll që përmban grupin e funksioneve që do t’i përdorim në skriptën tonë. Në këtë mënyrë formojmë “biblioteka” të funksioneve.

Anatomia e funksionit

Emërtimi i funksionit

Funksioni duhet ta ketë një emër që fillon me shkronjë apo në raste të caktuara me _ (underline). Emri duhet të jetë unik, që të mos ketë kolizion me emrat e funksioneve ekzistuese. Emri i funksionit është case-insensitive, që dmth se nëse e emërtojmë funksionin tvsh, mund ta thërrasim edhe me Tvsh ose TVSH.

Pas emrit të funksionit vendosen kllapat (), brenda të cilave do t’i vendosim parametrat, apo thënë ndryshe - vlerat hyrëse të funksionit, nëse funksioni ka nevojë për ta. Pas kllapave vendosen kllapat e mëdha (curly braces), të cilat e definojnë bllokun e kodit të funksionit.

1 function tvsh($input) {
2 . . .
3 }

Tërësitë e funksionit

Funksionet mund t’i zbërthejmë në 3 tërësi:

  • Leximi i vlerave hyrëse
  • Procesimi i vlerave hyrëse dhe krijimi i vlerës dalëse
  • Kthimi i vlerës dalëse

Vlerat hyrëse, apo parametrat e funksionit janë atë vlera që përcillen nga programi/skripta për t’u përpunuar brenda funksionit. Imagjinojeni funksionin si një makinë e cila kërkon lëndë të parë për ta prodhuar një produkt. Lënda e parë e funksioneve janë vlerat numerike, tekstuale, logjike, etj. Ato vlera procesohen brenda funksionit për t’u përfituar rezultati i cili pastaj i kthehet “thirrësit”.

1 <?php
2 echo "Cmimi me TVSH: ".tvsh(100);
3 
4 function tvsh($cm) {
5 $cmt = $cm+($cm*16/100);
6 return $cmt;
7 }
8 ?>

Funksioni tvsh thirret në rreshtin e dytë si tvsh(100), ku vlera 100 është çmimi pa TVSH.

Funksioni e merr atë vlerë nëpërmes parametrit $cm. Parametrat shënohen brenda kllapave pas emërtimit të funksionit.

Rreshti vijues e vendos vlerën e $cm në formulën $cm+($cm*16/100), formulë kjo që vlerën e variablit $cm e rrit për 16%, duke e fituar kështu çmimin me TVSH. Vlerat e re vendoset në variablin $cmt. Në rreshtin tjetër, me urdhërin return e kthejmë vlerën e cmimit me TVSH. Ku apo kujt ia kthejmë. Thirrësit, që në këtë rast është rreshti: echo "Cmimi me TVSH: ".tvsh(100);

Krejt pjesa tvsh(100) zëvendësohet me vlerën e kthyer nga funksioni, pra me numrin 116. Prandaj, echo do ta “printojë” tekstin Cmimi me TVSH: 116.

Funksionet mund të kenë një apo më tepër parametra, por mund edhe të mos e kenë asnjë. Funksionet të cilave nuk kanë nevojë për të dhëna hyrëse, nuk kanë parametra. Për shembull funksionin i PHP time() që tregon UNIX timestamp, nuk ka nevojë për asnjë vlerë hyrëse për të na kthyer si rezultat kohën aktuale.

Brenda funksionet shkruajmë kod në mënyrë standarde, nuk dallon asgjë nga programimi i pjesës tjetër të skriptës.

Kthimi i vlerave

Funksionet kthejnë vlera, por kemi edhe funksione që nuk kanë nevojë të kthejnë vlera fare. Parimisht, nëse funksioni duhet vetëm të kryejë procesim për të ardhur deri te një vlerë, ne zgjedhim që funksioni të kthejë vlerë. Në rastet kur funksioni duhet ta kryejë një veprim, atëherë ai mund të mos kthejë rezultate.

Dallimi ndërmjet argumentit dhe parametrit

Jo rrallë krijohet konfuzion me terminologjinë e përdorur për përshkrimin e funksioneve, ku ngatërrohen kuptimet e fjalës argument me atë parametër.

Kur e thërrasim një funksion, ne atij i përcjellim argumente:

1 $cmimi_tvsh = tvsh(56);

Numri 56 është argument që i jepet funksionit.

Te rreshti ku e definojmë funksionin, i shënojmë parametrat.

1 function tvsh($cm) {
2 
3 }

Variabli $cm këtu është parametër.

Renditja e parametrave duhet të jetë krejtësisht e njëjtë me renditjen e argumenteve, si dhe duhet të jenë të tipit të njëjtë. Pra, argumenti i parë i përgjigjet parametrit të parë dhe të dyja duhet ta kenë tipin e njëjtë (integer, float, array, …). Emrat e parametrave nuk është e thënë të jenë të njëjtë me ato të argumenteve, mund të përdorim çfarëdo emrash, me rëndësi është vetëm renditja e tyre.

1 $cmimi = 100;
2 $tvsh = 16;
3 echo tvsh($cmimi, $tvsh);
1 function tvsh($cm, $shk) {
2 . . .
3 }

Siç shohim parametrit $cm i përgjigjet argumenti $cmimi, ndërsa atij $shk i përgjigjet $tvsh. Emrat janë irelevantë, renditja është ajo që merret parasysh.

Numri i argumenteve nuk është e thënë të jetë i barabartë me numrin e parametrave:

1 echo tvsh(100);
1 function tvsh($cm, $shk=16) {
2 $cmt = $cm+($cm*$shk/100);
3 return $cmt;
4 }

Në këtë rast, funksioni thirret me vetëm një argument, por funksioni i ka dy parametra. Argument i dytë në këtë rast është opcional. Në mungesë të vlerës për parametrin e dytë, vendoset default value, në këtë rast 16. Pra, nëse dëshirojmë të llogarisim me bazën 16% të TVSH, funksionin e thërrasim duke i dhënë vetëm argumentin e parë. Nëse kërkojmë llogaritje me ndonjë bazë tjetër, atëherë e shënojmë edhe argumentin e parë, edhe argumentin e dytë.

Pra, $shk e merr vlerën 16, vetëm atëherë kur mungon argumenti i dytë gjatë thirrjes së funksionit, përndyshe, në prezencë të argumentit të dytë - parametri i dytë e merr vlerën e atij argumenti.

Funksioni kthen vetëm një vlerë: një string, një numër, një boolean,… Nëse dëshirojmë të kthejmë më tepër vlera, e përdorim një varg (array), brenda së cilës i kemi vendosur vlerat e dëshiruara. Në shembullin e mëposhtëm, funksioni do të na kthejë dy vlera: vlerën e TVSH-së dhe çmimin me TVSH.

 1 <?php
 2 $cmimi = tvsh(115, 16);
 3 echo "<p>Vlera e TVSH:".$cmimi['tvsh'];
 4 echo "<p>Cmimi me TVSH:".$cmimi['cmimi_tvsh'];
 5 
 6 function tvsh($cm, $shk=16) {
 7 $tvsh = $cm*$shk/100;
 8 $cmimi_tvsh = $cm+$tvsh;
 9 $rezultati = array('tvsh' => $tvsh, 'cmimi_tvsh' => $cmimi_tvsh);
10 return $rezultati;
11 }

Rezultati:

1 Vlera e TVSH:18.4
2 Cmimi me TVSH:133.4

Jetëgjatësia e variablave brenda funksioneve

Variablat që përdoren brenda funksionit, kanë një dallim me variablat në pjesën tjetër të skriptës: ato “jetojnë” aq sa jeton funksioni, dhe me kryerjen e ekzekutimit të funksionit - ato vlera fshihen. Variablat e tilla quhen variabla lokale. Këto variabla nuk do të bijnë në kolizion me variablat me emërtim të njëjtë që janë jashtë funksionit.

 1 <?php
 2  $cmimi = 100;
 3  echo "<p>Cmimi:".$cmimi;
 4  trego_cmimin();
 5  echo "<p>Cmimi:".$cmimi;
 6  
 7  
 8  function trego_cmimin()
 9  	{
10 	$cmimi = 200;
11 	 echo "<p>Cmimi:".$cmimi;	
12 	}
13 ?>

Rezultati:

1 Cmimi:100
2 Cmimi:200
3 Cmimi:100

Siç shihet nga shembulli, vlera e variablit $cmimi në skriptë është 100, brenda funksionit është 200, dhe kur e “printojmë” prapë - vlera është 100. Pra, ndryshimi i vlerës së variablit me emër të njëjtë brenda funksionit - nuk e ka ndryshuar vlerën e atij variabli jashtë funksionit.

Kjo karakteristikë na mundëson që në funksione të përdorim variabla me emërtime sipas dëshirës, pa pasur frikë se ato do t’i “mbulojnë” vlerat e variablave me emër të njëjtë jashtë skriptës.

Po ashtu, ky “izolim” i variablave brenda funksionit, mundëson që vlera e tyre të mos ndryshohet aksidentalisht, duke e marrë vlerën e ndonjë variabli me emër të njëjtë jashtë funksionit.

Me këtë, funksionet janë si “kuti të zeza”, variablat e të cilave nuk ndikohen nga “ambienti i jashtëm”, duke e bërë kodin e tyre portabil, pra që të mund ta përdorim në cilëndo skriptë që të na nevojitet.

Nëse megjithatë na nevojitet ndonjë “interaksion” i funksionit me “ambientin e jashtëm”, kemi mundësi që variablat e caktuar t’i shpallim si “variabla globalë”, me global.

 1 <?php
 2 $cmimi = 100;
 3 echo "<p>Cmimi pa TVSH:".$cmimi;
 4 echo "<p>Cmimi me TVSH:".trego_cmimin(16);
 5 
 6 function trego_cmimin($tvsh)
 7  	{
 8 	global $cmimi;
 9 	return $cmimi+$cmimi*$tvsh/100;	
10 	}
11 ?>

Këtu, funksionit nuk ia kemi përcjellur fare çmimin me përdorimin e ndonjë argument, e kemi përcjellë vetëm vlerën e TVSH-së (16). Funksioni e merr vlerën e variablit $cmimi nga skripta, sepse është shënuar global $cmimi, pra $cmimi është deklaruar si variabël globale. Pas llogaritjes me formulën $cmimi+$cmimi*$tvsh/100, funksioni me return e kthen atë vlerë, dhe echo-ja e dytë në skriptë e “printon”, duke e dhënë vlerën e re (116).

Nëse vlera e variablit global $cmimi ndryshohet brenda funksionit, edhe skripta do të ketë qasje në atë vlerë të re.

 1 <?php
 2 $cmimi = 100;
 3 echo "<p>[Skripta] Cmimi pa TVSH:".$cmimi;
 4 echo "<p>[Funksioni] Cmimi me TVSH:".trego_cmimin(16);
 5 echo "<p>[Skripta] Cmimi pa TVSH:".$cmimi;
 6  
 7  
 8  function trego_cmimin($tvsh)
 9  	{
10 	global $cmimi;
11 	$cmimi = $cmimi+$cmimi*$tvsh/100;
12 	return $cmimi;	
13 	}
14 ?>

Rezultati: ``` [Skripta] Cmimi pa TVSH:100

[Funksioni] Cmimi me TVSH:116

[Skripta] Cmimi pa TVSH:116 ```

Në rreshtin e tretë shohim se edhe skripta është duke e parë vlerën e ndryshuar të variablit $cmimi.