Przeglądarka bazy danych przy użyciu PHP-Gtk2.pdf
(
1072 KB
)
Pobierz
8140284 UNPDF
Dla zaawansowanych
Przeglądarka bazy danych
przy użyciu PHP-Gtk2
Christian Weiske
Stopień trudności:
lll
Bardzo mocną stroną PHP są wbudowane funk-
cje obsługi baz danych. Z kolei aplikacje okien-
kowe wiodą prym dzięki intuicyjnym interfej-
som, doskonale reagującym na działania użyt-
kownika. W tym artykule opiszemy, jak połączyć
zalety tych dwóch aspektów programistycznych,
budując przeglądarkę bazy danych, którą łatwo
będzie można udoskonalać oraz dostosowywać
do różnych systemów bazodanowych.
za danych” oraz “przeglądarka”,
na myśl przychodzi nam zazwy-
czaj phpMyAdmin lub podobne jemu na-
rzędzie. Wygląd (ang.
layout
) tych apli-
kacji jest w większości przypadków bar-
dzo do siebie zbliżony: w górnym lewym
rogu mamy menu rozwijane z możliwo-
ścią wyboru bazy danych, na której bę-
dziemy pracować, zaś poniżej wyświetla-
ne są jej tabele.
Cała zawartość prawej części apli-
kacji jest przeznaczona na wyświetla-
nie zawartości i struktury aktualnie za-
znaczonej tabeli. Często zawiera także
elementy nawigacyjne, pozwalające na
zmianę struktury, właściwości czy za-
wartości tabeli.
Ponieważ takie rozmieszczenie jest
popularne i dobrze znane większości
użytkowników, nasza przeglądarka ba-
zy danych będzie także miała taki wy-
gląd. Oto lista wszystkich funkcjonalno-
ści, które omówimy w ramach artykułu,
wraz z ich reprezentacją koloru w wido-
ku strukturalnym (patrz Rysunek 1):
• możliwość wyboru bazy danych z me-
nu rozwijanego (pomarańczowy),
• wyświetlanie nazw i ilości wierszy
tabel w zaznaczonej bazie danych
(zielony),
• wyświetlanie zawartości (wierszy) za-
znaczonej tabeli (ioletowy),
• numeracja i sortowanie, nawigacja
wierszy za pomocą przycisków w to-
olbarze (niebieski).
W SIECI
•
http://www.gnope.org
– pakiet PHP5 + Gtk2 dla
Windows,
•
http://gtk.php.net
– strona główna projektu
PHP-Gtk2 wraz
z repozytorium,
•
http://cweiske.de/iles/
download/phpgtk2/
DatabaseBrowser.tar.bz2
– pełen kod aplikacji
zbudowanej w tym artykule,
•
http://pear.php.net/package/
MDB2
– pakiet MDB2 dla PEAR,
•
http://pear.php.net/package/
Gtk2_ExceptionDump
– pakiet Gtk_ExceptionDump
dla PEAR,
•
http://pear.php.net/package/
Structures_Form_Gtk2
– pakiet Structures_Form_Gtk2
dla PEAR.
Co należy wiedzieć...
Przydatna będzie znajomość podstaw
PHP-Gtk oraz podstawowych zapytań
SQL.
Co obiecujemy...
Dowiesz się, jakie nowe funkcje przynosi
druga wersja PHP-Gtk. Zbudujesz prze-
glądarkę baz danych z funkcją sortowa-
nia i podziału na strony.
44
www.phpsolmag.org
PHP Solutions Nr 2/2007
S
łysząc kombinację słów „ba-
PHP-Gtk2 Dla zaawansowanych
Na Rysunku 1. pokazaliśmy, jakie wid-
gety GTK+ zostaną użyte oraz, w jaki
sposób będą zagnieżdżone.
Ponieważ
GtkWindow
może mieć
jedynie jeden element potomny, a my
potrzebujemy użyć kilku widgetów, sko-
rzystamy z
GtkContainer.
GtkHPaned
z kolei idealnie będzie pasował do na-
szych wymagań: dzieli bowiem okno
na dwie sekcje, których rozmiar może
zmieniać użytkownik.
Dla lewego panelu użyjemy kla-
sycznego
GtkVBox
, w którym zagnieź-
dzimy nasze rozwijane menu (
Gtk-
ComboBox
ze specjalnym
GtkListStore
funkcjonującym jako jego model), oraz
dla listy tabel – także
GtkTreeView
z odpowiednim
GtkListStore
jako mo-
delem.
Prawa strona naszej aplikacji jest
podobnie zamknięta w
GtkVBox
. Prze-
trzymujący element
GtkTreeView
, będzie
pokazywał wszystkie wiersze. Będzie
on także zawierał element
GtkToolbar
z
przyciskami nawigacyjnymi, usprawnia-
jącymi poruszanie się po liście: pierw-
sza i ostatnia strona, odśwież, następna
i ostatnia strona.
Kilka słów na temat stylu kodo-
wania i używania klas: z doświadcze-
nia wiem, że bardzo pomocne okazu-
je się rozszerzanie klas głównych wid-
getów Gtk, tworząc własne klasy i osa-
dzając je według kolejności zagnież-
dżenia. To może powiększyć ilość linii
kodu przy małych projektach, jednak
jest absolutnie niezbędne przy budo-
waniu wielkoskalowych projektów – in-
aczej szybko zgubimy się we własnym
kodzie. Ta metoda pozwala także na
łatwe przystosowanie kodu do ponow-
nego użycia, ponieważ wystarczy za-
łączyć klasę i zainicjować ją komendą
new MyClassName()
– bez porówna-
nia jest to mniej kodu, niż w przypad-
ku wycinania i kopiowania kodu każdej
funkcji (co z kolei utrudnia znalezienie
i korektę błędów).
Podłączamy się do bazy
Wykonanie połączenia do bazy danych,
używając MDB2 jest relatywnie proste:
wystarczy stworzyć cią DSN (ang.
Data
Source Name
), który odpowiada nasze-
mu środowisku, i wywołać metodę
sin-
gleton
klasy MDB2:
require_once 'MDB2.php';
$dsn = 'mysql://username:
password@hostname/databasename';
$mdb2 = MDB2::singleton($dsn, array());
Jeśli otrzymujesz błąd podobny do
"MDB2 Error: not found", prawdopo-
dobnie nie masz zainstalowanych odpo-
wiednich sterowników MDB2. Wystarczy
wykonać polecenie
pear install MDB2_
Driver_mysql
, by całość zaczęła działać
(należy zamienić “
mysql
” na nazwę na-
szego systemu bazodanowego).
Rysunek 1.
Struktura przeglądarki bazy danych
Rozprawiamy się z błędami
W przypadku dużego projektu, zaprzęgli-
byśmy do pracy wyjątki, sprawdzając, czy
zwracany obiekt w
$mdb2
to
PEAR_Error
i rzucalibyśmy wyjątek w przypadku praw-
dy. Ponieważ tego typu zabiegi są bardzo
kosztowne pod kątem np. czasu wykony-
wania, czy pisania aplikacji, użyjemy za-
let pakietu PEAR :
Gtk2_ExceptionDump
.
Tworzy on graiczny zrzut wszelkiego ro-
dzaju błędów: wyjątków, obiektów
PEAR_
Error,
kiedy zostaną utworzone oraz błę-
dów PHP, w przypadku ich pojawienia się
(patrz Rysunek 2).
Dobrą wiadomością jest, że ten skom-
plikowany z pozoru proces reprezentują w
kodzie zaledwie dwie linijki:
Wymagania
Przygotujmy najpierw nasze stanowisko. Niezbędne będą:
• PHP 5.1.x
• zainstalowany moduł PHP-Gtk2
• zainstalowany PEAR z pakietami MDB2 i Gtk2_ExceptionDump (
patrz ramka W Sieci
)
• dostęp do bazy danych
Ja wybrałem MDB2, ponieważ oferuje najłatwiejszy sposób dostępu do różnych typów baz
danych, w tym Oracle, DB2 i MySQL. Jeśli pracujesz w systemie Windows, polecam uży-
cie pakietu Gnope (patrz ramka “
W Sieci
”), który zawiera wszystkie niezbędne składniki,
pozwalające rozpocząć pracę z PHP5 i Gtk2. Jeśli używasz Linuxa lub Macintosha, powi-
nieneś pobrać PHP-Gtk2 Alpha (patrz ramka “W Sieci”) i skompilować go samodzielnie. W
manualu załączonym do pakietu znajdziesz instrukcję, jak przeprowadzić kompilację dla
obu systemów. Mamy już zainstalowane narzędzia pracy, możemy więc przejść do właści-
wego rzemiosła.
require_once 'Gtk2/ExceptionDump.php';
Gtk2_ExceptionDump::setupAllHandlers();
Nie musimy już martwić się o błędy i
możemy skupić się na programowaniu
funkcjonalności naszej aplikacji. Taki
PHP Solutions Nr 2/2007
www.phpsolmag.org
45
Dla zaawansowanych
PHP-Gtk2
Listing 1.
Kod klas wyświetlających bazy danych
zabieg jest bardzo przydatny przy two-
rzeniu prototypu aplikacji, jednak je-
śli zamierzasz rozprzestrzeniać swój
kod, powinieneś zaimplementować wła-
sny system obsługi błędów, by klient
otrzymywał bardziej przydatne i bar-
dziej czytelne informacje o ewentual-
nych błędach.
class
DatabaseBrowser_DatabaseList
extends
GtkListStore
{
public
function
__construct
()
{
parent::__construct
(
Gtk::TYPE_STRING
)
;
$this
-
>
loadDatabases
()
;
}
Wyświetlamy tabele
Pierwsze zapytanie SQL, jakiego bę-
dziemy używać, to naturalnie "
SHOW
DATABASES
". Jego wynikiem wypeł-
nimy
GtkComboBox
. By być przygoto-
wanym na wprowadzanie zmian i udo-
skonaleń w przyszłości, skorzystamy
z naszej własnej klasy, która będzie
rozszerzała
GtkListStore
. Widget ten
posiada jedynie jedną kolumnę typu
Gtk::TYPE_STRING
, która przechowu-
je nazwy dostępnych baz danych. Kod
klas zamieściliśmy na Listingu 1, wynik
jego działania widać na Rysunku 3.
GtkListStore
oferuje kilka metod do-
dawania wierszy. W tym przypadku za-
stosujemy
append()
, ponieważ jest dla
nas najłatwiejsza w użyciu. Pobiera
ona jako parametr tablicę, która powin-
na mieć tyle wartości, ile nasza lista ma
kolumn.
Zauważmy, że stosujemy obiekt pu-
bliczny
$mdb2
typu
static
naszej głów-
nej klasy,
DatabaseBrowser
, do wykony-
wania zapytań do bazy danych...
W połączeniu z dwoma kolejnymi
linijkami, otrzymujemy działające me-
nu rozwijane z listą dostępnych baz da-
nych.
Kiedy użytkownik wybierze bazę
danych, powinniśmy wyświetlić mu
Gtk-
TreeView
(Listing 2). Element ten bę-
dzie zawierał nazwy tabel oraz ilość
wierszy w nich dostępnych. Podobnie,
jak poprzednio, stworzymy własną kla-
sę rozszerzając
GtkListStore
. Tym ra-
zem musimy pamiętać, że lista musi
być czyszczona i ponownie uzupełnia-
na przy każdym kolejnym wyborze ba-
zy danych przez użytkownika. Tym sa-
mym, klasa otrzyma własną metodę
lo-
adTables()
, która będzie wymagała ja-
ko jedynego parametru, nazwy bazy
danych. Wynik jej działania będziemy
wyświetlać w dwóch kolumnach: jednej
dla nazwy tabeli, drugiej dla ilości re-
kordów w niej istniejących.
Wypełnienie elementu
GtkTreeView
będzie wymagało tym razem więcej
pracy, niż w przypadku baz danych w
protected function
loadDatabases
()
{
$res
= DatabaseBrowser::
$mdb2
-
>
query
(
'SHOW DATABASES'
)
;
while
((
$row
=
$res
-
>
fetchRow
()))
{
$this
-
>
append
(
array
(
$row
[
0
]))
;
}
}
}
$cmbDatabase
= GtkComboBox::new_text
()
;
$cmbDatabase
-
>
set_model
(
new
DatabaseBrowser_DatabaseList
())
;
Listing 2.
Wyświetlamy dostępne tabele
class
DatabaseBrowser_TableList
extends
GtkListStore
{
public function
__construct
()
{
parent::__construct
(
Gtk::TYPE_STRING, Gtk::TYPE_LONG
)
;
}
public function
loadTables
(
$strDatabase
)
{
$this
-
>
clear
()
;
DatabaseBrowser::
$mdb2
-
>
setDatabase
(
$strDatabase
)
;
$res
= DatabaseBrowser::
$mdb2
-
>
query
(
'SHOW TABLES'
)
;
while
((
$row
=
$res
-
>
fetchRow
()))
{
$strTable
=
$row
[
0
]
;
$nRows
= DatabaseBrowser::
$mdb2
-
>
queryOne
(
t
'SELECT COUNT(*) FROM '
.
$strTable
)
;
$this
-
>
append
(
array
(
$strTable
,
$nRows
))
;
}
}
}
$lstTables
=
new
GtkTreeView
(
new
DatabaseBrowser_TableList
())
;
$renderer
=
new
GtkCellRendererText
()
;
$col
=
new
GtkTreeViewColumn
(
'Table'
,
$renderer
,
'text'
, 0
)
;
$lstTables
-
>
append_column
(
$col
)
;
$numberRenderer
=
new
GtkCellRendererText
()
;
$col
-
>
pack_end
(
$numberRenderer
, false
)
;
$col
-
>
add_attribute
(
$numberRenderer
,
'text'
, 1
)
;
$cmbDatabase
-
>
connect
(
'changed'
,
array
(
$this
,
'onSelectDatabase'
)
,
$lstTables
)
;
public function
onSelectDatabase
(
$cmbDatabase
,
$lstTables
)
{
$strDatabase
=
$cmbDatabase
-
>
get_active_text
()
;
$lstTables
-
>
get_model
()
-
>
loadTables
(
$strDatabase
)
;
}
$scrTables
=
new
GtkScrolledWindow
()
;
$scrTables
-
>
set_policy
(
Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC
)
;
$scrTables
-
>
add
(
$lstTables
)
;
46
www.phpsolmag.org
PHP Solutions Nr 2/2007
Dla zaawansowanych
PHP-Gtk2
GtkComboBox
, ponieważ nie posiada
on odpowiedniego konstruktora, który
mógłby ustawić wszystkie kolumny.
Użyjemy więc następujących kompo-
nentów:
Ostatnie zadanie, to umożliwie-
nie przewijania listy, co staje się trywial-
ne przy użyciu widgeta
GtkScrolledWin-
dow
. Miejmy na uwadze, że
GtkTreeView
,
w odróżnieniu od wielu innych widge-
tów, posiada swój własny system wido-
ku. Oznacza to, że jeśli będziemy przewi-
jać zawartość widgetu, tytuły kolumn bę-
dą zawsze widoczne. Dodatkowo, upew-
nijmy się, że paski przewijania nie będą
widoczne, jeśli nie są konieczne. To za-
danie spełni proste odwołanie do
set_
policy
.
Po połączeniu kodu, otrzymujemy
aplikację widoczną na Rysunku 4.
Pokazujemy dane
Zmapowanie zawartości całej tabeli z ba-
zy danych do jednego widgetu
GtkList-
Store
jest możliwe, acz nie trywialne.
Będziemy musieli zmierzyć się z dwoma
problemami:
Po pierwsze, lista kolumn każdej ta-
beli nie jest znana podczas progra-
mowania naszej przeglądarki baz da-
nych. Oznacza to, że nie możemy zaini-
•
GtkTreeView
jako główny widget, ma-
jący dostęp do modelu
Database-
Browser_TableList,
•
GtkTreeViewColumn
, wyświetlający
zawartość kolumn,
•
GtkCellRendererText
, by narysować
nazwy tabel w wierszach,
•
GtkScrolledWindow
, by wyświetlone
zostały suwaki na wypadek, gdyby li-
sta tabel nie mieściła się w oknie.
Listing 3.
Tworzymy menu nawigacyjne
$this
-
>
tbl =
new
DatabaseBrowser_Table
(
$strDatabase
,
$strTable
)
;
Konstruktor
GtkTreeView
potrzebuje,
jako pierwszego i jedynego parame-
tru modelu, podajemy więc mu instan-
cję naszej klasy
DatabaseBrowser_
TableList
.
GtkTreeViewColumn
potrzebuje z
kolei czterech parametrów: jako pierw-
szego, tytułu nagłówka kolumny. Ja-
ko drugiego – obiektu
GtkCellRenderer
,
który zajmuje się rysowaniem danych
modelu. Trzeci parametr determinuje,
który atrybut
GtkCellRenderer
zostanie
ustawiony (np.
GtkCellRendererText
ja-
ko atrybut “text”, ale już
GtkCellRende-
rerPixbuf
jako "pixbuf", bowiem determi-
nuje obraz). Czwarty i ostatni, parametr,
to numer kolumny modelu, który prze-
trzymuje dane zawarte w atrybucie.
Moglibyśmy teraz po prostu dodać
drugą kolumnę, by wyświetlać ilości
wierszy, lecz istnieje także inna metoda:
dodanie drugiego elementu
GtkCellRen-
dererText
do tej samej kolumny. Ponie-
waż klasa
GtkTreeViewColumn
imple-
mentuje interfejs
GtkCellLayout
, może-
my użyć jej podobnie, jak w przypadku
GtkBox
, używającego
pack_start()
oraz
pack_end()
, w celu dodania większej ilo-
ści rendererów.
Jeśli uważnie śledziłeś dotychcza-
sową treść artykułu, zapewne zastana-
wiasz się, skąd lista tabel “wie”, kiedy
zachodzą zmiany w liście baz danych.
Odpowiedź jest prosta: jeszcze nie wie.
Musimy więc uzupełnić kod, dodając
uchwyt (ang.
handler
) do sygnału
Gtk-
ComboBox
changed
(reakcja na zmia-
nę). Przekazujemy objekt tabeli do funk-
cji pełniącej rolę callbacka (połączenie
zmiany z jej efektem), bowiem będziemy
odnosili się do metody
loadTables()
mo-
delu, który wcześniej zdeiniowaliśmy.
$scrwnd
=
new
GtkScrolledWindow
()
;
$scrwnd
-
>
set_policy
(
Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC
)
;
$scrwnd
-
>
add
(
$this
-
>
tbl
)
;
$this
-
>
pack_start
(
$scrwnd
)
;
$tb
=
new
GtkToolbar
()
;
$arButtons
=
array
(
Gtk::STOCK_GOTO_FIRST =
>
'irst'
,
Gtk::STOCK_GO_BACK =
>
'back'
,
Gtk::STOCK_REFRESH =
>
'refresh'
,
Gtk::STOCK_GO_FORWARD =
>
'forward'
,
Gtk::STOCK_GOTO_LAST =
>
'last'
)
;
foreach
(
$arButtons
as
$nStockItem
=
>
$strAction
)
{
$btn
= GtkToolButton::new_from_stock
(
$nStockItem
)
;
$btn
-
>
connect_simple
(
'clicked'
,
array
(
$this
-
>
tbl,
'navigate'
)
,
$strAction
)
;
$tb
-
>
insert
(
$btn
, -1
)
;
$this
-
>
arButtons
[
$strAction
]
=
$btn
;
}
Rysunek 2.
Wynik działania Gtk2_ExceptionDump po stworzeniu obiektu PEAR_Error
przez MDB2
48
www.phpsolmag.org
PHP Solutions Nr 2/2007
Plik z chomika:
Kaktus
Inne pliki z tego folderu:
Algebra macierzy.pdf
(88 KB)
Tworzymy frontend do Wake-On-Lan w PHP-GTK.pdf
(612 KB)
Przeglądarka bazy danych przy użyciu PHP-Gtk2.pdf
(1072 KB)
Delphi i PHP.pdf
(516 KB)
Inne foldery tego chomika:
Czasopisma
Zgłoś jeśli
naruszono regulamin