Un script PHP este în esență o înşiruire de instrucţiuni. Instrucţiunile pot fi de mai multe feluri: atribuiri, apeluri de funcţii, structuri de control sau chiar instrucţiunea vidă. Aceste instrucţiuni sunt delimitate la finalul lor de către semnul punct şi virgulă. Totodată ele pot fi grupate într-o singură instrucţiune compusă, care la rândul ei devine o instrucţiune de sine stătătoare, înglobând mai multe instrucţiuni simple între două acolade.

Decizia

În crearea unui script, sau în general a oricărui program, vă veți întâlni cam în 100% din cazuri cu luatul de decizii. Sau mai bine zis cu scris cod care să ia decizii pe loc în momentul rulării aplicaţiei respective. Deşi rudimentară, este una din tehnicile de bază în programare (alături de iteraţie), fără de care probabil programarea dacă ar fi existat ar fi fost o meserie destul de greoaie. Se bazează pe faptul că în timpul execuţiei se poate dori execuţia unor anume instrucţinui în detrimentul altora în funcţie de, să zicem, nişte parametrii proveniţi de la utilizatori, deci de a lua o decizie: ce instrucţiune, sau set de instrucţiuni, să execut? Există două structuri de control care vă pot ajuta în luarea acestor decizii: if şi switch.

Instrucțiunea IF-ELSE-ELSEIF este o instrucţiune întâlnită în majoritatea limbajelor de programare şi mai este întâlnită sub denumirea de instrucţiunea decizională simplă. Astfel aceasta dă posibilitatea de a alege dintre două sau mai multe posibilităţi de execuţie a codului, folosind-se de niște condiţii testate în prealabil. Formatul general al acesteia este:


if ()

[elseif ()

elseif ()

else
]

Efectul acestei instrucţiuni este următorul: se evaluează condiţia din cadrul ramurei if, dacă aceasta are valoare logică de TRUE, atunci se execută instrucţiunea imediat următoare. În caz contrar se trece la prima ramură elseif(dacă există) testându-se condiţia şi executându-se instrucţiunea corespunzătoare în caz ca aceasta se evaluează la TRUE. Procesul continuă pentru toate ramurile elseif până când sunt terminate sau până la prima condiţie evaluată la TRUE. În caz ca nici una nu va fi găsită TRUE, se va executa instrucţiunea de pe ramura else, dacă există. De remarcat este faptul că se pot defini oricât de multe ramuri elseif şi doar una if sau else, şi că evaluarea la TRUE a unei condiţii face ca execuția să iasă din această structură de control. Totodată trebuie menţionat că oricare din ramurile definite suportă în corpul lor o singură instrucţiune; în cazul în care se dorește execuţia mai multor instrucțiuni acestea se pot grupa într-o instrucțiune compusă. Iată nişte exemple, pur didactice:


$number = 27;
if ($number % 2 == 0)
echo "Numarul este par";
else
echo "Numarul este impar";
/*
structura care foloseste si elseif
*/
if ($number % 3 == 0)
echo "Numarul este divizibil cu 3";
elseif ($number % 3 == 1)
echo "Numarul nu este divizibil cu 3, restul impartirii este 1";
else
echo "Numarul nu este divizibil cu 3, restul impartirii este 2";

În cazul în care o instrucțiune IF ar conține multe ramuri elseif, scrierea lor ar putea deveni greoaie, precum citirea şi înțelegerea lor. De aceea PHP dispune şi de o instrucțiune decizională multiplă: SWITCH. Switch are avantajul că permite testarea unei variabile, sau a unei aceleiași expresii cu mai multe valori şi să execute o serie de instrucțiuni în caz că acesta ar fi egal cu una din valorile conținute în ramurile case.


switch ()
{
case var1:
instructiune1;
[break;]
[case var2:
instructiune2;
[break;]
case varn:
instructiunen;
[break;]]
[default:
instructiune;]
}

Iată şi un exemplu concret:


$number = 27;
switch ($number % 3)
{
case 0:
echo "Numarul este divizibil cu 3";
break;
case 1:
echo "Numarul nu este divizibil cu 3, restul impartirii este 1";
break;
case 2:
echo "Numarul nu este divizibil cu 3, restul impartirii este 2";
break;
}

Spre deosebire de lanțul de if-uri care se pot forma, instrucțiunea switch este mult mai robustă, atât prin modul de scriere dar şi prin modul de lucru. Diferă de instrucțiunea if prin faptul ca expresia este evaluată o singură dată la început şi apoi este verificată cu toate valorile întâlnite în ramurile case până când acestea corespund. Poate exista și o ramură default, care va fi executată când nici una din valorile din case nu corespund cu valoarea evaluată. Instrucțiunea break este folosită pentru a evita executarea mai multor ramuri în cazul în care o valoarea expresiei evaluate este întâlnită în una din ramurile case. Considerăm următorul exemplu:


switch ($number % 3)
{
case 0:
echo "Numarul este divizibil cu 3";
case 1:
echo "Numarul nu este divizibil cu 3, restul impartirii este 1";
case 2:
echo "Numarul nu este divizibil cu 3, restul impartirii este 2";
}

Deşi cu valoarea nulă în practică, exemplul de mai sus dacă v-a primi un număr divizibil cu zero si va afişa mesajele (sau executa intrucţiunile) de pe toate ramurile existente sub prima ramură până când va întâlni o instrucţiune break, sau, cum e şi cazul nostru, până la finalul structurii. Totuşi, un exemplu carea ar avea ceva logică şi care ar scoate în evidenţă lipsa folosirii de break, ar fi următorul:


switch ($number % 3)
{
case 0:
echo "Numarul este divizibil cu 3";
break;
case 1:
case 2:
echo "Numarul nu este divizibil cu 3";
}

În caz că expresia se va evalua la valoarea 1 scriptul va executa instrucţiunile din ramura cu valoarea 1 (in cazul nostru nici unul) şi instrucţiunile din ramura cu valoarea 2. Procesul ar fi continuat dacă ar fi existat şi alte ramuri.

Iteraţia

Iterația este procedura de repetare a unui set de aceleaşi instrucţiuni în anumite condiţii. Astfel aceste structuri de control pot fi folosite de regulă pentru a aplica acelaşi tratament asupra unui set de date, sau chiar pe o singură informaţie, până când se obţine un rezultat dorit. Cele mai uzuale instrucţiuni iterative sunt while, do-while, for, foreach.


while ()
;

do
{
;
} while ();

Ambele structuri au rolul de a executa instrucţiunile din corpul lor până când expresiile respective ajung la valoarea TRUE. Diferenţa esenţială dintre ele este ca in cazul structurii while expresia este evaluată înainte ca orice iteraţie să aibă loc, deci corpul structurii while poate să nu fie executat niciodată, pe când în cazul instrucţiunii do-while expresia este evaluată după prima iteraţie, deci numărul minim de cicluri efectuate este de unu. Asemeni instrucţiunii decizionale simple, şi instrucţiunile iterative suportă în corpul lor doar execuţia unei singuri instrucţiuni, executarea mai mult instrucţiuni se face prin gruparea lor în una compusă.


/*
codul va afisa toate numerele de la 0 la 9
valoarea cu care $i va iesi din ciclu este 10
*/
$i = 0;
do {
echo $i;
$i++;
} while ($i < 10);
/*
codul următor are același efect cu cel de mai sus
*/
$i = 0;
while ($i < 10)
{
echo $i;
$i++;
}

În ambele cazuri, în instrucţiunile ce alcătuiesc corpul structurii, trebuie avută în vedere modificarea variabilei, sau a expresiei, care face scopul acelei expresiei, astfel se poate genera o bulcă infinită, buclă care nu se va termina într-un număr finit de paşi, ducând la o execuţie infinită a scriptului. In cazul celor doua exemple de mai sus, presupunem ca din corpul structurilor am scoate instrucţiunile de incrementare ale lui $i; acest lucru ar face ca valoarea lui $i să rămână tot timpul 0, deci mai mică decât 10, deci condiţia valabilă în orice iteraţie. Astfel de cazuri trebuiesc evitate.

Instrucţiunile for si foreach sunt tot instrucţiuni repetitive şi sunt considerate cele mai complexe structuri iterative din cadrul limbajului PHP.


for (expr-initiere; expr-testare; expr-iterare)
instructiune;

Modul de funcţionare al acestei structuri este următorul: la prima intrarea în structura se va executa necondiţionat expresia expr-initiere, care de regulă va conţine instrucţiuni de iniţializare de variabile ce vor fi folosite în interiorul for-ului. În continuare, la fiecare iteraţie se va evalua expr-testare, al cărui rezultat va decide dacă instrucţiunea din corpul for-ului va fi executată sau nu. În caz că expresia va fi evaluată la valoarea FALSE, instrucţiunea nu va fi evaluată iar execuţia programului va ieşi din această structură. În cazul evaluării la TRUE, corpul structurii va fi executat, iar la finalul acestuia se va executa şi expr-iterare. Ca şi în cazurile precedente, executarea mai multor instrucţiuni presupune gruparea lor într-una compusă şi aceeaşi atenţie trebuie acordată evitării de bucle infinite. Complexitatea aceste structuri constă în faptul că oricare din cele 3 expresii pot lipsi, dându-se astfel o mai mare libertate programatorului în controlul acestei structuri.

Structura foreach este o structură introdusă din versiunea 4 a PHP şi este creată special pentru a itera prin elementele unui vector şi poate fi folosită în 2 moduri:


foreach ($array as $valoare)

foreach ($array as $index => $valoare)

Prima variantă de utilizarea va extrage fiecare element al vectorului la fiecare iteraţie în interiorul variabilei $valoare, pe când ce-l de-al doilea exemplu va separa indexul de valoarea elementului în cele 2 valori. Micul neajuns al acestei structuri este acela că iteraţia se face pe o copie a vectorului, deci orice modificare asupra $index sau $valoare nu va avea efect în vectorul care se iterează.

Întreruperea şi continuarea

Break şi continue sunt două instrucţiuni cu care se pot controla toate structurile iterative în sensul opririi sau continuării execuţiei de la începutul buclei. Astfel, o instrucţiune break va determina ieşirea dintr-o structură repetitivă a execuţiei, pe când continue va determina întoarcerea la începutul buclei, evaluarea expresiei de testare (dacă este cazul) şi reluarea execuţiei.


for ($i = 0; $i < 10; $i++)
{
if ($i == 5)
continue;

echo $i . ',';

if ($i == 7 )
break;
}

Exemplul precedent va afişa numerele 0, 1, 2, 3, 4, 6, 7. În interiorul structurii for la atingerea valorii 5 a lui $i se va executa instrucţiunea continue care va muta execuţia la incrementarea lui $i, şi apoi la execuţia următorului ciclu. La întâlnirea lui 7, deşi va fi afişat, execuţia va paraşi structura for, datorită instrucţiunii break. Un exemplu mult mai practic de folosirea a lui break este acela în care se dispune de un set de date (numere de exemplu), şi se doreşte aflarea dacă un număr oarecare se află în acel set de date. Metoda cea mai simplă şi rudimentară este căutarea secvenţială, în care fiecare element al setului de date este comparat cu acea valoare, până când cele 2 valori conicid sau până setul de date este temrinat. Îmbunătăţirea considerabilă ar fi ca în momentul în care elementul a fost găsit, scriptul ca nu caute în elementele rămase ci să printeze un mesaj şi să încheie execuţia.


$array = array(1,4,2,8,6,3,9,0);
$searchNo = 8;
foreach ($array as $element)
{
if ($searchNo == $element)
{
echo "Numarul cautat a fost gasit";
break;
}
}

De notat este că în cazul instrucţiunilor imbricate repetitive, apelul lui continue sau break va determina continuarea sau întreruperea primului ciclu repetitiv în care instucţiunea a fost apelată. Dacă de exemplu se doreşte iesirea şi din cel de-al doilea, sau al treilea ciclu imbricat, se poate folosi următoarea sintaxă:


break 2;

Aşadar, este recomandat ca după fiecare apel a lui break să nu uitaţi terminarea instrucţiunii cu un punct şi virgulă, în caz contrar, dacă după aceasta există o instrucţiune care să returneze sau să se evalueze la o valoarea numerică, această valoare va fi pasată instrucţiunii break, lucru care poate afecta logica scriptului.