Laborator 2. Accesul si folosirea bazei de date in PHP

Responsabil: Popovici Matei pdmatei@gmail.com

Data publicarii: 28-02-2009

Data ultimei modificari: 02-03-2009

Obiective:

- familiarizarea cu limbajul PHP 5 si mecanismele OO (Object Oriented)

- "prepared statements" in PHP 5

- mecanisme de conectare la o baza de date MySQL, in PHP 5

Prezentarea laboratorului:

1. Clase

Clasele in PHP (versiunea 5) sunt foarte asemanatoare cu cele din JAVA. PHP suporta mostenire (ca si in JAVA, in PHP nu ofera suport pentru mostenire multipla, altfel spus o clasa copil nu poate mosteni decat o singura clasa parinte). De asemenea, in PHP se pot defini clase abstracte, interfete, metode statice. PHP suporta polimorfismul si supraincarcarea. Pentru mai multe detalii legate de Clase si Obiecte in PHP 5, consultati: http://us2.php.net/oop

Exemplu de clasa in PHP 5:

class Example {

private $id;

public $string;

public function display ()

{

echo $string;

}

}

Constructorii se pot declara folosind doua modalitati in PHP 5:

class Example {

private $id;

public $string;

public function Example ($id, $string)

{

}

}

Aceasta varianta este perfect asemanatoare cu declararea unui constructor in Java. Pe langa aceasta mai exista si varianta:

class Example {

private $id;

public $string;

public function __construct($id, $string)

{

}

}

Aceasta varianta foloseste cuvantul-cheie “__construct”. Avantajele acestei metode sunt legate de numele clasei. “__construct” pune in evidenta aspectul comportamental al metodei (si face pereche cu metoda “__destruct”). In plus, daca se doreste redeumirea clasei, acest lucru nu va afecta codul interior – constructorul nu va trebui modificat.

Spre deosebire de PHP 4, unde obiectele erau transmise prin valoare, in PHP 5, acestea sunt transmise prin referinta. De asemenea, vizibilitatea in interiorul unei clase prezinta cateva particularitati; Exemplul urmator arata modalitatea corecta de accesare a membrilor unei clase:

class Example {

private $id;

public $string;

public function __construct($id, $string)

{

$this->id = $id;

$this->string = $string;

}

}

Membrii unei clase nu se pot apela direct; spre exemplu folosirea lui $string in interiorul constructorului de mai sus este echivalenta cu declararea unei variabile locale cu numele $string, diferita de membrul clasei $this->string;

In PHP 5 se pot defini si apela metode statice astfel:

class Example {

public static function foo ()

{

}

}

Example::foo();

2. Conectarea la baza de date

2.1. Prepared statements

Pentru conectarea la baza de date MySQL, in PHP 5 pune la dispozitie clasele mysqli si mysqli-stmt. Exemplul urmator arata modalitatea de conectare la o baza de date. Presupunem ca baza de date are un tabel cu urmatoarea structura:


users

id

username

description

1

mihai

Mihai’s description


1. $id = 1;


2. $connection = new mysqli(‘localhost’,’username’,’password’,’database-name’);

3. $query = “SELECT * from users where id = ?”;

4. $stmt = $connection->prepare($query);


5. $stmt->bind_param(“i”,$id);

6. $stmt->execute();


7. $stmt->bind_result($id,$username,$description);

8. $stmt->fetch();


9. $stmt->close();

10. $db->close();


11. echo $id;

12. echo $username;

13. echo $description;

La linia 2, se creeaza un obiect mysqli - conexiunea la baza de date. Parametrii uzuali sunt adresa (folosim deseori localhost, intrucat baza de date se afla local in raport cu serverul care ruleaza codul PHP), username-ul si parola asociate unui utilizator al bazei de date (crearea unui utilizator si adaugarea de drepturi acestuia pentru accesul la o baza de date, se realizeaza din interfata de administrare MySQL).

Linia 3 formateaza un query catre baza de date. Se observa ca acest query contine (unul sau mai multe) simboluri ?. Acestea vor fi inlocuite cu valori de variabile, dupa cum vedem in continuare;

Linia 4 creeaza un prepared statement;

Linia 5 atribuie prepared statement-ului creat, valorile variabilelor. Mecanismul este urmatorul: primul parametru contine un string cu unul sau mai multe caractere. Fiecare caracter desemneaza tipul variabilei de inlocuit. Urmatorii parametrii (in exemplul nostru exista doar unul) sunt variabilele ce vor fi "inlocuite" cu ?.

Altfel spus, apelul din linia 5, inlocuieste simbolul ? din query cu o variabila de tip integer (de unde "i"), al carui continut este $id.

Linia 6 executa query-ul obtinut prin inlocuirea variabilelor.

Linia 7 asociaza campurile intoarse cu cele trei variabile - parametrii

Linia 8 executa preluarea efectiva a datelor (din acest moment, cele trei variabile contin valorile campurilor din baza de date)

Observatii:

- cand executarea unui query produce mai multe rezultate, apelul fetchva intoarce doar pe primul dintre ele; prin apeluri succesive ale fetch (pana cand nu mai exista rezultate), se pot obtine toate rezultatele unui query;

- desi prepared statement-urile par dificil de folosit la prima vedere, ele sunt utile in situatii in care dorim executarea de query-uri generice; ele sunt de asemenea utile in a garanta corectitudinea codului scris;


2.2. Query-uri simple


2. $connection = new mysqli(‘localhost’,’username’,’password’,’database-name’);

3. $query = “SELECT * from users where id = 1”;

4. $result = $connection->query($query);


5. while ($row = $result->fetch_assoc() )

6. {


7. echo $row["userId"];

8. }



La linia 2, se stabileste o conexiune, similar cu exemplul anterior;

Linia 3 creeaza un query simplu;

Linia 4 executa query-ul, si obtine un obiect result, ce contine rezultatele executarii query-ului;

Linia 5 parcurge inregistrare cu inregistrare, rezultatul intors. Metoda fetch_assoc intoarce un array asociativ ce contine drept chei numele coloanelor din tabel, iar drept valori, valoarile inregistrarii curente, asa cum se poate observa la linia 7.

Task-uri de rezolvat:

1. Scrieti o clasa care abstractizeaza operatiile de extragere, adaugare si modificare campuri pentru un Utilizator. Folositi clasa User, anexata ca resursa. Membrii clasei corespund campurilor din baza de date. Implementati:

- constructorul clasei (extrage campurile pentru un id dat, sau creeaza o clasa goala)

- metoda update: actualizeaza membrii clasei in baza de date

- metoda insert: primeste ca parametrii campurile tabelului, si creeaza o noua inregistrare in baza de date.

Folositi prepared statements.

Scrieti un script pentru testarea operatiilor clasei. Pentru testare, importati baza de date anexata la resurse.

5p

2. Adaugati clasei User o metoda statica ce cauta un utilizator dupa prenume, si il intoarce pe primul gasit. Metoda statica va intoarce un obiect de tip User.

5p


3. (Bonus 1) Scrieti o noua clasa MyObject (dupa modelul lui User) care realizeaza aceleasi operatii ca si User (extrage, updateaza si insereaza) insa pe o inregistrare generica (tabel cu orice structura, care insa contine un index 'id'). Folositi query-uri simple.

4p


Tips:

Pentru a obtine id-ul ultimei inregistrari inserate intr-un tabel, folositi:

$stmt->insert_id;

unde $stmt este un obiect mysqli_stmt ( prepared statement ) sau

$connection->insert_id;

unde $connection este un obiect mysqli

Pentru includerea unui fisier extern script-ului curent folositi require_once('nume-fisier')

Consultati www.php.net pentru informatii complete privind comportamentul functiilor descrise in laborator.