Mapowanie relacyjno-obiektowe jest techniką programowania, w której dostęp do SQL-owej bazy danych jest zapewniany przez zestaw klas odpowiadających tabelom, relacjom i rekordom. Wstawianie, usuwanie czy wyszukiwanie rekordów wykonywane jest za pomocą obiektów. Rozwiązanie takie, choć wygodne, wymaga przygotowania szeregu klas i wielu metod. Zadanie to można zautomatyzować stosując Propel.
Mapowanie relacyjno-obiektowe
Mapowanie relacyjno-obiektowe (ORM, ang. object-relational mapping) jest techniką programowania, która polega na organizacji dostępu do bazy danych za pomocą zestawu klas i obiektów. Rozwiązaniem takim są m.in. aktywne rekordy.
Taka technika programowania wyodrębnia w aplikacji nową warstwę: zestaw klas realizujących mapowanie relacyjno-obiektowe. Z jednej strony jest to rozwiązanie bardzo wygodne – kod aplikacji znacznie się upraszcza, nie pojawiają się w nim takie szczegóły jak zapytania SQL czy sprawdzanie wyników zapytań, a wyłącznie wywołania metod obiektów. Jednak nie odbywa się to bez dodatkowego nakładu pracy – przygotowania klas aktywnych rekordów.
Z pomocą przychodzi Propel – narzędzie do automatycznego generowania kodu PHP5 zapewniającego obiektowy interfejs dostępu do relacyjnej bazy danych. Pomaga on zautomatyzować proces generowania klas aktywnych rekordów.
Czym jest Propel?
Propel jest zestawem narzędzi i bibliotek automatyzujących proces przygotowywania klas aktywnych rekordów. Został napisany w PHP i składa się z dwóch części: generatora oraz zestawu bibliotek.
Generator jest aplikacją konsolową, która na podstawie pliku XML opisującego strukturę bazy danych oraz dodatkowych plików konfiguracyjnych automatycznie generuje zestaw klas PHP5 aktywnych rekordów, skrypt SQL tworzący bazę danych o zadanej strukturze oraz plik konfiguracyjny.
Wygenerowane klasy możemy wykorzystywać w aplikacji, pod warunkiem że w systemie dostępne są bazowe klasy biblioteki Propel (tzw. środowisko runtime Propela). W ten sposób stosowanie metody aktywnych rekordów w aplikacji sprowadza się do przygotowania plików konfiguracyjnych dla generatora Propel oraz poznania interfejsu klas generowanych przez Propel. Zanim rozpoczniemy wykorzystywanie Propela, musimy oczywiście przebrnąć przez proces instalacji.
Instalacja aplikacji Propel w Windows XP
Propel swoje działanie opiera na:
- dostępności interpretatora PHP w konsoli,
- interfejsie dostępu do stosowanej bazy danych (np. MySQL) w PHP,
- bibliotece transformacji XSLT: php_xsl.dll,
- bibliotece Creole,
- aplikacji Phing,
- klasie Log biblioteki PEAR.
Najlepiej, jeśli wykorzystamy najnowszą wersję PHP – 5.2.1. Wówczas pozbędziemy się dwóch błędów: błędu CLI zgłaszanego przez aplikacje konsolowe PHP oraz problemu ze strefą czasową zgłaszanego przez Phing. Omówiony proces instalacji przetestowałem w systemie Windows XP.
PHP w wierszu poleceń
Jeśli w systemie jest zainstalowany interpretator PHP, to jego dostępność w wierszu poleceń wymaga jedynie dodania w środowisku ścieżki dostępu. Najpierw sprawdzamy czy interpretator PHP jest dostępny w wierszu poleceń. Uruchamiamy wiersz poleceń i wydajemy (w dowolnym folderze) polecenie php. Jeśli ujrzymy komunikat:
C:\>php
Nazwa \'php\' nie jest rozpoznawana jako polecenie wewnętrzne lub zewnętrzne, program wykonywalny lub plik wsadowy
oznacza to, że interpretator PHP nie jest dostępny w wierszu poleceń.
Wówczas przechodzimy do okna dialogowego Start / Ustawienia / Panel Sterowania / System, wybieramy zakładkę Zaawansowane i klikamy przycisk Zmienne środowiskowe. Przechodzimy do edycji zmiennej systemowej Path i dodajemy na końcu ścieżkę do interpretatora PHP. Zależnie od instalacji może to być np. C:\php.
Jeśli teraz uruchomimy ponownie wiersz poleceń i wydamy komendę php, to interpretator PHP będzie wykonywał wprowadzane komendy. Napiszemy prosty skrypt PHP:
C:\>php
^Z
Po czym zakończymy wprowadzanie danych naciskając przycisk F6 lub Ctrl+Z, zapisywany również jako ^Z (jest to odpowiednik uniksowego znaku końca pliku ^D). Ujrzymy wynik wykonania skryptu, czyli komunikat Witaj w konsoli, widoczny na rys. 5.
Biblioteka PEAR, klasa PEAR:Log
Jeśli dotychczas nie instalowaliśmy żadnych pakietów PEAR, to tworzymy w systemie folder C:\php\PEAR przeznaczony na klasy biblioteki PEAR. Rozpakowujemy pliki PEAR-1.4.11.tgz oraz Log-1.9.9.tgz. Wypakowaną zawartość kopiujemy (wraz z podfolderami) do folderu C:\php\PEAR w taki sposób, by w systemie pojawiły się pliki:
c:\php\PEAR\PEAR.php
c:\php\PEAR\Log.php
Modyfikujemy ścieżki dostępu. W pliku php.ini wpis:
include_path = \".;c:\php\smarty\libs\"
zastępujemy wpisem:
include_path = \".;c:\php\smarty\libs;c:\php\PEAR\"
Phing
Wypakowujemy plik phing-2.2.0.zip do folderu phing-2.2.0. Zmieniamy nazwę folderu phing-2.2.0 na phing i przenosimy go do folderu C:\php, tak by w systemie pojawił się plik C:\php\phing\bin\phing.bat.
W środowisku (Start / Ustawienia / Panel Sterowania / System / Zmienne środowiskowe / Zmienne systemowe) dodajemy na końcu zmiennej Path wpis:
C:\php\phing\bin
Zmieniamy ścieżki dostępu PHP. W pliku php.ini dodajemy:
include_path = \"...;c:\php\phing\classes;...\"
W wierszu poleceń wydajemy komendę phing. Powinien pojawić się komunikat:
C:\>phing
Buildfile: build.xml does not exist!
Creole
Wypakowujemy plik creole-1.1.0.zip do folderu creole-1.1.0 i zmieniamy jego nazwę na creole. Przenosimy folder creole do C:\php, tak by w systemie pojawił się plik C:\php\creole\classes\creole\creole.php. W ścieżkach dostępu (plik php. ini) dodajemy wpis:
include_path = \"...;c:\php\creole\classes;c:\php\creole\classes\jargon;...\"
Zwróćmy uwagę, że są to dwa osobne wpisy oddzielone znakiem średnika.
Propel
Wypakowujemy plik propel-1.2.0.zip do folderu propel-1.2.0.zip i zmieniamy jego nazwę na propel. Przenosimy folder propel do C:\php, tak by w systemie pojawił się plik C:\php\propel\generator\bin\propel-gen.bat. W php.ini dodajemy ścieżkę:
include_path = \"...;c:\php\propel\runtime\classes;...\"
oraz bibliotekę do obsługi XSL:
extension=php_xsl.dll
W środowisku dodajemy w zmiennej Path wpis:
C:\php\propel\generator\bin
Łączne zmiany środowiska i ścieżek dostępu
Powyższa procedura instalacyjna wymaga dodania w pliku php.ini następujących ścieżek:
c:\php\PEAR
c:\php\phing\classes
c:\php\creole\classes
c:\php\creole\classes\jargon
c:\php\propel\runtime\classes
Wpis include_path przyjmie zatem postać:
include_path = \"
.;
c:\php\smarty\libs;
c:\php\PEAR;
c:\php\phing\classes;
c:\php\creole\classes;
c:\php\creole\classes\jargon;
c:\php\propel\runtime\classes
\"
(W pliku konfiguracyjnym wpis ten należy zapisać w jednej długiej linijce bez spacji ani znaków złamania wiersza wewnątrz cudzysłowów.) Natomiast w środowisku należy dodać (na końcu) trzy wpisy:
C:\php
C:\php\phing\bin
C:\php\propel\generator\bin
oddzielone średnikami, czyli:
C:\php;C:\php\phing\bin;C:\php\propel\generator\bin
Restartujemy teraz serwer Apache. Przy restarcie nie powinniśmy ujrzeć żadnego komunikatu o błędzie.
Test poprawności instalacji
Poprawność instalacji stwierdzimy wywołując w wierszu poleceń komendy:
php
phing
propel-gen
Jeśli wywołanie tych komend (w dowolnym folderze) powiedzie się (czyli: ujrzymy komunikat inny niż „Nazwa 'xxxxx’ nie jest rozpoznawana…”), oznacza to, że Propel jest zainstalowany i gotowy do pracy.
Przykład praktyczny
Jako przykład omówię aplikację prezentującą wiersze poetów. Baza danych będzie zawierała dwie tabele: poeta oraz wiersz połączone relacją jeden do wielu. W tabeli poeta będą umieszczone nazwiska poetów, zaś w tabeli wiersz – wiersze (tytuł, treść oraz klucz obcy identyfikujący autora w tabeli poeta).
Na witrynie WWW będą dostępne podstrony:
- zestawienie wszystkich poetów,
- zestawienie wszystkich wierszy,
- zestawienie wierszy wybranego poety,
- treść wybranego wiersza.
Dane do generowania aktywnych rekordów
Pracę nad aplikacją rozpoczynamy od wygenerowania klas aktywnych rekordów. W tym celu należy przygotować pliki konfiguracyjne, na bazie których Propel wygeneruje odpowiednie klasy. Plikami tymi są:
- schema.xml – plik opisujący strukturę bazy danych (czyli wszystkie tabele, pola, relacje oraz ograniczenia),
- build.properties – plik konfiguracyjny generatora klas,
- runtime-conf.xml – plik z konfiguracją dostępu do bazy danych dla generowanych klas aktywnych rekordów.
Struktura bazy danych
Plik schema.xml opisuje strukturę bazy danych. Jest to plik w języku XML zawierający elementy takie jak: database, table, column, unique, unique-column, foreign-key, reference
Przy użyciu tych elementów należy przedstawić strukturę bazy danych. Na listingu 1 widać zarys całego pliku. Zawiera on element database oraz elementy table (jeden element table dla każdej tabeli bazy danych).
...
...
Każda z tabel jest opisana przez szereg elementów column wraz z ewentualnymi ograniczeniami. Na listingu 2 przedstawiona została tabela poeta. Oprócz definicji kolumn elementami column znajdziemy tam wymuszenie unikalności pól elementami unique oraz unique-column.
Natomiast listing 3 ilustruje metodę definiowania relacji jeden do wielu. W tabeli wiersz pojawia się klucz obcy foreign-key odwołujący się do tabeli poeta.
Konfiguracja generatora
Konfigurując generator musimy podać nazwę oprogramowania zarządzającego bazą. W poniższym przykładzie użyty jest serwer mysql. Mówi o tym wpis propel.database. Ponadto musimy podać ustawienia dostępu do serwera (wpis propel.database.url). Plik build.properties jest przedstawiony na listingu 4.
propel.project = poetawiersz
propel.database = mysql
propel.database.url = mysqli://pwadm:secretpass@localhost/poetawiersz
propel.targetPackage = poetawiersz
Konfiguracja runtime
Ostatnim z wymaganych plików jest runtime-conf.xml. Zawiera on dane, na podstawie których wygenerowane klasy aktywnych rekordów będą łączyły się z bazą danych. Plik ten jest przedstawiony na listingu 5.
mysql
mysqli
localhost
poetawiersz
pwadm
secretpass
Generowanie
Trzy pliki konfiguracyjne, a więc schema.xml, build.properties oraz runtime-conf.xml umieszczamy w jednym folderze, na przykład D:\bd\poeci.
Aby wygenerować kod PHP należy w konsoli wydać ciąg poleceń:
c:
cd \
cd php\propel\generator\bin
propel-gen.bat d:\bd\poeci
Najwygodniej polecenia te zapisać w pliku generuj.bat. Plik ten umieszczamy w folderze D:\ bd\poeci. Jeśli stosujemy PHP 5.1 i podczas generowania otrzymujemy komunikat o błędnym ustawieniu strefy czasowej (Propel nie generuje wówczas pliku poetawiersz-conf.php), to problem ten rozwiążemy dodając jako pierwszą linijkę pliku generuj.bat wpis:
set TZ=\"Europe/Paris\"
Wygenerowane pliki
Po uruchomieniu generatora w folderze D:\bd\poeci pojawi się folder build. W folderze tym znajdziemy podfoldery:
- classes – zawiera kod PHP aktywnych rekordów,
- conf – zawiera plik konfiguracyjny poetawiersz-conf.php, który jest wymagany przez skrypty PHP stosujące wygenerowane klasy,
- sql – zawiera skrypt schema.sql tworzący tabele bazy danych.
Przykładowa baza danych zawiera dwie tabele. Wygenerowane zostaną cztery klasy pozwalające na łatwy dostęp do bazy danych:
- klasa Poeta (plik build/poetawiersz/Poeta.class.php),
- klasa PoetaPeer (plik build/poetawiersz/PoetaPeer.class.php),
- klasa Wiersz (plik build/poetawiersz/Wiersz.class.php),
- klasa WierszPeer (plik build/poetawiersz/WierszPeer.class.php).
oraz klasy: BasePoeta, BasePoetaPeer, BaseWiersz, BaseWierszPeer, PoetaMapBuilder, WierszMapBuilder (foldery map oraz om).
Tutorial
Gdy wygenerujemy klasy PHP, skrypt konfiguracyjny poetawiersz-conf.php oraz skrypt SQL, możemy przystąpić do pracy nad aplikacją. Najpierw musimy utworzyć bazę danych, następnie poznać podstawowe operacje na aktywnych rekordach, takie jak wstawianie do bazy czy wyszukiwanie, po czym możemy przystąpić do pracy nad samą aplikacją.
Przygotowując aplikacje stosujące aktywne rekordy będziesz wykonywać następujące operacje:
- wstawianie rekordu do bazy danych (konstrukcja nowego obiektu, ustalenie wartości pól metodami {stala}setXXX(){/stala}, np. {stala}setImie(){/stala}, {stala}setNazwisko(){/stala} oraz metoda zapisu w bazie danych: {stala}save(){/stala}),
- wyszukiwanie rekordu na podstawie klucza pierwotnego (metoda {stala}retrieveByPK(){/stala}),
- odczytanie rekordu z bazy danych (metoda {stala}retrieveByPK(){/stala} oraz metody dostępu do pól {stala}getXXXXX(){/stala}, np. {stala}getImie(){/stala}, {stala}getNazwisko(){/stala}),
- uaktualnienie rekordu w bazie danych ({stala}retrieveByPK(){/stala}, metody ustalania wartości pól {stala}setXXXXX(){/stala}, np. {stala}setImie(){/stala}, {stala}setNazwisko(){/stala} oraz zapisanie w bazie: metoda {stala}save(){/stala}),
- usuwanie rekordu (metoda {stala}delete(){/stala}),
- wyszukiwanie rekordu na podstawie różnych kryteriów (klasa Criteria, jej metoda {stala}add(){/stala} oraz metoda {stala}doSelect(){/stala}).
Tworzenie bazy danych
W celu utworzenia bazy danych przygotujemy skrypt poetawiersz.sql. Umieścimy w nim instrukcje SQL tworzące bazę danych poetawiersz oraz konto pwadm o haśle secretpass z prawami INSERT, DELETE, UPDATE, SELECT do wszystkich tabel bazy danych poetawiersz:
DROP DATABASE IF EXISTS poetawiersz;
CREATE DATABASE poetawiersz;
GRANT
INSERT, DELETE, UPDATE, SELECT
ON
poetawiersz.*
TO
pwadm@localhost
IDENTIFIED BY
\'secretpass\';
FLUSH PRIVILEGES;
USE poetawiersz;
Poniżej wklejamy zawartość skryptu schema.sql wygenerowanego przez Propel. Skrypt ten zawiera instrukcje SQL tworzące tabele poeta oraz wiersz.
Zwróćmy uwagę, że konto pwadm o haśle secretpass wykorzystaliśmy w plikach konfiguracyjnych Propel-a: build.properties oraz runtime-conf.xml. Tak przygotowany skrypt poetawiersz.sql możemy wykonać wydając w konsoli polecenie:
c:\mysql\bin\mysql -uroot -pAX1BY2CZ3 < poetawiersz.sql
AX1BY2CZ3 jest hasłem konta root serwera MySQL.
Jeśli umieścimy powyższą instrukcję w pliku poetawiersz.bat, wówczas będzie można utworzyć bazę danych podwójnym klinkięciem pliku poetawiersz.bat.
Wymagane pliki
Skrypty PHP wykorzystujące klasy wygenerowane przez aplikację Propel muszą zawierać instrukcje:
require_once \'propel/Propel.php\';
Propel::init(\'poetawiersz-conf.php\');
include_once \'poetawiersz/Poeta.php\';
include_once \'poetawiersz/Wiersz.php\';
Pierwsza z nich dołącza do skryptu ogólne biblioteki Propel (tzw. środowisko runtime). Uruchamianie aplikacji nie wymaga obecności plików schema.xml, build.properties oraz runtime-conf.xml, na podstawie których zostały wygenerowane klasy Poeta oraz Wiersz. Konieczna jest jedynie obecność środowiska runtime Propela.
Wstawianie rekordów
Wstawianie rekordów do bazy wykonamy wywołując metodę {stala}save(){/stala}. Najpierw tworzymy egzemplarz klasy Poeta, następnie ustalamy wartości pól wywołując metody {stala}setImie(){/stala} i {stala}setNazwisko(){/stala}, po czym zapisujemy rekord w bazie, wywołując metodę {stala}save(){/stala}:
$poeta = new Poeta();
$poeta->setImie(\'Adam\');
$poeta->setNazwisko(\'Mickiewicz\');
$poeta->save();
Wstawianie rekordów połączonych relacją
Jeśli wstawiane rekordy są połączone relacją, wówczas ustalając pola jednego z obiektów należy podać jako parametr inny obiekt. Najpierw tworzymy obiekt Poeta i przypisujemy mu właściwości. Następnie tworzymy obiekt Wiersz i również przypisujemy mu właściwości. Autora wiersza ustalamy przekazując do wywołania metody {stala}setPoeta(){/stala} obiekt klasy Poeta. Zapisanie w bazie danych wiersza spowoduje automatyczne zapisanie poety:
$poeta = new Poeta();
$poeta->setImie(\'Jan\');
$poeta->setNazwisko(\'Zielony\');
$wiersz = new Wiersz();
$wiersz->setTytul(\'Lorem\');
$wiersz->setTekst(\'Lorem ipsum dolor sit amet...\');
$wiersz->setPoeta($poeta);
$wiersz->save();
Wyszukanie rekordu o zadanym kluczu pierwotnym
Statyczne metody {stala}retrieveByPK(){/stala} klas WierszPeer oraz PoetaPeer służą do tworzenia obiektów na podstawie wartości klucza pierwotnego. Wartości pól odczytamy wywołując metody {stala}getImie(){/stala}, {stala}getNazwisko(){/stala} czy {stala}getTytul(){/stala}:
$wiersz = WierszPeer::retrieveByPK(173);
$poeta = PoetaPeer::retrieveByPK(13);
echo $poeta->getImie();
echo $wiersz->getTytul();
Wyszukanie poety o zadanym imieniu i nazwisku
Jeśli chcemy odnaleźć w bazie danych poetę o zadanym imieniu i nazwisku, to należy posłużyć się kryteriami. Najpierw tworzymy obiekt {stala}$kryteria{/stala}. Następnie ustalamy dane wyszukiwanego poety (w przykładzie: Juliusz Słowacki), po czym wywołujemy statyczną metodę {stala}doSelect(){/stala} klasy PoetaPeer. Zwrócony wynik jest tablicą obiektów klasy Poeta:
$kryteria = new Criteria;
$kryteria->add(
PoetaPeer::IMIE,
\'Juliusz\'
);
$kryteria->add(
PoetaPeer::NAZWISKO,
\'Słowacki\'
);
$poeci = PoetaPeer::doSelect($kryteria);
foreach ($poeci as $poeta) {
echo $poeta->getImie();
echo $poeta->getNazwisko();
}
Warunkowe wstawianie rekordu
Jeśli chcemy wstawić do bazy danych rekord, pod warunkiem, że takiego rekordu jeszcze w bazie nie ma, to wykorzystujemy wyszukiwanie. Najpierw znajdujemy rekordy odpowiadające podanym kryteriom. Następnie w zależności od liczby znalezionych rekordów albo tworzymy nowy obiekt, albo posługujemy się egzemplarzem zwróconym przez metodę {stala}doSelect(){/stala}:
$imie = \'Jan\';
$nazwisko = \'Zielony\';
$kryteria = new Criteria;
$kryteria->add(
PoetaPeer::IMIE,
$imie
);
$kryteria->add(
PoetaPeer::NAZWISKO,
$nazwisko
);
$autorzy = PoetaPeer::doSelect($kryteria);
if (count($autorzy) == 0) {
$poeta = new Poeta();
$poeta->setImie($imie);
$poeta->setNazwisko($nazwisko);
$poeta->save();
} elseif (count($autorzy) == 1) {
$poeta = $autorzy[0];
}e
cho $poeta->getImie();
echo $poeta->getNazwisko();
Po wykonaniu powyższego skryptu w bazie danych będzie znajdował się rekord Jan Zielony. Obiekt {stala}$poeta{/stala} będzie zapewniał dostęp do niego.
Wyświetlanie listy wszystkich rekordów
Wyznaczenie listy wszystkich rekordów sprowadza się do podania pustych kryteriów wyszukiwania. Do kryteriów takich pasują wszystkie rekordy w tabeli:
$kryteria = new Criteria;
$poeci = PoetaPeer::doSelect($kryteria);
foreach ($poeci as $poeta) {
echo $poeta->getNazwisko();
}
Wyświetlanie szczegółowych danych poety
Łącząc aktywne rekordy generowane przez Propela z szablonami Smarty należy do szablonu przekazywać obiekty. W skrypcie PHP należy utworzyć obiekt {stala}$poeta{/stala} i zsynchronizować jego zawartość z bazą danych, na przykład wywołując metodę {stala}retrieveByPK(){/stala}. Obiekt taki przekazujemy do szablonu metodą {stala}assign(){/stala}. Natomiast w szablonie dostęp do pól obiektu realizujemy wywołując metody {{stala}$poeta->getImie(){/stala}} czy {{stala}$poeta->getNazwisko(){/stala}}:
---skrypt.php---
$poeta = PoetaPeer::retrieveByPK(3);
$s = new Smarty;
$s->assign(\'poeta\', $poeta);
$s->display(\'poeta.tpl\');
---poeta.tpl---
id: {$poeta->getPoetaId()}
imie: {$poeta->getImie()}
nazwisko: {$poeta->getNazwisko()}
Wyświetlanie listy poetów
Wynikiem wyszukiwania rekordów przez metodę {stala}doSelect(){/stala} jest tablica instancji klasy Poeta. Tablicę {stala}$poeci{/stala} przekazujemy do szablonu metodą {stala}assign(){/stala}, po czym przetwarzamy w szablonie pętlą section:
---skrypt.php---
$kryteria = new Criteria;
$poeci = PoetaPeer::doSelect($kryteria);
$s = new Smarty;
$s->assign(\'poeci\', $poeci);
$s->display(\'poeci.tpl\');
---poeci.tpl---
{section name=i loop=$poeci}
{$poeci[i]->getPoetaId()}
{$poeci[i]->getImie()}
{$poeci[i]->getNazwisko()}
{/section}
Kaskadowe odwołania
Ostatnim aspektem użycia klas Propela w przykładowej aplikacji są odwołania kaskadowe. Wyświetlając dane wiersza (czyli tytuł i tekst) warto dołączyć dane autora. Informacje takie nie są dostępne w obiekcie klasy Wiersz. Należy więc w klasie Wiersz zdefiniować własne metody dostępu, {stala}getPoetaImie(){/stala} oraz {stala}getPoetaNazwisko(){/stala}:
class Wiersz extends BaseWiersz {
...
public function getPoetaImie()
{
$tmp = $this->getPoeta();
if ($tmp) {
return $tmp->getImie();
} else {
return \'\';
}
}
...
}
Metody te możemy wywoływać zarówno w skrypcie PHP, jak i w szablonie Smarty, podobnie jak standardowe metody dostępu do pól:
$wiersz = WierszPeer::retrieveByPK(3);
echo $wiersz->getPoetaImie();
echo $wiersz->getPoetaNazwisko();
echo $wiersz->getTytul();
echo $wiersz->getTekst();
Modyfikowanie istniejącego rekordu
Jeśli chcemy zmodyfikować rekord, który już jest zapisany w bazie, wówczas najpierw tworzymy obiekt odwołujący się do danego rekordu, stosując np. metodę {stala}retrieveByPK(){/stala}. Następnie modyfikujemy dowolne właściwości obiektu, po czym zapisujemy rekord w bazie wywołując metodę {stala}save(){/stala}:
$poeta = PoetaPeer::retrieveByPK(1);
$poeta->setImie(\'Tomasz\');
$poeta->save();
Usuwanie rekordu
W celu usunięcia rekordu tworzymy obiekt odwołujący się do niego, po czym wywołujemy metodę {stala}delete(){/stala}:
$poeta = PoetaPeer::retrieveByPK(1);
$poeta->delete();
Aplikacja: wiersze/poeci
Przykładowa aplikacja jest wykonana w czterech krokach. Najpierw należy zdefiniować strukturę bazy danych i przy użyciu Propela wygenerować skrypt SQL tworzący tabele oraz niezbędne klasy. Następnie przygotowujemy skrypt SQL, który utworzy pustą bazę danych. W kroku trzecim przygotowujemy skrypt wstaw-rekordy.php. Skrypt ten ma - przy użyciu klas Poeta i Wiersz wygenerowanych przez Propela - wstawić do bazy danych zawartość pochodzącą z plików tekstowych. Zarys skryptu jest widoczny na listingu 6.
$p = glob(\'dane/*.txt\');
$pc = count($p);
for ($i = 0; $i < $pc; $i++) {
$wiersz = file($p[$i]);
$autor = trim($wiersz[0]);
$tytul = trim($wiersz[1]);
$wiersz[0] = \'\';
$wiersz[1] = \'\';
$tekst = trim(implode(\'\', $wiersz));
$l = split(\' +\', $autor);
$imie = $l[0];
$nazwisko = $l[1];
$kryteria = new Criteria;
$kryteria->add(
PoetaPeer::IMIE,
$imie
);
$kryteria->add(
PoetaPeer::NAZWISKO,
$nazwisko
);
$poeci = PoetaPeer::doSelect($kryteria);
if (count($poeci) == 0) {
$poeta = new Poeta();
$poeta->setImie($imie);
$poeta->setNazwisko($nazwisko);
} elseif (count($poeci) == 1) {
$poeta = $poeci[0];
}
$wiersz = new Wiersz();
$wiersz->setTytul($tytul);
$wiersz->setTekst($tekst);
$wiersz->setPoeta($poeta);
$wiersz->save();
}
Ostatnim krokiem jest sama aplikacja. Jej kod sprowadza się do instrukcji switch, która ma pięć przypadków:
- strona błędu,
- lista wszystkich poetów,
- lista wszystkich wierszy,
- konkretny wiersz,
- wiersze wybranego poety.
Szkielet aplikacji został przedstawiony na listingu 7.
switch ($numer) {
case 1:
break;
case 2:
$kryteria = new Criteria;
$poeci = PoetaPeer::doSelect($kryteria);
$s->assign(\'poeci\', $poeci);
break;
case 3:
$kryteria = new Criteria;
$wiersze = WierszPeer::doSelect($kryteria);
$s->assign(\'wiersze\', $wiersze);
break;
case 4:
$wiersz = WierszPeer::retrieveByPK($_GET[\'id2\']);
$s->assign(\'wiersz\', $wiersz);
break;
case 5:
$poeta = PoetaPeer::retrieveByPK($_GET[\'id2\']);
$kryteria = new Criteria;
$kryteria->Add(
WierszPeer::POETA_ID,
$_GET[\'id2\']
);
$wiersze = WierszPeer::doSelect($kryteria);
$s->assign(\'poeta\', $poeta);
$s->assign(\'wiersze\', $wiersze);
break;
}
$s->assign(\'numer\', $numer);
$s->display(\'index.tpl\');