Piotr Czapiewski Wydział Informatyki ZUT Wykład 2
$this – wskazuje na bieżący obiekt
W ciele metody – użycie $this jest konieczne $this->nazwa – pole klasy $nazwa – zmienna lokalna Wynik: hau hau Wynik: hau hau Wynik: Wynik:
W metodzie statycznej – odnosi się do obiektu wołającego
Przypisanie istniejącego obiektu do nowej zmiennej Nowa zmienna będzie odnosić się do tej samej instancji object(Zwierze)#1 (2) { ["gatunek"]=> string(4) "pies" ["odglos"]=> NULL }object(Zwierze)#1 (2) { ["gatunek"]=> string(4) "pies" ["odglos"]=> string(7) "hau hau" }object(Zwierze)#1 (2) { ["gatunek"]=> string(4) "pies" ["odglos"]=> NULL }object(Zwierze)#1 (2) { ["gatunek"]=> string(4) "pies" ["odglos"]=> string(7) "hau hau" }
Trzy warianty: Przypisanie Referencja Klonowanie
Zwierze { gatunek : "pies" } Zwierze { gatunek : "pies" } $a $b $c $a = new Zwierze("pies"); $b = $a; $c = &$a;
Zwierze { gatunek : "żyrafa" } Zwierze { gatunek : "żyrafa" } $a $b $c $a = new Zwierze("pies"); $b = $a; $c = &$a; $b->gatunek = "żyrafa";
Zwierze { gatunek : "żyrafa" } Zwierze { gatunek : "żyrafa" } $a $b $c $a = new Zwierze("pies"); $b = $a; $c = &$a; $b->gatunek = "żyrafa"; $a = new Zwierze("kot"); Zwierze { gatunek : "kot" } Zwierze { gatunek : "kot" }
Zwierze { gatunek : "pies" } Zwierze { gatunek : "pies" } $a $b $c $a = new Zwierze("pies"); $b = $a; $c = &$a; $b->gatunek = "żyrafa"; $a = new Zwierze("kot"); $c = null;
$klon = clone $oryginal Kopia wszystkich właściwości obiektu Opcjonalnie: funkcja __clone() Zwierze { gatunek : "pies" } Zwierze { gatunek : "pies" } $a $b $a = new Zwierze("pies"); $b = clone $a; Zwierze { gatunek : "pies" } Zwierze { gatunek : "pies" }
Brak dziedziczenia wielorakiego Można nadpisać metody klasy bazowej Dostęp do nadpisanych metod klasy nadrzędnej – parent:: Nie można nadpisać metody zdefiniowanej jako final
var1 => value 1 var2 => value 2 var3 => value 3 var1 => value 1 var2 => value 2 var3 => value 3
var1 => value 1 var2 => value 2 var3 => value 3 MyClass::iterateVisible: var1 => value 1 var2 => value 2 var3 => value 3 prot => protected var priv => private var var1 => value 1 var2 => value 2 var3 => value 3 MyClass::iterateVisible: var1 => value 1 var2 => value 2 var3 => value 3 prot => protected var priv => private var
Standardowe funkcje i wyrażenia nie rzucają wyjątków Wynik:
Rozwiązanie: set_error_handler()
PHP Data Objects (PDO)
Biblioteki dedykowane Warstwy abstrakcji Mapowanie obiektowo-relacyjne
Różne DBMS = różne interfejsy MySQL, PostgreSQL, Oracle, Informix, DB2, Microsoft SQL Server, Firebird, Paradox, Sybase, SQLite… Sposób klasyczny: biblioteki dedykowane PHP Data Objects Różne DBMS = jeden interfejs Nie rozwiązuje problemu niezgodności wersji SQL Warstwa abstrakcji: PDO
$sql = 'SELECT * from ksiazki'; $result = $dbh->query($sql); foreach($result as $row) { $id = $row['id']; $tytul = $row['tytul']; $autor = $row['autor']; echo "{$autor}: {$tytul} "; } $sql = 'SELECT * from ksiazki'; $result = $dbh->query($sql); foreach($result as $row) { $id = $row['id']; $tytul = $row['tytul']; $autor = $row['autor']; echo "{$autor}: {$tytul} "; }
print_r($row); Array ( [id] => 2 [0] => 2 [tytul] => PHP dla opornych [1] => PHP dla opornych [autor] => Jan Kowalski [2] => Jan Kowalski [wydawnictwo] => 2 [3] => 2 ) Array ( [id] => 2 [0] => 2 [tytul] => PHP dla opornych [1] => PHP dla opornych [autor] => Jan Kowalski [2] => Jan Kowalski [wydawnictwo] => 2 [3] => 2 ) $id = $row['id']; $id = $row[0]; $t = $row['tytul']; $t = $row[1]; $id = $row['id']; $id = $row[0]; $t = $row['tytul']; $t = $row[1];
class Ksiazka { public $id; public $tytul; public $autor; public $wydawnictwo; } $statement = $dbh->query('SELECT * from ksiazki'); $ksiazki = $result->fetchAll(PDO::FETCH_CLASS, 'Ksiazka'); foreach($ksiazki as $k) { echo "{$k->autor}: {$k->tytul}\n"; } class Ksiazka { public $id; public $tytul; public $autor; public $wydawnictwo; } $statement = $dbh->query('SELECT * from ksiazki'); $ksiazki = $result->fetchAll(PDO::FETCH_CLASS, 'Ksiazka'); foreach($ksiazki as $k) { echo "{$k->autor}: {$k->tytul}\n"; }
Problem: Budujemy zapytanie na podstawie danych pobranych z żądania HTTP
Zwykłe połączenie jest zamykane po zakończeniu skryptu Połączenie trwałe jest zachowywane do późniejszego wykorzystania Poprawa wydajności Nie wpływa na funkcjonalność
Rozpoczęcie transakcji $dbh->beginTransaction(); Zatwierdzenie transakcji $dbh->commit(); Wycofanie transakcji $dbh->rollBack();
Tryby obsługi błędów w PDO Tryb cichy – PDO::ERRMODE_SILENT ▪ W razie wystąpienia błędu ustawiane są kody błędu w obiektach PDO ▪ Informacje o błędzie do pobrania za pomocą: PDO::errorCode(), PDO::errorInfo() Tryb ostrzeżeń – PDO::ERRMODE_WARNING ▪ Dodatkowo emitowane ostrzeżenie Tryb wyjątków – PDO::ERRMODE_EXCEPTION ▪ Rzucany jest wyjątek PDOException
Biblioteka Doctrine ORM
ORM – Object-Relational Mapping Odwzorowanie obiektów w aplikacji na tabele w bazie danych Operacje na obiektach dziedzinowych zamiast SQL Koncepcja ORM Doctrine ORM, Propel, Eloquent ORM, Biblioteki ORM dla PHP
ksiazki id tytul autor wydawnictwo wydawnictwa id nazwa
Konfiguracja Generowanie mapowania na podstawie istniejącej bazy danych Generowanie klas encji na podstawie mapowania doctrine.bat orm:convert:mapping --from-database xml config\xml doctrine.bat orm:generate:entities model bootstrap.php, cli-config.php
class Wydawnictwo { private $id; private $nazwa; public function getId() { return $this->id; } public function getNazwa() { return $this->nazwa; } public function setNazwa($nazwa) { $this->nazwa = $nazwa; return $this; } class Wydawnictwo { private $id; private $nazwa; public function getId() { return $this->id; } public function getNazwa() { return $this->nazwa; } public function setNazwa($nazwa) { $this->nazwa = $nazwa; return $this; }
class Ksiazka { private $id; private $tytul; private $autor; private $wydawnictwo; public function getTytul() { return $this->tytul; }... public function getWydawnictwo() { return $this->wydawnictwo; } public function setWydawnictwo(\Wydawnictwo $wydawnictwo = null) { $this->wydawnictwo = $wydawnictwo; return $this; } class Ksiazka { private $id; private $tytul; private $autor; private $wydawnictwo; public function getTytul() { return $this->tytul; }... public function getWydawnictwo() { return $this->wydawnictwo; } public function setWydawnictwo(\Wydawnictwo $wydawnictwo = null) { $this->wydawnictwo = $wydawnictwo; return $this; }
Zapytanie w języku DQL $dql = "SELECT b FROM Ksiazka b"; $query = $entityManager->createQuery($dql); $ksiazki = $query->getResult(); foreach ($ksiazki as $k) { $id = $k->getId(); $tytul = $k->getTytul(); $nazwaWydawcy = $k->getWydawnictwo()->getNazwa(); echo "{$id}: {$nazwaWydawcy}; {$tytul}\n"; } $dql = "SELECT b FROM Ksiazka b"; $query = $entityManager->createQuery($dql); $ksiazki = $query->getResult(); foreach ($ksiazki as $k) { $id = $k->getId(); $tytul = $k->getTytul(); $nazwaWydawcy = $k->getWydawnictwo()->getNazwa(); echo "{$id}: {$nazwaWydawcy}; {$tytul}\n"; }
Edycja istniejącego obiektu $ksiazka1 = $entityManager->find('Ksiazka', 1); $ksiazka1->setTytul('Zmieniony tytul'); $entityManager->persist($ksiazka1); $entityManager->flush(); $ksiazka1 = $entityManager->find('Ksiazka', 1); $ksiazka1->setTytul('Zmieniony tytul'); $entityManager->persist($ksiazka1); $entityManager->flush();
Tworzenie nowego obiektu $nowaKsiazka = new Ksiazka(); $nowaKsiazka->setTytul('Testowy tytul'); $nowaKsiazka->setAutor('Jan Kowalski'); $helion = $entityManager->find('Wydawnictwo', 2); $nowaKsiazka->setWydawnictwo($helion); $entityManager->persist($nowaKsiazka); $entityManager->flush(); $nowaKsiazka = new Ksiazka(); $nowaKsiazka->setTytul('Testowy tytul'); $nowaKsiazka->setAutor('Jan Kowalski'); $helion = $entityManager->find('Wydawnictwo', 2); $nowaKsiazka->setWydawnictwo($helion); $entityManager->persist($nowaKsiazka); $entityManager->flush();