Uczelnia Warszawska im. Marii Skłodowskiej-Curie
Kierunek: Informatyka i ekonometria
Adam Kowalski
Nr albumu 16755
Projekt witryny internetowej dla przykładowej firmy
Praca inżynierska
napisana pod kierunkiem naukowym
dr hab. inż. Kazimierza Worwy
Warszawa 2008
SPIS TREŚCI
Wstęp
Cel pracy
Celem niniejszej pracy jest przedstawienie rozwiązań umożliwiających zaprezentowanie produktów firmy wytwarzającej oprogramowanie do obsługi przedsiębiorstwa. W obecnych czasach naturalnym rozwiązaniem użytym do prezentacji produktów jest stworzenie witryny internetowej.
Argumenty przemawiające za wykorzystaniem Internetu*, jako medium dla systemu informacyjnego
Ciągły dostęp do informacji;
Nieograniczony zasięg terytorialny;
Możliwość szybkiego zamieszczania nowych informacji;
Minimalne koszty utrzymania i aktualizowania zawartości;
Brak ograniczeń ilości zamieszczanych informacji;
Możliwość szybkiego i sprawnego wyszukiwania informacji;
Projekt zostanie opracowany w oparciu o architekturę trójwarstwową (ang. three-layer architecture), czyli architekturę typu klient-serwer, w której interfejs użytkownika, przetwarzanie danych i składowanie danych są rozwijane w postaci osobnych modułów. Architektura tego typu pozwala aktualizować lub zastępować poszczególne moduły niezależnie od siebie, w miarę jak zmieniają się warunki techniczne - na przykład zmiana systemu operacyjnego na komputerze użytkownika, wpływa jedynie na warstwę interfejsu użytkownika, ale nie wpływa na składowanie i przetwarzanie i danych.
W ciągu okresu istnienia Internetu powstało wiele technologii umożliwiających tworzenie i prezentowanie treści na stronach WWW. Istnieje wiele rozwiązań komercyjnych (płatnych) jak również sporo rozwiązań bezpłatnych, tworzonych przez zapaleńców z całego świata. Istnieją również rozwiązania umożliwiające bezpłatne korzystanie z oprogramowania, jeśli jest wykorzystywanie w celach niekomercyjnych, a płatne (najczęściej cena jest, w porównaniu do programów sensu stricte komercyjnych, bardzo atrakcyjna dla użytkowników), jeśli istnieje chęć komercyjnego wykorzystania rozwiązań.
Ważną rzeczą jest możliwość wglądu w pełny kod oprogramowania (open source). Co prawda naraża to na potencjalne wykorzystanie zdobytej o nim wiedzy w niecnych celach, ale także umożliwia szukanie rozwiązań zwiększających bezpieczeństwo programów przez entuzjastów z całego świata.
Komercyjne rozwiązania najczęściej mają kod zamknięty i niepubliczny. Najczęściej skutkuje to sytuacją, że hakerzy i tak włamią się do programu i poznają jego słabe punkty pozwalające wykorzystać program w celach przestępczych, niezgodnie z intencjami jego twórców. Prace nad poprawianiem programu może prowadzić tylko ten, kto go stworzył i posiada jego kod źródłowy, czyli producent. W sposób oczywisty brak tutaj wsparcia szerszej grupy ludzi.
Per saldo wybór oprogramowania open source jest rozwiązaniem bardziej perspektywicznym.
Charakterystyka zawartości rozdziałów
W kolejnych rozdziałach zostały opisane następujące zagadnienia:
W rozdziale pierwszym zaprezentowano wybrane rozwiązania programowe oraz przedstawiono ich krótkie charakterystyki. W drugim rozdziale omówiono zagadnienia bezpieczeństwa: wybranego serwera (Apache) i przechowywanych oraz przesyłanych Internetem danych. W rozdziale trzecim przedstawiono opis projektu oraz wyspecyfikowano i przeanalizowano wymagania odnośnie systemu. Rozdział czwarty prezentuje sposób realizacji projektu. Ukazano sposób projektowania i implementacji bazy zawierającej dane prezentowane później w witrynie WWW, W piątym rozdziale podsumowano pracę.
Wybrane rozwiązania
Wybrane przeze mnie rozwiązania bazują na otwartym kodzie źródłowym (open source) oraz mogą działać na wielu platformach systemowych.
Są to:
Apache - serwer stron WWW
PHP - język programowania używany do projektowania witryn internetowych
MySQL - relacyjna baza danych
Za wykorzystaniem oprogramowania typu open source przemawiają następujące jego cechy:
Jest darmowe. Istotą oprogramowania ze swobodnym dostępem do kodu źródłowego jest jego bezpłatność i ogólna dostępność. Projektanci i programiści na zasadzie wolontariatu poświęcają swój czas, by poprawiać istniejące programy i tworzyć nowe;
Z definicji twórcy oprogramowania tego typu nie mogą wymagać opłat za licencję lub sprzedaż;
Są niezależne od platformy i „neutralne technologicznie". Dzięki temu wymogowi społeczność wolnego oprogramowania ma pewność, iż programy mogą być stosowane przez każdego, kto chce z nich korzystać;
Zgodnie z definicją oprogramowania open source dostępną na witrynie organizacji programy tego typu nie mogą zależeć od żadnej „indywidualnej technologii lub stylu interfejsu" i muszą być „neutralne technologicznie". Oprogramowanie spełnia wyż wym. kryterium, jeśli może działać na więcej niż jednym systemie operacyjnym;
Nie mogą ograniczać innego oprogramowania. Oznacza to, że jeśli program typu open source jest rozpowszechniany z innymi programami to te inne programy mogą być produktami komercyjnymi lub typu open source. Zapewnia to twórcom oprogramowania maksymalną kontrolę i elastyczność;
Stymulują różnorodność rozwiązań co daje lepsze wyniki dla ogółu społeczności internetowej, ponieważ zmusza firmy-giganty typu Microsoft czy Sun Microsystems do rozwijania i ulepszania własnych komercyjnych rozwiązań;
Programy open source - zgodnie z założeniami tego ruchu - nie mogą dyskryminować dowolnej osoby lub grupy osób, ani nie mogą zakazywać innych „dziedzin eksploatacji". Przykładowo program zaprojektowany do użytku w jednej dziedzinie nie może zostać ograniczony tylko do tego pola zastosowań, jeśli ktoś z innej dziedziny stwierdzi, że po pewnych modyfikacjach będzie on spełniał jego oczekiwania.
Pełna lista kryteriów, które muszą zostać spełnione, aby program został potraktowany, jako open source jak również dodatkowe informacje na temat społeczności związanej z programami tego typu znajduje się w witrynie OSI.
1.1. Apache
Apache jest otwartym serwerem HTTP* dostępnym dla wielu systemów operacyjnych (m.in. UNIX*, GNU/Linux*, BSD*, Microsoft Windows). Pochodzi on od serwera NCSA - National Center for Supercomputing Applications, opracowanego w 1995 roku na zlecenie rządu Stanów Zjednoczonych.
Serwer Apache cechuje się następującymi właściwościami:
kontrolę dostępu i możliwość uwierzytelniania użytkowników;
możliwość stosowania stron chronionych hasłem dla wielu użytkowników;
możliwość dostosowania do potrzeb stron błędów;możliwość zastosowania proxy* typu HTTP, FTP;
dzienniki użycia i błędów w wielu dostosowywanych do własnych potrzeb formatach;
możliwość skonfigurowania hostingu wirtualnego dla wielu różnych adresów IP przypisanych do tego samego serwera;
dyrektywy Directory Index dla wielu plików;
możność zastosowania skryptów CGI*; możliwość osadzania interpreterów języków skryptowych, (np. PHP, PERL*, PYTON*);
możliwość zaimplementowania protokołu SSL*.
Firma Netcraft Web w czerwcu 2008 przeprowadziła badanie Internetu. Otrzymano odpowiedź z 172 338 726 serwerów Apache pozostaje liderem z udziałem w rynku na poziomie 49.1% co daje liczbę serwerów zbliżającą się do 85 mln (na koniec 2005 roku były to 34 mln). Jego elastyczność, użyteczność i cena powodują, że jest wybierany niezwykle często. Może służyć zarówno, jako rozwiązanie dla dużego serwera WWW, intranetu firmy lub po prostu do testowania własnych stron przed ich umieszczeniem na właściwym serwerze.
1.2. PHP
PHP jest pełnowartościowym językiem programowania pozwalającym na tworzenie aplikacji WWW z wszystkimi potrzebnymi funkcjami. PHP współpracuje z wieloma systemami baz danych. Pozwala to na bardzo łatwe tworzenie aplikacji WWW korzystających z informacji zapisanych w bazie danych. Możliwy jest również dostęp do następujących usług sieciowych::
IMAP *- Internet Message Access Protocol,
POP3 * - Post Office Protocol version 3,
NNTP * - Network News Transfer Protocol,
TTP *- Time-Triggered Protocol.
Pozwala on również na otwieranie gniazd sieciowych i podłączanie się do innych protokołów TCP/IP.
PHP może być użyty w wielu konfiguracjach serwerów. PHP rozprowadzany jest głównie w postaci kodu źródłowego, może być skompilowany na wielu różnych platformach, na przykład w systemach Linux, FreeBSD, a także w systemie Windows. Dla systemów platformy Win32 są dostępne również dystrybucje binarne.
PHP może działać, jako program CGI lub może być zainstalowany, jako moduł Apache lub rozszerzenie ISAPI. Dzięki temu może on działać z praktycznie każdym serwerem WWW, od Apache posadowionego na systemie Linux do IIS (IIS- Internet Information Services) na systemie Windows. Jeśli chcemy utworzyć elastyczne środowisko pracy możemy samodzielnie skompilować i zainstalować PHP. Jeśli zależy nam na szybkim zaczęciu pracy, możemy użyć binarnej dystrybucji PHP.
Do głównych konkurentów PHP należą: Perl, Microsoft Active Server Pages (ASP), Java Server Pages (JSP).
W porównaniu z tymi produktami PHP posiada wiele zalet. Są to między innymi:
wysoka wydajność;
wygodna składnia oparta na języku C;
interfejsy do wielu różnych systemów baz danych;
wbudowane biblioteki służące do rozwiązywania różnych popularnych zadań WWW;
funkcje obsługi popularnych protokołów Internetu;
duży zasób funkcji i procedur z wielu niestandardowych zakresów zastosowań, rzadko dostępnych w językach skryptowych, takich jak: kryptografia, kompresja plików (gzip), manipulowanie plikami graficznymi oraz plikami w formacie PDF, obsługa połączeń TCP/IP;
prosta obsługa mechanizmu wgrywania plików na serwer WWW (HTTP POST i PUT);
otwarta architektura ułatwiająca przygotowywanie rozszerzeń języka w postaci kompilowanych bibliotek funkcji i procedur, które mogą być dołączane w momencie wykonywania skryptu;
otwarta architektura ułatwiająca przygotowywanie rozszerzeń języka w postaci kompilowanych bibliotek funkcji i procedur, które mogą być dołączane w momencie wykonywania skryptu;
niski koszt;
obsługa mechanizmów zorientowanych obiektowo;
przenośność (działanie na wielu platformach systemowych);
wbudowany debugger* oraz wiele opcji pozwalających na dogłębne analizowanie wykonania skryptu i raportowanie błędów.
Sposób działania PHP
Język HTML to język opisu strony, co znaczy, że pozwala jedynie na określanie wyglądu i zawartości witryny. Za pomocą HTML można wyróżnić kolorem fragmenty tekstu, pogrubić słowa kluczowe czy stworzyć nagłówki HTML pozwala także na osadzanie grafiki, tworzenie tabel i poziomych linii. To wszystko sprawia, że za jego pomocą oraz wykorzystując CSS* (kaskadowe arkusze stylów) możemy stworzyć ładnie wyglądającą witrynę internetową.
Strona wykonana tylko za pomocą HTML i CSS będzie wyglądać zawsze tak samo, dopóki czegoś na niej nie zmienimy. Internauci odwiedzający witrynę nie mogą w żaden sposób wpływać na jej wygląd, nie będą mogli jej ocenić, wyrazić na jej temat własnej opinii. Taka statyczna strona będzie przypominać zadrukowaną kartkę papieru. Nie zachęca to raczej to internautów do regularnego odwiedzania witryny.
Aby uzyskać ciekawszy efekt warto sięgnąć po PHP. Jest on liderem wśród języków wykonywanych po stronie serwera. Oznacza to, że kod tego języka nie jest wysyłany do przeglądarki internauty, a wysyłane są jedynie wyniki działania kodu. Dzięki temu nie ma znaczenia, z jakiej przeglądarki internetowej korzysta internauta odwiedzający witrynę - zawsze zobaczy to, co zaplanował twórca strony. Zaletą PHP jest również to, że internauta nie jest w stanie podejrzeć kodu źródłowego skryptów (jak ma to miejsce w wypadku JavaScript*), a więc nie będzie mógł go powielić lub na przykład sprawdzić znajdujących się w nim haseł.
Język PHP pozwala na dynamiczne tworzenie stron WWW. PHP sprawia, że witryna jest żywa i interaktywna, a dzięki temu interesująca wizualnie dla internautów. Za pomocą skryptów PHP można umieścić na stronie wiele ciekawych elementów, na przykład ankiety, fora dyskusyjne czy księgi gości. Język PHP pozwala na osiągnięcie efektów niemożliwych do uzyskania za pomocą języka HTML czy nawet skryptów JavaScript.
Dodatkowo programista PHP ma możliwość korzystania z baz danych, zapisywania i odczytywania plików czy łączenia się z innymi serwerami, by pobrać z nich dodatkowe informacje.
Na schemacie pokazanym poniżej przedstawiona jest zasada wyświetlania strony stworzonej w języku PHP.
Rysunek 1. Zasada wyświetlania w przeglądarce strony stworzonej w języku PHP (źródło: opracowanie własne),.
W przypadku typowych, statycznych dokumentów HTML, gdy wprowadzi się adres do przeglądarki internetowej, łączy się ona z serwerem WWW i wysyła do niego żądanie przesłania odpowiedniego pliku. Serwer szuka tego pliku i jeśli go odnajdzie, wysyła do przeglądarki, a ona wyświetla jego zawartość. W wypadku serwisów korzystających z PHP proces ten jest trochę bardziej złożony. Gdy wprowadzimy adres do przeglądarki, łączy się ona z serwerem i żąda przesłania odpowiedniego pliku. Serwer po odnalezieniu tego pliku nie wysyła go od razu do użytkownika, ale najpierw przekazuje do tak zwanego interpretera PHP. Plik, po przetworzeniu w interpreterze, powraca do serwera i dopiero wtedy zostaje wysłany do przeglądarki internauty.
Interpreter PHP
Interpreter PHP to specjalny program, który rozumie polecenia języka PHP. Interpreter otrzymuje dokument HTML i wyszukuje w nim fragmenty, które są zapisane w języku PHP. Po ich odnalezieniu wycina je i uruchamia. Jeśli zwracają one jakieś wyniki, interpreter wstawia je do dokumentu w miejsce, w którym wcześniej był kod PHP.
Warto ten proces prześledzić na przykładzie prostej strony internetowej:
Niemal cały dokument jest zapisany w języku HTML. W części <body> znajduje się tylko jeden znacznik - nagłówek <h1>.
<html>
<head>
<meta http-equiv="Content-type"
content="text/html; charset=iso-8859-2" />
</head>
<body>
<h1>
<?php echo("Strona testowa PHP") ?>
</h1>
</body>
Wewnątrz tego nagłówka znacznik <?php oznacza początek kodu języka PHP. Koniec tego kodu oznacza się za pomocą znacznika ?> (istnieją również ekwiwalentne postacie znaczników, ale wymienione powyżej są preferowanymi przez twórców PHP). Zatem w powyższym dokumencie fragment:
<?php echo("Strona testowa PHP") ?>
nie jest zapisany w języku HTML, lecz w języku PHP.
Kiedy przeglądarka internauty zażąda od serwera przesłania jej dokumentu, zostaje on najpierw przekazany do interpretera PHP. Interpreter odnajduje wspomniany fragment i usuwa go z dokumentu. Następnie próbuje go uruchomić. Kod PHP zwraca napis „Strona testowa PHP”. Interpreter wstawia więc ten napis w miejsce całego kodu PHP i taki plik wysyła z powrotem do przeglądarki internauty. Dzięki temu w przeglądarce wyświetlona zostaje strona.
<html>
<head> <meta http-equiv="Content-type"
content="text/html; charset=iso-8859-2" />
</head>
<body>
<h1>
Strona główna
</h1>
</body>
</html>
1.3. MySQL
Bardzo popularną aplikacją typu open source jest baza danych MySQL umożliwiająca PHP i Apache dostęp do danych, które są (z wykorzystaniem przeglądarki internetowej) prezentowane użytkownikowi. MySQL to serwer strukturalnego języka zapytań (SQL) zaprojektowany do działania w dużym obciążeniu i przetwarzania złożonych zapytań. Jako relacyjny system bazy danych, MySQL umożliwia łączenie wielu tabel w celu zapewnienia maksymalnej wydajności i szybkości.
Najważniejsze cechy relacyjnej bazy danych MySQL:
działanie na wielu platformach systemowych;
duża szybkość działania;
polecenia, które umożliwiają wyświetlenie wielu przydatnych administratorowi informacji na temat bazy danych;
funkcje grupujące z obliczeniami matematycznymi i sortującymi;
do 64 indeksów na tabelę i możliwość zaimplementowania rozwiązania dla 60 tysięcy tabel i 5 miliardów rekordów (wielkość ta zależy jedynie od fizycznych możliwości komputera);
w pełni wykorzystanie mocy komputerów wieloprocesorowych;
różne typy kolumn obejmujące wszelkie możliwe typy danych;
lokalizowane komunikaty błędów dla wielu różnych języków;
interfejsy API dla języków programowania (m.in. C, PHP, Perl);
duża liczba użytkowników mogących jednocześnie korzystać z bazy danych.
MySQL to bardzo często wybierane rozwiązanie zapewniające dostęp do danych w Internecie, ponieważ bardzo dobrze radzi sobie ze znacznym obciążeniem i posiada rozbudowane funkcje bezpieczeństwa.
Co to jest baza danych?
W relacyjnych bazach danych, dane są zgrupowane w tabelach. Tabele są utworzone poprzez grupowanie danych z tego samego tematu i zawierają kolumny oraz wiersze informacji. Tabele są ze sobą wiązane za pomocą mechanizmów bazy danych, gdy uruchamiane jest zapytanie. Tabele są ściśle związane z pojęciami relacji lub encji*.
Generalnie bazę danych można przedstawić, jako zbiór powiązanych danych. W niektórych wcześniejszych systemach baz danych, baza danych była plikiem zawierającym pojedynczą tabelę danych. Na przykład, jeśli chcieliśmy zgromadzić informacje dotyczące pracowników to wewnątrz pliku umieszczaliśmy kolumny odnoszące się do danych pracownika, takich jak pensja, data przyjęcia, nazwisko, numer legitymacji ubezpieczeniowej itp. Plik zawierał wiersz dla każdej osoby w firmie, z odpowiednimi wartościami w odpowiednich kolumnach. Indeksy, użyte do przyspieszenia dostępu do danych, były w odrębnym pliku, tak jak inne elementy dotyczące zabezpieczeń.
W obecnie stosowanych systemach bazodanowych, baza danych niekoniecznie jest związana z pojedynczym plikiem, ale jest to pojęcie bardziej logiczne, oparte na zbiorze powiązanych obiektów.
Obiekty relacyjnej bazy danych
Relacyjna baza danych składa się z obiektów różnego typu. Poniżej przedstawiono kilka najpowszechniejszych obiektów:
Tabele są obiektami zawierającymi typy danych i aktualne dane;
Kolumny są częścią tabel przechowującą dane. Kolumny muszą posiadać określony typ danych i unikalną nazwę;
Typy danych określają rodzaj przechowywanych danych. Można korzystać z wielu typów danych, takich jak typ znakowy, numeryczny i typ data. Każdej kolumnie w tabeli jest przypisany pojedynczy typ danych;
Widoki są to głównie zapytania przechowywane w bazie danych, odnoszące się do jednej lub wielu tabel. Widoki można stworzyć i zachować w celu łatwiejszego użycia w przyszłości. Widoki zwykle wykluczają kolumny z tabeli lub łączą dwie lub więcej tabel;
Indeksy pomagają tak zorganizować dane, że zapytania są wykonywane szybciej.
Klucze podstawowe pomimo tego, że nie są obiektami, mają podstawowe znaczenie dla relacyjnych baz danych. Wymuszają unikalność wierszy umożliwiając identyfikację każdego przechowywanego elementu.
Klucze obce to jedna lub więcej kolumn, do których odnoszą się klucze podstawowe z innych tabel. Systemy baz danych wykorzystuje klucze podstawowe i obce do określenia relacji między danymi z odrębnych tabel, podczas wykonywania zapytania.
Definicje poprawności są zaimplementowanymi w systemie mechanizmami opartymi na serwerze, zapewniającymi integralność danych.
Reguły są przypisane do kolumn, powodując, że wpisywane dane są zgodne z określonymi standardami. Przykładowo, można używać reguł, aby upewnić się, czy wpisywany numer telefonu danej osoby zawiera jedynie cyfry lub wpisywane nazwisko tylko litery i ewentualnie myślnik.
Wartości domyślne mogą być ustawione dla pól i są używane, kiedy żadne dane nie zostaną wpisane podczas wykonywania operacji INSERT. Przykładem jest domyślne ustawienie kodu pocztowego obszaru, z którego pochodzi najwięcej klientów. Pozwala to uniknąć każdorazowego wpisywania kodu pocztowego dla klientów lokalnych z danego obszaru;
Bezpieczeństwo
Początki Internetu wiążą się z powstaniem sieci ARPANET i sięgają końca lat 60. XX wieku, gdy amerykańska firma RAND Corporation prowadziła badania studyjne nad możliwościami dowodzenia i łączności w warunkach wojny nuklearnej. Na podstawie jej raportów podjęto prace projektowe nad skonstruowaniem sieci komputerowej mogącej funkcjonować pomimo zniszczenia jej części. Sieć Internet w swojej pierwotnej postaci, miała służyć przed wszystkim środowisku akademickiemu.. Dlatego też, ze względów historycznych, trudno mówić o bezpieczeństwie globalnej sieci. Można tylko próbować dołożyć wszelkich starań, aby poszczególne jej elementy były jak najbezpieczniejsze. Jeśli chodzi o aplikacje to podstawowym obowiązkiem administratora systemu jest dbanie o instalacje poprawek zwiększających niezawodność i łatających istniejące luki.
2.1 Bezpieczeństwo serwera Apache.
Przede wszystkim należy zadbać o aktualne wersje oprogramowania - stare wersje Apache, mogą mieć dziury, których załatanie może być niemożliwe bez aktualizacji konkretnego pakietu. W przypadku serwera wystawionego do publicznego Internetu jest to procedura niezbędna, tym bardziej, że w sieci mnożą się robaki korzystające właśnie z dziur w Apache.. Dbanie o bezpieczeństwo serwera Apache wymaga instalacji poprawek zwiększających niezawodność i łatających istniejące luki.
Bardzo ważnym zagadnieniem jest także odpowiednie konfigurowanie tego serwera. Nie należy włączać wszystkich modułów serwera, a tylko te, które są nam w danej chwili potrzebne. Plik konfiguracyjny serwera Apache nosi nazwę httpd.conf i w zależności od systemu, na jakim serwer ten jest zainstalowany może być różnie umiejscowiony. Zazwyczaj jednak jest to katalog /etc/apache lub /etc/apache2 (w zależności od wersji serwera Apache).
Wygodnym sposobem na pewne zmiany w konfiguracji serwera jest edycja pliku .htaccess - Zmiany te są widoczne tylko w podkatalogach i katalogu, w którym ten plik się znajduje.
Ogólnie mówiąc dzięki plikom .htaccess możemy ustawić parametry dla kilku tysięcy stron jednocześnie zamiast ustawiać je pojedynczo.
2.2. Bezpieczeństwo danych magazynowanych.
Zabezpieczenie bazy danych jest szczególnie ważne w przypadku udostępniania przez nią danych poprzez stronę WWW.
Należy unikać uruchamiania serwera MySQL w kontekście użytkownika root. w unikowych systemach operacyjnych. Dawałoby to każdemu użytkownikowi logującemu się do serwera baz danych prawo do odczytywania i zapisywania plików w dowolniej lokalizacji w systemie operacyjnym. Zalecane jest zarejestrowanie nowego użytkownika, przeznaczonego tylko do uruchamiania serwera MySQL. Ponadto zalecane jest utworzenie odrębnego katalogu przeznaczonego do przechowywania danych, a dostępnego tylko dla użytkownika utworzonego na potrzeby MySQL.
Każdy użytkownik, powinien posiadać hasło dostępu, które dodatkowo powinno być trudne do odgadnięcia oraz często zmieniane. Podstawową zasadą konstruowania hasła jest, aby nie było zwykłym słowem, mającymi określone znaczenie (istniejącym w słownikach). Najlepszym rozwiązaniem jest zastosowanie kombinacji liter (dużych i małych), cyfr oraz innych znaków dostępnych bezpośrednio na klawiaturze. Jeżeli hasła dostępu mają być przechowywane w plikach skryptów, to pliki te powinny być dostępne tylko dla użytkowników, do których te hasła należą.
W skryptach PHP inicjujących połączenie z serwerem baz danych trzeba podać hasło dostępu odpowiedniego użytkownika. Hasło to oraz identyfikator użytkownika dobrze jest zapisać w oddzielnym pliku, który w razie potrzeby dołącza się do skryptu za pomocą polecenia include(). Zalecane jest, aby plik ten zapisać w innej lokalizacji niż dokumenty WWW i udostępnić tylko jednemu, wskazanemu użytkownikowi.
W przypadku aplikacji internetowych czasem trzeba zapisać identyfikatory i hasła dostępu użytkowników z niej korzystających w bazie danych. Dane te należy przed zapisaniem zaszyfrować jednostronnie, tzn. bez możliwości ich odszyfrowania, za pomocą funkcji SHA1(). Należy jednak pamiętać, że po zapisaniu tak zaszyfrowanego hasła poprzez polecenie INSERT, w tekście polecenia SELECT, wykonywanego w celu odszukania w bazie i zalogowania użytkownika, również należy użyć na haśle tej samej funkcji szyfrującej, aby porównać, czy podane hasło dostępu jest prawidłowe.
Nie należy przyznawać użytkownikowi większych przywilejów, niż jest to niezbędne - należy je sprawdzić w tabelach przywilejów. W szczególności nie powinno się nadawać przywilejów PROCESS, FILE, SHUTDOWN i RELOAD użytkownikom niebędącym administratorami, chyba, że jest to konieczne. Użytkownik posiadający przywilej PROCESS ma możliwość podglądania czynności wykonywanych przez innych użytkowników oraz wpisywanych przez nich poleceń i danych, a więc także ich haseł dostępu. Przywilej FILE natomiast uprawnia do odczytywania i zapisywania plików z i do systemu operacyjnego (w tym także np. /etc/password w systemach uniksowych).
Również przywilej GRANT powinno nadawać się z rozwagą, gdyż użytkownik, który go posiada, może nadawać innym użytkownikom takie przywileje, jakie sam posiada.
MySQL korzysta z tabel przywilejów w celu sprawdzenia, jakie operacje może wykonywać dany użytkownik. Proces ten przebiega dwuetapowo.
Pierwszy etap: weryfikacja połączenia.
Odczytując dane zapisane w tabeli user, MySQL sprawdza, czy dany użytkownik w ogóle może uzyskać dostęp do serwera baz danych. Użytkownik rozpoznawany jest na podstawie identyfikatora i hasła. Jeżeli w tabeli user identyfikator użytkownika nie zostanie określony, wówczas będzie on interpretowany, jako dowolny. Jeżeli w polu Password nie zostanie zapisana żadna wartość, to przy logowaniu serwer MySQL nie będzie wymagał podania hasła dostępu. Bezpieczniej jest unikać pustych identyfikatorów użytkownika czy też pustych haseł dostępu..
Drugi etap: weryfikacja polecenia.
Za każdym razem, gdy zalogowany użytkownik wywoła jakiekolwiek polecenie, MySQL w pierwszej kolejności sprawdza, czy dysponuje on odpowiednimi przywilejami. Najpierw sprawdzane są przywileje globalne (zapisane w tabeli user). Jeśli użytkownik nie posiada odpowiednich przywilejów globalnych, wówczas zostaną przejrzane tabele db i host. Jeśli i w tych tabelach nie ma informacji o posiadaniu przez użytkownika wymaganych przywilejów, to MySQL przegląda dane w tabeli tables_priv, a w przypadku ich braku tam, zostanie przeszukana tabela columns_priv.
2.3. Bezpieczeństwo transmisji.
Internet w całości bazuje na otwartych specyfikacjach i technologiach dostępnych dla wszystkich. Ta cecha spowodowała, że rozpowszechnił się na świecie w bardzo szybkim tempie. Jego uniwersalność i otwartość ułatwia wykorzystywanie go, jako medium do wielu zadań.
Powszechnie w Internecie używany jest protokół TCP/IP* zapewniający komunikację Działanie TCP/IP opiera się na dzieleniu danych na części zwane pakietami, które są następnie przekazywane od jednego komputera do drugiego, do momentu, gdy dotrą do miejsca przeznaczenia. Oznacza to, że dane przechodzą przez wiele różnych komputerów, a każdy z nich może posłużyć do podejrzenia przesyłanych za jego pośrednictwem informacji. Do prześledzenia drogi, jaką przebywają dane z określonej maszyny, można użyć polecenia traceroute (w systemach unikowych) lub trace (w Windows). Komenda ta spowoduje wypisanie adresów wszystkich komputerów, przez które przechodzą będą pakiety danych, zanim osiągną komputer docelowy.
Internet jest również środkiem przekazu zapewniającym niemal całkowitą anonimowość. Trudno jest uzyskać pewność, że użytkownik jest rzeczywiście tym, za kogo się podaje.
W 1994 roku firma Netscape stworzyła protokół, służący do bezpiecznej transmisji zaszyfrowanego strumienia danych, nazwany SSL* (Secure Socket Layer). Rok później pojawiła się wersja v3 tego protokołu. W 1996 roku Internet Engineering Task Force (IETF) powołało grupę roboczą pod nazwą TLS (Transport Layer Security), której zadaniem było rozwijanie protokołu SSL. W 1999 roku został opublikowany standard TLS 1.0, który jest również czasem określany, jako SSL 3.1. SSL jest więc protokołem typu klient-serwer pozwalającym na nawiązanie bezpiecznego połączenia z użyciem certyfikatów. Jest on zorientowany głównie na uwierzytelnianie serwera (np. sklepu internetowego, do którego klient wysyła numer karty kredytowej i chce mieć pewność, co do odbiorcy), ale przewiduje również możliwość autoryzacji klienta.
Niektóre wczesne wersje protokołu używały szyfrowania 40-bitowym kluczem ze względu na ograniczenia nałożone przez rząd USA na eksport technologii kryptograficznych. Rząd specjalnie nałożył ograniczenie 40-bitowe, aby rządowe agencje były w stanie złamać hasło za pomocą ataku brute-force a jednocześnie było zbyt skomplikowane dla zbyt ubogich hakerów. Po kilku latach publicznej debaty, lepszemu rozpoznaniu dłuższych kluczy przez agencje rządowe oraz kilku sprawach sądowych, rząd złagodził nieco swoje stanowisko wobec stosowania dłuższych kluczy. Obecnie 40-bitowe klucze wyszły praktycznie z użycia, zastąpione przez o wiele bezpieczniejsze klucze 128-bitowe.
Zasada działania SSL.
Protokół SSL dodaje kolejną warstwę do stosu protokołu oraz kilka protokołów warstwy aplikacji odpowiedzialnych za działanie SSL.
Rysunek 2. Protokół SSL dodaje warstwę do stosu protokołu (źródło: opracowanie własne na podstawie pozycji [3] z wykazu literatury),.
Podczas wysyłania danych z użyciem SSL wykonywane są następujące operacje:
dane dzielone są na niewielkie pakiety;
każdy pakiet poddawany może być kompresji (nie jest to jednak działanie obowiązkowe);
za pomocą algorytmu mieszającego dla każdego pakietu obliczany jest kod uwierzytelniający MAC (ang. Message Authentication Code);
skompresowane dane i ich kod uwierzytelniający zostają połączone i zaszyfrowane;
zaszyfrowane pakiety wraz z dołączonymi do nich nagłówkami informacji zostają wysłane do sieci.
Rysunek 3, Podział, kompresja, mieszanie i szyfrowanie danych przed wysłaniem (źródło: opracowanie własne na podstawie pozycji [3] z wykazu literatury),.
Zasada działania SSL
Schemat działania protokołu wygląda następująco (w poniższym schemacie: K - tak oznaczony jest klient, S - tak oznaczony jest serwer):
K --> S ClientHello
Klient wysyła do serwera zgłoszenie zawierające m.in. obsługiwaną wersję protokołu SSL, dozwolone sposoby szyfrowania i kompresji danych oraz identyfikator sesji. Komunikat ten zawiera również liczbę losową używaną potem przy generowaniu kluczy.
K <-- S ServerHello
Serwer odpowiada podobnym komunikatem, w którym zwraca klientowi wybrane parametry połączenia: wersję protokołu SSL, rodzaj szyfrowania i kompresji, oraz podobną liczbę losową.
K <-- S Certificate
Serwer wysyła swój certyfikat pozwalając klientowi na sprawdzenie swojej tożsamości (ten etap jest opcjonalny, ale w większości przypadków występuje)
K <-- S ServerKeyExchange
Serwer wysyła informację o swoim kluczu publicznym. Rodzaj i długość tego klucza jest określony przez typ algorytmu przesłany w poprzednim komunikacie.
K <-- S ServerHelloDone
Serwer zawiadamia, że klient może przejść do następnej fazy zestawiania połączenia.
K --> S ClientKeyExchange
Klient na podstawie ustalonych w poprzednich komunikatach dwóch liczb losowych (swojej i serwera) generuje klucz sesji używany do faktycznej wymiany danych. Następnie wysyła go serwerowi używając jego klucza publicznego. Uwaga: wygenerowany klucz jest kluczem algorytmu symetrycznego (typowo DES)! Jest on jednak ustalony w sposób bezpieczny i znany jest tylko komunikującym się stronom.
K --> S ChangeCipherSpec
Klient zawiadamia, że serwer może przełączyć się na komunikację szyfrowaną…
K --> S Finished
... oraz, że jest gotowy do odbierania danych zakodowanych.
K <-- S ChangeCipherSpec
Serwer zawiadamia, że wykonał polecenie - od tej pory wysyłał będzie tylko zaszyfrowane informacje…
K <-- S Finished
... i od razu wypróbowuje mechanizm - ten komunikat jest już wysyłany bezpiecznym kanałem uwierzytelnianie klienta
Jak widać na powyższym schemacie, w protokole SSL domyślna sytuacja zakłada tylko uwierzytelnianie serwera. Istnieją jednak metody pozwalające na uwierzytelnienie klienta. W tym celu korzysta się z trzech dodatkowych komunikatów:
K <-- S CertificateRequest
Po przesłaniu swojego certyfikatu serwer zawiadamia, że chciałby otrzymać certyfikat klienta
K --> S Certificate
Po otrzymaniu komunikatu ServerHelloDone klient odsyła swój certyfikat
K --> S CertificateVerify
Klient musi potwierdzić, że faktycznie posiada klucz prywatny odpowiadający wysłanemu certyfikatowi. W tym celu klient podpisuje swoim kluczem prywatnym skrót wszystkich dotychczas ustalonych danych o połączeniu i wysyła go korzystając z tego komunikatu.
Dostępne są liczne komercyjne implementacje protokołu SSL oraz implementacja oparta na otwartej licencji o nazwie OpenSSL*.
Projekt
3.1. Opis systemu
Klient, który chce zapoznać się z ofertą firmy, musi połączyć się z Internetem i wejść na stronę firmy. Na stronie internetowej ma możliwość przejrzenia oferty poprzez znajdujący się na niej katalog. Przeglądanie jest możliwe według nazwy lub właściwości
3.2. Specyfikacja wymagań
Celem projektu jest umożliwienie klientowi zapoznanie się z ofertą firmy.
klient ma możliwość przejrzenia pozycji znajdujących się w ofercie
klient ma możliwość zapoznania się z opisem każdej z pozycji
klient ma możliwość wyświetlenia wybranych pozycji
.
3.3. Analiza przypadków użycia
Rysunek 4. Analiza przypadków użycia (źródło: opracowanie własne),.
Scenariusze realizacji funkcji przypadków użycia.
Scenariusz prawidłowej realizacji funkcji dla przypadku użycia: przeglądanie katalogu
połączenie ze stroną internetową;
wybranie odpowiedniej kategorii
przeglądanie pozycji wg nazwy artykułu
Scenariusz nieprawidłowej realizacji funkcji dla przypadku użycia: przeglądanie katalogu
brak połączenia z Internetem
nieaktywna strona internetowa firmy
niemożność zalogowania się
brak pozycji w katalogu
Scenariusz prawidłowej realizacji funkcji dla przypadku użycia: zapoznanie się opisem
wybranie interesującej nas pozycji
przeczytanie opisu
Scenariusz nieprawidłowej realizacji funkcji dla przypadku użycia: zapoznanie się opisem
nie otwiera się strona z opisem
brak opisu
Scenariusz prawidłowej realizacji funkcji dla przypadku użycia: logowanie się
wprowadzenie nazwy użytkownika i hasła
sprawdzenie poprawności
akceptacja logowania
Scenariusz nieprawidłowej realizacji funkcji dla przypadku użycia: logowanie się
brak użytkownika w bazie użytkowników systemu
błędny login* lub hasło
Scenariusz prawidłowej realizacji funkcji dla przypadku użycia: wyświetlanie wybranych pozycji:
potwierdzenie prawidłowości wybranych pozycji
Scenariusz nieprawidłowej realizacji funkcji dla przypadku użycia: wyświetlanie wybranych pozycji:
zawieszenie się systemu
3.4. Diagram aktywności systemu
Diagram aktywności ukazuje kolejne etapy, przez które przechodzi przeglądający ofertę firmy.
Klient musi połączyć się ze stroną WWW firmy i zalogować się. Pomyślne połączenie pozwala mu na wybranie odpowiedniej kategorii i przeglądanie oferty firmy.
Rysunek 5. Diagram aktywności systemu (źródło: opracowanie własne),.
3.5. Diagram sekwencji logowanie
Rysunek 6. Diagram sekwencji logowanie (źródło: opracowanie własne),.
Rysunek 7 Diagram: przeglądanie oferty (źródło: opracowanie własne),.
3.6. Przypadki użycia dla klienta
Rysunek 8. Przypadki użycia dla klienta (źródło: opracowanie własne),.
Realizacja projektu
Znając wymagania systemu, można rozpocząć projektowanie wszystkich składników rozwiązania. Najpierw należy wygenerować biblioteki funkcji dla następujących działań:
uwierzytelnienie użytkownika,
sprawdzenie prawidłowości danych,
połączenia z bazą danych,
wyświetlenie wyników w przeglądarce - spójny wygląd wszystkich stron witryny zostanie zrealizowany za pomocą kaskadowych arkuszy stylów (CSS) - ułatwi to ewentualne późniejsze wprowadzanie modyfikacji sposobu prezentacji
Najważniejsze elementy rozwiązania zostaną przedstawione i omówione w dalszej części pracy.
4.1. Implementacja bazy danych
Najpierw utworzona zostanie baza danych MySQL, przeznaczona dla całego projektu. Jest ona niezbędna do działania witryny - w niej przechowywane będą wszystkie informacje dotyczące prezentowanych produktów.
Baza ta mogłaby zawierać bazę, którą nazwałem MainBase, a w niej jedną tablicę zawierającą informację o oferowanych produktach. Kod w języku SQL zastosowany do utworzenia tej bazy oraz tablicy jest przedstawiony poniżej:
create database MainBase;
use MainBase;
CREATE TABLE Products (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Name VARCHAR(24) NOT NULL,
Pict VARCHAR(20) NOT NULL,
Descr_short VARCHAR(255) NOT NULL,
Descr_long VARCHAR(2000) NOT NULL,
Prof_line VARCHAR(20) NOT NULL,
Prod_cat VARCHAR(30) NOT NULL,
Price FLOAT NOT NULL,
Price_lic FLOAT NOT NULL,
Prod_leader VARCHAR(30) NOT NULL,
Producer VARCHAR(100) NOT NULL,
PRIMARY KEY(id) );
Ta sama tablica zaprojektowana w programie DBDesigner 4, wygląda następująco:
Rysunek 9. Wstępny projekt bazy zaprojektowanej w programie DBDesigner 4 (źródło: opracowanie własne),.
Jednakże tak zaprojektowana baza (z tylko jedną tablicą w niej umieszczoną) jest nieefektywna, jeśli chodzi o prędkość działania oraz nieprawidłowa pod względem metodologii tworzenia baz. Dlatego też przeprojektowałem całą bazę tworząc słowniki, które można użyć w tabeli głównej. Kod tworzący tak przeprojektowaną bazę wygląda następująco:
CREATE TABLE Line (
idLine INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
prod_line VARCHAR(20) NOT NULL,
PRIMARY KEY(idLine)
);
CREATE TABLE Producer (
idProducer INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
producer_name VARCHAR(100) NOT NULL,
PRIMARY KEY(idProducer)
);
CREATE TABLE Leader (
idLeader INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
leader_name VARCHAR(20) NOT NULL,
leader_surname VARCHAR(30) NOT NULL,
leader_email VARCHAR(40) NOT NULL,
leader_telephone VARCHAR(20) NOT NULL,
PRIMARY KEY(idLeader)
);
CREATE TABLE Category (
idCategory INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
prod_cat VARCHAR(30) NOT NULL,
PRIMARY KEY(idCategory)
);
CREATE TABLE Products (
idProducts INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Name VARCHAR(40) NOT NULL,
Descr_short VARCHAR(500) NOT NULL,
Descr_long VARCHAR(4000) NOT NULL,
Line_idLine INTEGER UNSIGNED NOT NULL,
Category_idCategory INTEGER UNSIGNED NOT NULL,
Producer_idProducer INTEGER UNSIGNED NOT NULL,
Leader_idLeader INTEGER UNSIGNED NOT NULL,
Price FLOAT NOT NULL,
Price_lic FLOAT NOT NULL,
Pict VARCHAR(20) NOT NULL,
PRIMARY KEY(idProducts),
FOREIGN KEY(Line_idLine)
REFERENCES Line(idLine)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY(Category_idCategory)
REFERENCES Category(idCategory)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY(Producer_idProducer)
REFERENCES Producer(idProducer)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY(Leader_idLeader)
REFERENCES Leader(idLeader)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
Te same tabele zaprojektowane w programie DBDesigner 4, wyglądają następująco:
Rysunek 10. Zmodyfikowany projekt bazy zaprojektowanej w programie DBDesigner 4 (źródło: opracowanie własne),.
Dla potrzeb uwierzytelnionego łączenia się ze stroną utworzyłem także bazę o nazwie Users zawierającą tabelę Users. W bazie tej przechowywane są konta (loginy), hasła oraz imiona, nazwiska i adresy mailowe użytkowników łączących się ze stroną poprzez sieć WWW. Kod w języku SQL zastosowany do utworzenia bazy oraz do utworzenia tablicy użytkowników jest przedstawiony poniżej:
create database Users;
use Users;
CREATE TABLE Users (
idUsers INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Login VARCHAR(15) NULL,
Password VARCHAR(40) NULL,
Name VARCHAR(20) NULL,
Surname VARCHAR(25) NULL,
Email VARCHAR(30) NULL,
PRIMARY KEY(idUsers)
);
Baza Users zaprojektowana w programie DBDesigner 4, wygląda następująco
Rysunek 11. Projekt bazy użytkowników systemu (Users) zaprojektowany w programie DBDesigner 4 (źródło: opracowanie własne),.
Powyższe bazy danych mogą zostać skonfigurowane w systemie w wyniku uruchomienia zbiorów poleceń tylko przez użytkownika MySQL zalogowanego jako root. Można to wykonać wydając polecenia w wierszu poleceń systemu (po zalogowaniu do serwera MySQL).
4.2 Działanie programu z punktu widzenia użytkownika.
Po wejściu na witrynę pokazują się informacje na temat oferowanych przez firmę linii produktów.
Rysunek 12. Strona startowa witryny (źródło: opracowanie własne),.
Aby uzyskać bardziej szczegółowe informacje należy być zarejestrowanym użytkownikiem posiadającym login i hasło. Login i hasło wprowadza się po wybraniu z menu pozycji Logowanie.
Rysunek 13. Strona logowania (źródło: opracowanie własne),.
Jeśli podany login nie istnieje w bazie użytkowników pojawi się stosowny komunikat informujący o tym fakcie.
Rysunek 14. Strona informująca o braku podanego u użytkownika w bazie Users (źródło: opracowanie własne),.
Jeśli podany login istnieje w bazie użytkowników, ale zostanie wprowadzone niepoprawne hasło, próbujący zalogować się, zostanie o tym poinformowany i poproszony o powtórzenie próby logowania.
Jeśli zostanie wprowadzony poprawny login i hasło …
Rysunek 15. Strona logowania z wpisami w polach użytkownik i hasło (źródło: opracowanie własne),.
.. użytkownik zostanie zalogowany i wyświetli się strona podobna do strony startowej.
W każdym momencie nawigowania po witrynie istnieje możliwość wysłania wiadomości e-mail'owej do właściciela witryny.
W tym celu należy z menu górnego wybrać pozycję Kontakt. Po wybraniu tej pozycji uruchomiony zostanie domyślny (ustawiony w systemie operacyjnym użytkownika) klient pocztowy z wypełnionym polem Do oraz wstępnie wypełnionym polem Temat.
Rysunek 16. Uruchomiony klient pocztowy z wiadomością zaadresowaną do właściciela witryny (źródło: opracowanie własne).
Powracając do opisu działania programu po pomyślnym zalogowaniu: wyświetlona strona daje możliwość dalszego nawigowania w serwisie.
Rysunek 17. Strona pokazująca linie produktów (źródło: opracowanie własne),.
Różnica pomiędzy stroną startową, a stroną wyświetloną po zalogowaniu, polega na tym, że z tej ostatniej, można, za pomocą odnośników umieszczonych przy opisie linii produktów, przejść do opisu produktów dostępnych w wybranej linii produktów.
Poniżej, dla przykładu, przedstawiony jest zrzut ekranu prezentującego produkty linii Premium.
Rysunek 18. Strona pokazująca informacje na temat programów z wybranej linii produktowej (źródło: opracowanie własne).
Z tego ekranu po kliknięciu na odnośniki umieszczone z prawej strony opisu każdego programu („>>>”) można przejść do prezentacji rozszerzonej informacji na temat wybranego produktu. Jest tu zamieszczony dokładniejszy opis cech wybranego programu, dane osoby, która z ramienia firmy jest opiekunem danej linii produktów oraz informacje pozwalające skontaktować się z tą osobą (telefon i adres e-mail'owy).
Rysunek 19. Strona prezentująca rozszerzoną informacją na temat wybranego programu (źródło: opracowanie własne).
Podsumowanie
Celem niniejszej pracy było zaprojektowanie witryny internetowej prezentującej produkty firmy software'owej.
Z założonego zakresu wyjściowego projektu pracy zrealizowane zostały wszystkie funkcjonalności i cele. Aplikacja umożliwia użytkownikom Internetu zapoznanie się z produktami firmy software'owej.
Aby było to możliwe skorzystałem z wybranych przeze mnie programów typu Open Source::
serwera stron WWW - Apache;
systemu baz danych MySQL;
oraz wykorzystałem języki PHP i HTML, aby napisać kod obsługujący witrynę WWW.
Użytkownicy witryny maja możliwość, po połączeniu się z witryną WWW,, uzyskać informacje na temat produktów firmy. System oferuje także możliwość łatwego kontaktu z firma poprzez użycie drogi mailowej. Zainteresowani konkretnym produktem mają możliwość uzyskania niezbędnych danych (imienia, nazwiska, telefonu, adresu mailowego) osoby sprawującej pieczę nad wybranym produktem firmy.
Bibliografia
Ken Elizabeth Naramore, Jason Gerner, Yann Le Scouranec, Jeremy stolz, Michael K. Glass: PHP, Apache i My SQL. Od podstaw. Tworzenie dynamicznych witryn WWW za pomocą technologii open source, Wydawnictwo Helion, Gliwice 2005
John Coggeshall: PHP5. Księga eksperta, Wydawnictwo Helion, Gliwice 2005.
Luke Welling, Laura Thomson: PHP i MySQL. Tworzenie stron WWW. Vademecum profesjonalisty. Wydanie trzecie, Wydawnictwo Helion, Gliwice 2005.
Julie Meloni: PHP. Pisanie dynamicznych stron WWW. Wydawnictwo MIKOM, Warszawa 2004.
Russel J.T. Dyer: MySQL Almanach. WWW, Wydawnictwo Helion, Gliwice 2006.
Eric A. Meyer: CSS. Kaskadowe arkusze stylów. Przewodnik encyklopedyczny, Wydawnictwo Helion, Gliwice 2008.
Marcin Lis: PHP. 101 praktycznych skryptów, Wydawnictwo Helion, Gliwice 2003.
Rachel Andrew: 101 wskazówek i trików. CSS. Antologia, Wydawnictwo Helion, Gliwice 2005.
Bartosz Danowski: Tworzenie stron WWW w praktyce. Wydanie drugie., Wydawnictwo Helion, Gliwice 2008.
http://pl.wikipedia.org/
Spis rysunków
Rysunek 1. Zasada wyświetlania w przeglądarce strony stworzonej w języku PHP (źródło: opracowanie własne),.
Załączniki
Kod źródłowy aplikacji
Poniżej jest przedstawiony kod źródłowy napisanej przeze mnie aplikacji „Witryna internetowa firmy software'owej”. Listing jest przedstawiony w rozbiciu na poszczególne pliki, niezbędne do działania tej witryny.
index.php
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<meta name="Description" content="Opis zawarto¶ci strony" />
<meta name="Keywords" content="Wyrazy kluczowe" />
<meta name="Author" content="Jacek Goclik" />
<title>Witryna WWW</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"
</head>
<frameset rows="120,90,*" border="0" frameborder="0" framespacing="0">
<frame name="spis" noresize="noresize" frameborder="0" src="logo.php" />
<frame name="spis" noresize="noresize" frameborder="0" src="menu.php" />
<noframes><body><a href="menu.php">Menu</a></body></noframes>
<frame name="strona" noresize="noresize" frameborder="0" src="home.php" />
</frameset>
</html
logo.php
-------------------------------------------------------------------
<!doctype html
public "-//w3c//dtd xhtml 1.0 transitional//en"
"http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-2" />
<meta name="author" content="Jacek Goclik" />
<title>strona główna</title>
<link rel="stylesheet" type="text/css" href="../css/style.css"
</head>
<body>
<p>
<center><img src="../img/logo.gif" ><!--alt="Sage Symfonia"--></center>
</p>
</body>
</html>
menu.php
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<meta name="Author" content="Jacek Goclik" />
<title>Menu</title>
<link rel="stylesheet" type="text/css" href="../css/style.css"
</head>
<body>
<!--<h4>Menu nawigacyjne</h2> -->
<div id="nawigacja">
<ul>
<li><a target="strona" href="home.php">Strona główna</a></li>
<li><a target="strona" href="login2.html">Logowanie</a></li>
<li><a target="strona" href="mailto:biuro@symfonia.pl?subject=Szanowni Państwo ...">Kontakt</li>
</ul>
</div>
</body>
</html>
home.php
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<meta name="Author" content="Jacek Goclik" />
<title>Strona główna</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"
</head>
<body>
<?php
//poł±czenie z serwerem i sprawdzenie czy sie powiodło
if(!($dbLink2 = mysql_pconnect("localhost", "root", "jacek")))
{
print("Nie można poł±czyć się z baz±!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
//wybór bazy danych i sprawdzenie rezultatów operacji
if(!mysql_select_db("MainBase", $dbLink2))
{
print("Nie można wybrać bazy test!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
// pobranie całej zawarto¶ci tabeli
$Query = "SELECT prod_line, Line_descr, idLine ";
$Query .= "FROM Line ";
if(!($dbResult = mysql_query($Query, $dbLink2)))
{
print("Nie można wykonać zapytania!<BR>\n");
print("komunikat MySQL: " . mysql_error() . "<BR>\n");
print("Zapytanie:$Query<BR>\n");
exit();
}
//pocz±tek tabeli
print("<TABLE BORDER=\"0\" align=center WIDTH=70%>\n");
print("<TR align=center><TD align=center WIDTH=30%>Linia</TD><TD align=center WIDTH=60%>Opis</TD><TD align=center>Link</TD></TR>");
// pobranie każdego z wierszy z bazy
while($dbRow = mysql_fetch_object($dbResult))
{
$pr_line=$dbRow->prod_line;
$descr.=$dbRow->Line_descr;
$id.=$dbRow->idLine;
echo ("<TR><TD align=center><h2>$pr_line</h2></TD><TD>");
echo ("$descr</TD><TD align=center>");
print("</TD><</TR>\n");
$descr="";
$id="";
print("<TR HEIGHT=80><TD></TD><TD></TD></TR>");
}
//koniec tabeli
print("</TABLE>\n");
@mysql_close ($dbLink2);
?>
</body>
</html>
login2.hrml
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<meta name="Author" content="Jacek Goclik" />
<title>Strona główna</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"
</head>
<body>
<form action="login.php" method="post">
<table border=1 align="center" cellpadding=5 cellspacing=1>
<tr><td>Użytkownik:</td>
<td><input type="text" name="login" size=15 maxlength=15></td></tr>
<tr><td>Hasło:</td>
<td><input type="password" name="pass" size=15 maxlength=15></td></tr>
<tr>
<td align="center" colspan=2><input type="submit" name="wyslij" value="zaloguj"></td></tr>
</table>
</form>
</body>
</html>
login.php
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<meta name="Author" content="Jacek Goclik" />
<title>Strona główna</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"
</head>
<?php
$user=$_POST[login];
$passw=$_POST[pass];
include './conn/config.php';
//poł±czenie z serwerem i sprawdzenie czy sie powiodło
if(!($dbLink = mysql_pconnect($dbhost, $dbuser, $dbpass)))
{
print("Nie można poł±czyć się z baz±!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
//wybór bazy danych użytkowników i sprawdzenie rezultatów operacji
if(!mysql_select_db("users", $dbLink))
{
print("Nie można wybrać bazy users!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
// pobranie rekordu z tabeli dla podanego uzytkownika
$Query = "SELECT login, password ";
$Query .= "FROM users ";
$Query .= "WHERE login='";
$Query .= $user;
$Query .= "'";
if(!($dbResult = mysql_query($Query, $dbLink)))
{
print("Nie można wykonać zapytania!<BR>\n");
print("komunikat MySQL: " . mysql_error() . "<BR>\n");
print("Zapytanie: $Query<BR>\n");
exit();
}
// pobranie rekordu z bazy
$jest=False;
while($dbRow = mysql_fetch_object($dbResult))
{
$jest=True; # ustawia zmienn± logiczn± $JEST na TRUE jesli znajdzie login w tablicy users podany podczas logowania
if (sha($passw)==sha($dbRow->password)) { # jesli podane haslo zgodne jest z odczytanym z tablicy UZYYTKOWNICY to:
include ("wylistuj_linie.php");
else { #jesli podane haslo nie jest zgodne z odczytanym z tablicy users to:
echo ("Niepoprawne hasło <br>Spróbuj jeszcze raz");
}
}
if (!$jest) # gdy loginu nie ma w bazie users
if ($user==NULL) {echo ("Musisz podac jakis login"); # jesli w ogóle nie podano loginu
}
else { # jesli podanego loginu nie ma w tablicy users
echo ("Podanego użytkownika nie ma w bazie ");
}
@mysql_close ($dbLink);
?>
config.php
-------------------------------------------------------------------
<?php
$dbhost = 'localhost';
$dbuser = 'common_user';
$dbpass = 'passw';
?>
wylistuj_linie.php
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<meta name="Author" content="Jacek Goclik" />
<title>Strona główna</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"
</head>
<body>
<?php
include './conn/config.php';
//poł±czenie z serwerem i sprawdzenie czy sie powiodło
if(!($dbLink2 = mysql_pconnect($dbhost, $dbuser, $dbpass)))
{
print("Nie można poł±czyć się z baz±!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
//wybór bazy danych i sprawdzenie rezultatów operacji
if(!mysql_select_db("MainBase", $dbLink2))
{
print("Nie można wybrać bazy test!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
// pobranie całej zawarto¶ci tabeli
$Query = "SELECT prod_line, Line_descr, idLine ";
$Query .= "FROM Line ";
// $Query .= "WHERE Category_idCategory=2";
// $Query .= $kat;
// $Query .= "'";
if(!($dbResult = mysql_query($Query, $dbLink2)))
{
print("Nie można wykonać zapytania!<BR>\n");
print("komunikat MySQL: " . mysql_error() . "<BR>\n");
print("Zapytanie:$Query<BR>\n");
exit();
}
//pocz±tek tabeli
print("<TABLE BORDER=\"0\" align=center WIDTH=70%>\n");
print("<TR align=center><TD align=center WIDTH=30%></TD><TD align=center WIDTH=60%></TD><TD align=center></TD></TR>");
// pobranie każdego z wierszy z bazy
while($dbRow = mysql_fetch_object($dbResult))
{
$pr_line="Symfonia (R) ".$dbRow->prod_line;
$descr.=$dbRow->Line_descr;
$id.=$dbRow->idLine;
echo ("<TR><TD align=center><h2>$pr_line</h2></TD><TD>");
echo ("$descr</TD><TD align=center>");
// echo ("<A HREF=wylistuj_programy_$id.php>pokaż</TD></TR>");
echo ("<A HREF=wylistuj_programy.php?lid=$id>pokaż</TD></TR>");
print("</TR>\n");
$descr="";
$id="";
print("<TR HEIGHT=80><TD></TD><TD></TD></TR>");
}
//koniec tabeli
print("</TABLE>\n");
@mysql_close ($dbLink2);
?>
</body>
</html>
wylistuj_programy.php
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<meta name="Author" content="Jacek Goclik" />
<title>Strona główna</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"
</head>
<body>
<?php
//połączenie z serwerem i sprawdzenie czy sie powiodło
include './conn/config.php';
if(!($dbLink3 = mysql_pconnect($dbhost, $dbuser, $dbpass)))
{
print("Nie można połączyć się z bazą!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
//wybór bazy danych i sprawdzenie rezultatów operacji
if(!mysql_select_db("MainBase", $dbLink3))
{
print("Nie można wybrać bazy $dbLink3!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
// pobranie całej zawartości tabeli
$Query = "SELECT Name, Descr_short, Pict, idProducts ";
$Query .= "FROM Products WHERE Line_idLine=$lid";
if(!($dbResult = mysql_query($Query, $dbLink3)))
{
print("Nie można wykonać zapytania!<BR>\n");
print("komunikat MySQL: " . mysql_error() . "<BR>\n");
print("Zapytanie: $Query<BR>\n");
exit();
}
//początek tabeli
print("<TABLE BORDER=\"0\" align=center WIDTH=70%>\n");
print("<TR align=center><TD align=center WIDTH=10%><TD align=center WIDTH=30%></TD><TD align=center WIDTH=50%></TD><TD align=center></TD></TR>");
// pobranie z tablicy każdego z wierszy spełniającego warunek
while($dbRow = mysql_fetch_object($dbResult))
{
$pr_name=$dbRow->Name;
$descr.=$dbRow->Descr_short;
$pr_pict="./img/".($dbRow->Pict);
$id.=$dbRow->idProducts;
echo ("<TR><TD align=center><IMG SRC=$pr_pict></TD>");
echo ("<TD align=center><h2>$pr_name</h2></TD><TD>");
echo ("$descr</TD><TD align=center>");
// echo ("<A HREF=$id>pokaż</TD></TR>");
//<a href="nowa_strona.htm" target="_blank">Otwórz w nowym oknie</a>
echo ("<A HREF=wylistuj_program.php?pid=$id>>>></TD></TR>");
// echo ("<A HREF=wylistuj_program.php?pid=$id target="_blank">pokaż</TD></TR>");
print("</TR>\n");
$descr="";
$id="";
print("<TR HEIGHT=80><TD></TD><TD></TD></TR>");
}
//koniec tabeli
print("</TABLE>\n");
@mysql_close ($dbLink3);
?>
</body>
</html>
wylistuj_program.php
-------------------------------------------------------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1250">
<meta name="Author" content="Jacek Goclik" />
<title>Strona główna</title>
<link rel="stylesheet" type="text/css" href="./css/style.css"
</head>
<body>
<?php
//połączenie z serwerem i sprawdzenie czy sie powiodło
include './conn/config.php';
if(!($dbLink3 = mysql_pconnect($dbhost, $dbuser, $dbpass)))
{
print("Nie można połączyć się z bazą!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
//wybór bazy danych i sprawdzenie rezultatów operacji
if(!mysql_select_db("MainBase", $dbLink3))
{
print("Nie można wybrać bazy $dbLink3!<BR>\n");
print("Zakończenie skryptu!<BR>\n");
exit();
}
// pobranie wybranych pól z tablicy
$Query = "SELECT Name, Descr_long, Producer_idProducer, Leader_idLeader, Pict ";
$Query .= "FROM Products WHERE idProducts=$pid";
if(!($dbResult = mysql_query($Query, $dbLink3)))
{
print("Nie można wykonać zapytania!<BR>\n");
print("komunikat MySQL: " . mysql_error() . "<BR>\n");
print("Zapytanie: $Query<BR>\n");
exit();
}
//początek tabeli
print("<TABLE BORDER=\"0\" align=center WIDTH=70%>\n");
print("<TR align=center><TD align=center WIDTH=80%></TD></TR>");
// pobranie żadanych wierszy z bazy
while($dbRow = mysql_fetch_object($dbResult))
{
$pr_pict="./img/".($dbRow->Pict);
$pr_name=$dbRow->Name;
$descr=$dbRow->Descr_long;
$pr_leader=$dbRow->Leader_idLeader;
// pobranie z balicy wybranego pola zawierającego informacje o opiekunie linii produktowej
$Query2 = "SELECT leader_name, leader_surname, leader_email, leader_telephone ";
$Query2 .= "FROM Leader WHERE idLeader=1";
if(!($dbResult2 = mysql_query($Query2, $dbLink3)))
{
print("Nie można wykonać zapytania!<BR>\n");
print("komunikat MySQL: " . mysql_error() . "<BR>\n");
print("Zapytanie: $Query<BR>\n");
exit();
}
{
$dbResult2 = mysql_query($Query2, $dbLink3);
$dbRow2 = mysql_fetch_object($dbResult2);
$lead_name = $dbRow2->leader_name;
$lead_name .= " ";
$lead_name .= $dbRow2->leader_surname;
$lead_email = $dbRow2->leader_email;
$lead_phone = $dbRow2->leader_telephone;
}
echo ("<TR><TD align=center><h2>$pr_name</h2></TD></TR>");
echo ("<TR><TD align=center><IMG SRC=$pr_pict></TD></TR>");
echo ("<TR><TD align=center>$descr</TD></TR>");
echo ("<TR><TD align=center>...</TD></TR>");
echo ("<TR><TD align=center></TD></TR>");
echo ("<TR><TD align=center>Osoba, która udzieli Państwu szczegółowych informacji</TD></TR>");
echo ("<TR><TD align=center>$lead_name</TD></TR>");
echo ("<TR><TD align=center>$lead_email</TD></TR>");
echo ("<TR><TD align=center>$lead_phone</TD></TR>");
}
//koniec tabeli
print("</TABLE>\n");
@mysql_close ($dbLink3);
?>
</body>
</html>
style.css
-------------------------------------------------------------------
<!DOCTYPE html
body {
background-color: lightgreen;
}
body.html.#nawigacja {
min-height:100%;
height:100%;
}
h2 {color:green;}
#nawigacja {
font-family: Arial, Helvetica, sans-serif;
font-size: .9em;
background-color:ligthgreen;
margin-left:300px;
margin-right:000px;
margin-top:2px;
padding-top:10px;
padding-bottom:10px
position:absolute;
bottom:0;
}
#nawigacja_pro {
font-family: Arial, Helvetica, sans-serif;
font-size: .9em;
background-color:ligthgreen;
margin-left:300px;
margin-right:300px;
margin-top:2px;
margin-bottom:2px;
padding-top:10px;
padding-bottom:10px
position:absolute;
bottom:0;
}
#nawigacja ul {
list-style: none;
margin: 0;
padding: 0;
padding-top: 4px;
}
#nawigacja li {
display: inline;
}
#nawigacja_pro ul {
list-style: none;
margin: 0;
padding: 0;
padding-top: 4px;
}
#nawigacja_pro li {
display: compact;
}
#nawigacja a:link, #nawigacja a:visited {
margin-right: 40px;
padding: 600px 50px 300px 50px;
color: green;
background-color: lightgreen;
text-decoration: none;
border-top: 2px solid lightgreen;
border-left: 2px solid lightgreen;
border-bottom: 2px solid lightgreen;
border-right: 2px solid lightgreen;
}
#nawigacja a:hover {
background-color: white;
color: brown;
border-top: 2px solid #FFFFFF;
border-left: 2px solid #FFFFFF;
border-bottom: 2px solid #FFFFFF;
border-right: 2px solid #FFFFFF;
}
table,td {font-family:Arial, Helvetica, sans-serif; font-size:14px; color:green}
.tab {border:1px dotted #6fff6f;width:90%;background:#8fff8f}
* Patrz: słownik pojęć
http://opensource.org/docs/definition.php
http://www.opensource.org
* Patrz: słownik pojęć
http://news.netcraft.com/archives/2008/06/22/june_2008_web_server_survey.html (June 2008 Web Server Survey. In the June 2008 survey we received responses from 172,338,726 sites. Microsoft's IIS web server grows by 2 million sites, boosting market share by 0.36%, but Apache remains in the lead with a total of 49.1%.)
* Patrz: słownik pojęć
* Patrz: słownik pojęć
relacja - zależność między dwoma bądź większą liczbą elementów (podmiotów, przedmiotów, cech, obiektów matematycznych, itp.); w modelu relacyjnym baz danych "relacja" to formalne określenie tabeli
* Patrz: słownik pojęć
* Patrz: słownik pojęć
* Patrz: słownik pojęć
* Patrz: słownik pojęć