PHP/Studium przypadku/System newsów: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
m +wymaga dopracowania |
rozpoczęcie przepisywania |
||
Linia 1:
{{prognav|PHP|phpMyAdmin|Bazy danych - co dalej?}}
== System newsów ==
Spróbujmy teraz zaimplementować zdobytą przez nas wiedzę w praktyce. Napiszemy prosty system newsów z podziałem na kategorie i możliwością dodawania komentarzy. Podręcznik ten pokaże, jak zacząć, natomiast twoim zadaniem będzie dopisanie (z pomocą wskazówek) wszystkich dodatków niezbędnych do tego, aby system był w pełni funkcjonalny. Nowością w porównaniu do księgi gości będzie to, iż nie będziemy już umieszczać kodu HTML bezpośrednio we właściwym pliku, lecz umieścimy go jako zbiór funkcji w osobnym. Dzięki temu poprawi się czytelność kodu, a ty poznasz zalety separacji tych dwóch elementów jeszcze przed przejściem do omawiania systemów szablonów.
=== Projekt bazy danych ===
System newsów oparty będzie o bazę danych MySQL, w której ulokujemy trzy tabelki. Będą one połączone ze sobą relacją jeden do wielu:
# Istnieje grupa kategorii
# Każda kategoria może zawierać dowolną liczbę newsów, ale pojedynczy news może należeć tylko do jednej z nich.
# Każdy news może zawierać dowolną ilość komentarzy.
Układ tabelek zostanie tak zoptymalizowany, aby jak najrzadziej zmuszać bazę do wykonywania funkcji ''COUNT()'' w celu zliczenia ilości wpisów.
Zacznijmy od tabeli kategorii:
<nowiki>CREATE TABLE
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin2;</nowiki>
Oprócz typowych pól informacyjnych: '''title''' oraz '''description''' (tytuł i opis), mamy też pole '''news_num''' przechowujące aktualną liczbę newsów wewnątrz kategorii. Musimy pamiętać, aby nasz system poprawnie zmniejszał i zwiększał jego zawartość w trakcie edycji i wprowadzania nowych elementów do bazy.
Następne w kolejności są newsy:
<nowiki>CREATE TABLE `news` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(128) NOT NULL,
`body` text NOT NULL,
`date` int(11) NOT NULL,
`author` varchar(30) NOT NULL,
`category_id` int(11) NOT NULL,
`comment_num` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin2;</nowiki>
Tabela zaczyna się od pól informacyjnych. Z punktu widzenia projektanta bazy najistotniejsze są jednak dwa ostatnie. '''category_id''' przechowuje ID kategorii, do której należy news; w tym miejscu tworzymy naszą relację. '''comment_num''' działa na podobnej zasadzie, jak w kategoriach. Dzięki temu nie trzeba będzie wykonywać skomplikowanych zapytań przy pobieraniu listy newsów, aby pokazać tam jednocześnie ilość komentarzy.
Na samym końcu zapoznamy się z tabelą komentarzy:
<nowiki>CREATE TABLE `comments` (
`id` int(11) NOT NULL auto_increment,
`news_id` int(11) NOT NULL,
`author` varchar(30) NOT NULL,
`date` int(11) NOT NULL,
`body` text NOT NULL,
PRIMARY KEY (`id`),
KEY `news_id` (`news_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=latin2;</nowiki>
Zwróć uwagę, w jaki sposób założony jest podwójny indeks na pola '''news_id''' oraz '''date'''. Gdyby utworzyć tutaj dwa osobne indeksy, w zasadzie nic byśmy nie uzyskali. Popatrzmy na to tak: nigdy nie wyświetlamy wszystkich komentarzy, jakie mamy w bazie. Zawsze są one powiązane z jakimś konkretnym newsem, dlatego tak istotne jest odzwierciedlenie tego w strukturze indeksów. Przy osobnych indeksach pole '''date''' zostanie posortowane globalnie, a wybierając komentarze tylko dla pojedynczego newsa, system DB i tak będzie musiał przeskanować całą tabelę, aby je względem tejże daty wybrać.
Od strony bazy danych to tyle. Przejdźmy do kodowania.
=== Funkcje podstawowe ===
Napiszemy teraz plik ''functions.php''. Umieścimy w nim różne podstawowe funkcje. W tej chwili jest ich stosunkowo niewiele: łączenie się z bazą, kontrola długości wprowadzonego tekstu, prymitywne zabezpieczenie przed floodem. Plik ten przyda Ci się jednak podczas samodzielnej rozbudowy; prawdopodobnie rozrośnie się wtedy znacznie. Jego zawartość wygląda następująco:
<nowiki><?php
function initSystem()
{
global $sql;
$sql = new pdo('host=localhost;port=3305;dbname=artykuly', 'root', 'root');
$sql -> exec('SET NAMES `latin2`');
ob_start();
} // end initSystem();
function doneSystem()
{
ob_end_flush();
} // end doneSystem();
function commentsAllowed()
{
if(isset($_COOKIE['a84skljf']))
{
return false;
}
setcookie('a84skljf', 1, time() + 3600);
return true;
} // end commentsAllowed();
function validTextField($text, $min, $max)
{
if(strlen($text) > $min && strlen($text) < $max)
{
return true;
}
return false;
} // end validTextField();
?></nowiki>
Opis poszczególnych funkcji:
# ''initSystem()'' - inicjacja systemu; nawiązuje połączenie z bazą danych i włącza buforowanie wyjścia.
# ''doneSystem()'' - aktualnie tylko kończy buforowanie wyjścia. Być może znajdziesz dla niej jakieś ciekawe dodatkowe zastosowania.
# ''commentsAllowed()'' - funkcja zwraca '''true''', jeżeli internauta ma prawo dodawać komentarze i '''false''', jeżeli już takowy niedawno dodał.
# ''validTextField()'' - prosta funkcja do kontroli danych. Zwraca '''true''', jeżeli długość tekstu mieści się w podanym zakresie.
=== DAO ===
=== Kod HTML ===
=== Składamy system w całość ===
=== Ćwiczenia ===
=== Zakończenie ===
|