CompZone.Org :: Artykuły :: PHP
Pytania w drugiej edycji Testu PHP powinny być:
Trudniejsze
Łatwiejsze
Skomplikowane
Na myślenie
Do liczenia
Sonda Wyniki

Add to Google

Księga gości w oparciu o Smarty

Często na stronach można spodkać księgi gości. Są to bardzo proste skrypty, które umożliwiają zostawianie informacji o sobie oraz krótki komentarz. Z tego artykułu dowiemy się w jaki sposób w oparciu o Smarty napisać taki skrypt.

Smarty

Smarty jest biblioteką szablonów umożliwiającą oddzielenie kodu PHP od wyglądu strony. W tym artykule zakładam podstawową znajomość Smarty. Wszystkich, którzy pierwszy raz stykają się ze smarty odsyłam do artykułu: Smarty - Instalacja

Baza danych

W naszym skrypcie używać będziemy bazy mysql. W tej bazie utworzymy tylko jedną tabelę entries, w której przechowywać będziemy wpisy. Każdy wpis będzie składał się z tytułu i treści oraz autora. Opcjonalne będą pola e-mail oraz strona WWW. Polecenie SQL tworzące tę tabelę widzimy poniżej.

  
CREATE TABLE entries(
id integer PRIMARY KEY auto_increment,
title varchar(150),
body text,
author varchar(50),
website varchar(100),
email varchar(100),
publish_date integer
);

Kod PHP strony

Utworzymy teraz plik db.php. Będzie on odpowiedzialny za komunikacje z bazą. Dodatkowo zaimplementujemy funkcję pobierającą wszystkie wpisy z zapytania do tablicy. Kod tego pliku przedstawia poniższa ramka.

  
<?php

$dbconfig = array(
'host' =>'localhost',
'user' =>'root',
'pass' =>'',
'dbname'=>'guestbook'
);

$db = mysql_connect($dbconfig['host'], $dbconfig['user'], $dbconfig['pass']);
mysql_select_db($dbconfig['dbname'], $db);

function db_fetch_all($sql){
global $db;

$query = mysql_query($sql);

$rows = array();

while(($row = mysql_fetch_array($query))!= null){
$rows[] = $row;
}

return $rows;

}

?>

W pliku index.php zawrzemy inicjacje obiektu smarty wraz z ustawieniem pewnych parametrów.

  
<?php

require_once('db.php');


require_once('smarty/Smarty.class.php');

$smarty = new Smarty();
if(isset($_POST['title'])){
$title = mysql_escape_string($_POST['title']);
$body = mysql_escape_string($_POST['body']);
$author = mysql_escape_string($_POST['author']);
$website = mysql_escape_string($_POST['website']);
$email = mysql_escape_string($_POST['email']);
mysql_query('Insert into entries(title, body, author, website, email, publish_date)
values("
'.$title.'", "'.$body.'", "'.$author.'", "'.$website.'", "'.$email.'", '.time().')', $db);
$smarty->assign('entry_added', true);
}

$entries = db_fetch_all('SELECT * FROM entries');

$smarty->compile_dir = 'var/compile';
$smarty->cache_dir = 'var/cache';
$smarty->assign_by_ref('entries', $entries);
$smarty->display('index.tpl');


?>

Na początku skryptu dołączamy odpowiednie pliki. Trzeba zwrócić uwagę, że ścieżka do pliku Smarty.class.php może się różnić, w zależności od tego gdzie zainstalujemy Smarty.

Dalej następuje sprawdzenie czy dane zostały przesłane metodą POST. Jeśli przesłano metodą post tytuł (zakładamy umownie, że tyle jest wymagane), to dodajemy wpis do bazy.

Przed sprawdzeniem czy powinniśmy dodać wpis do bazy nastąpiło stworzenie obiektu klasy Smarty. Po ewentualnym dodaniu wpisu do bazy następuje ustawienie zmiennej entry_added na wartość true. W ten sposób wyświetlimy informacje o dodaniu wpisu. Dalej pobieramy wszystkie wpisy z bazy do zmiennej $entries. Następnie ustawiamy katalogi kompilacji szablonów i cache'owania szablonów. Moglibyśmy ustawić także inny katalog przechowywania szablonów (zmienna template_dir), jednak w tym przypadku katalog templates jest dobrym wyborem. Na końcu następuje przypisanie przez referencje wpisów. Aby przypisać przez referencje używamy funkcji assign_by_ref. Dzięki temu oszczędzamy pamięć. Gdybyśmy, przekazywali zmienną $entries funkcją assign, skrypt musiałby utworzyć sobie lokalną kobie tej tablicy. W przypadku dużych tablic polecam używać funkcji assign_by_ref.

Tworzymy szablon

Teraz zajmiemy sie szablonem. Tutaj nauczymy się wykorzystywania pętli foreach, kilku modyfikatorów zmiennych i instrukcji warunkowej if. Popatrzmy na kod szablonu (plik templates/index.tpl).

  
<html>
<head>
<title>Moja księga gości</title>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=iso-8859-2"/>
<style>
{literal}
p{
font-size: 12pt;
font-family: Verdana,Arial;
}

.small{
font:8pt bold Verdana;
color:rgb(144,144,144);
margin: 0 0 0 0;
}
.author{
color: rgb(54,54,54);
font-size:8pt;
font-style:italic;
}
h2{
background: rgb(200,200,200);
color: rgb(54,54,54);
font-variant:
margin-bottom: 0;
}
input, textarea{
border: 1px solid black;
margin: 1px 0 1px 0;
}
{/literal}
</style>
<body>
{if $entry_added}
<p><b>Dodano wpis!</b></p>{/if}
{foreach from=$entries item=entry}
<h2>{$entry.title|escape:"htmlall"}</h2>
<p class="small">{if $entry.website != ''}<a href="{$entry.website|escape:"url"}">{$entry.website|escape:"htmlall"}</a>{/if}</p>
<p class="small">{$entry.email|escape:"mail"|default:"brak"}</p>
<p>{$entry.body|escape:"htmlall"}</p>
<p class="author">{$entry.author|escape:"htmlall"}, {$entry.publish_date|date_format:"%d-%m-%y %H:%M:%S"}</p>
<hr>
{foreachelse}
<p>Nie dodano żanych wpisów</p>
{/foreach}

<form action="#" method="post">
<input type="textbox" name="title" style="width:400px" /><br />
<textarea rows="8" style="width:400px" name="body"></textarea><br />
Autor:
<input type="textbox" name="author" style="width:300px" /><br />
Strona WWW:
<input type="textbox" name="website" style="width:300px" /><br />
E-mail:
<input type="textbox" name="email" style="width:300px" /><br />
<input type="submit" value="Dodaj wpis">
</form>
</body>
</html>

Widzimy, że na samej górze, tuż po tagu <style> otwieramy blok {literal}. Blok ten zamykamy tuż przez tagiem </style>. Otwarcie tego boku powoduje zaniechania kompilacji tego kawałka i wstawienia go do szablonu jako tekst. Dzięki temu parser Smarty nie będzie stwierdzał błędu, gdy otwieramy wpisy css { i zamykamy }. Gdyby nie ten blok parser Smarty wskazałby błąd. Jeżeli na stronie musimy, często używać znaków { i }, łatwiej będzie zmienić znaki ograniczające wyrażenia Smarty. Aby to uczynić ustawiamy polom left_delim i right_delim inne wartości niż standardowe { i }.

Dalej widzimy wykorzystanie bloku if. Dzięki temu blokowi możemy wykonać instrukcje tylko gdy warunek jest spełniony. W tym przypadku wyświetlimy informacje o dodanym wpisie, tylko wówczas, gdy $entry_added zostało ustawione na true (patrz plik index.php). Poniżej warunku if znajduje się pętla foreach. Przyjmuje ona 2 parametry. Parametr from określa zmienną, którą chcemy iterować. Parametr item określa nazwę iteratora. W bloku foreach używamy iteratora jak normalną zmienną. Przy wypisywaniu tytułu używamy modyfikatora escape z parametrem "htmlall", dzięki czemu zabezpieczamy się przed atakami XSS. Podobnie postępujemy ze wszystkimi innymi zmiennymi. Warto zwrócić uwagę, na parametr modyfikatora "email", który zamienia @ na [AT] i . na [DOT]. O wszystkich parametrach można przeczytać w manualu. Ciekawym modyfikatorem jest default, który określa wartość domyślną, jeśl zmienna nie została ustawiona.

Bardzo istotnym i przydatnym modyfikatorem jest date_format, który zamienia uniksowy znacznik czasu (zwracany m.in. przez funkcje time) na postać tekstową. Modyfikator ten działa podobnie jak funkcja date, jednak należy uważać, ponieważ niektóre parametry mają inne znaczenie.

Ciekawą opcją Smarty jest możliwość umieszczenie bloku foreachelse. Jest on opcjonalny i umożliwia on wyświetlenie informacji, gdy tablica jest pusta. Dzięki temu nie trzeba przed każdym blokiem foreach wstawiać ifa sprawdzającego czy tablica jest pusta.

Stronicowanie danych

Każda dobra księga gości musi mieć stronicowanie. Dzięki stronicowaniu nauczymy się kilku ciekawych rzeczy. Oto kod PHP zmodyfikowanego pliku index.php

  
<?php

require_once('db.php');


require_once('smarty/Smarty.class.php');

$smarty = new Smarty();
if(isset($_POST['title'])){
$title = mysql_escape_string($_POST['title']);
$body = mysql_escape_string($_POST['body']);
$author = mysql_escape_string($_POST['author']);
$website = mysql_escape_string($_POST['website']);
$email = mysql_escape_string($_POST['email']);
mysql_query('Insert into entries(title, body, author, website, email, publish_date)
values("
'.$title.'", "'.$body.'", "'.$author.'", "'.$website.'", "'.$email.'", '.time().')', $db);
$smarty->assign('entry_added', true);
}


$page = 1;
if(isset($_GET['page'])) $page = (int)$_GET['page'];

$perPage = 1;
$offset = ($page - 1)*$perPage;

$entries = db_fetch_all('SELECT * FROM entries LIMIT '.$offset.', '.$perPage);
$pages = mysql_result(mysql_query('SELECT count(*) from entries'),0,0);
$pages /= $perPage;

$smarty->compile_dir = 'var/compile';
$smarty->cache_dir = 'var/cache';
$smarty->assign('entries', $entries);
$smarty->assign('page', $page);
$smarty->assign('pages',$pages);

$smarty->display('index.tpl');



?>

Nie ma tu nic nowego oprócz kilku przeliczeń dotyczących ilości stron i ograniczenia LIMITem ilości pobranych rekordów. Teraz zobaczmy fragment kodu odpowiadający za wyświetlenie stron. Należy go umieścić go w tym miejscu, gdzie chcemy wyświetlić listę stron (np. po {/foreach}).

  
{section name=p start=1 loop=$pages+1}
{assign var=i value=$smarty.section.p.index}
{if $i == $page}
<b> {$page} </b>{else}
<a href="index.php?page={$i}"> {$i} </a>{/if}
{/section}

Używamy tutaj nowego bloku: section. Ten blok także pozwala iterować tablice, jednak tutaj wykorzystujemy go podobnie do pętli for. Parametrem name nadajemy mu nazwę p. Parametrem start określamy pierwszą wartość iteratora, a parametrem loop ilość przejść pętli. Wewnątrz bloku section wykorzystujemy funkcję assign, która przypisuje zmiennej i wartość iteratora (ze zmiennej $smarty.section.p.index). Dalej wyświetlamy link lub stały tekst, jeżeli jesteśmy już na tej stronie.

Działająca księga gości
Działająca księga gościPowiększ

Podsumowanie

Smarty zawiera jeszcze wiele ciekawych funkcji i nie sposób ich opisać w jednym artykule. Z tego artykułu nauczyliśmy się wykorzystywać kilka najważniejszych i najprzydatniejszych. Warto jeszcze doczytać o nich w manualu.

Kodie @ 03-08-2006 21:54

#1

Dobry artykuł, lecz sądzę, że nie ma sensu robić AŻ tyle dla zwykłej księgi gości, tym bardziej, że ta, jeśli się ją nie rozbuduje, jest dość mało efektywna. Smarty to kompletny bezsens przy takim czymś.

lucky777 @ 18-05-2007 18:13

#2

Dla prostego systemu pewnie nie, ale chodziło mi przede wszystkim o idee i sposób działania :)

Kodie @ 30-09-2007 12:01
Copyright © 2005-2006 Compzone.Org. Kopiowanie i wykorzystywanie materiałów zawartych na tej stronie bez zgody autora zabronione!