Ten artykuł jest archiwalny, korzystasz z niego na własną odpowiedzialność.
System podstron w PHP
Początkujący webmasterzy bardzo często korzystają z takiego kodu:
<?php
$id = $_GET['id'];
if(file_exists($id.'.php')) {
include $id.'.php';
} else {
include 'glowna.php';
}
?>Jest to bardzo proste rozwiązanie. W adresie np. index.php?id=omnie sprawdzamy czy istnieje plik omnie.php i go includujemy, w przeciwnym wypadku zostaje załączony plik glowna.php. Proste, łatwe i szybkie. No ale jest jeden problem... bezpieczeństwo. Wystarczy wpisać w adresie index.php?id=config i mamy hasła i co nam tam sie podoba.
Jest również wersja całkowicie bezpieczna ale trzeba ręcznie wpisywać wszystkie podstrony:
<?php
echo '<a href="index.php">Home</a><br>';
echo '<a href="index.php?page=kontakt">Kontakt</a><br>';
echo '<a href="index.php?page=omnie">O mnie</a><br>';
switch($_GET['page']) {
case 'kontakt':
include 'kontakt.php';
break;
case 'omnie':
echo 'Coś o mnie';
break;
default:
include 'glowna.php';
}
?>Jak widać kod też jest prosty. Nic trudnego ;)
No ale my byśmy chcieli pójść krok do przodu... zrobimy panel administratora! Całość będzie się opierała na tabeli w MySQL. Tak więc najpierw ją stworzymy:
CREATE TABLE `strony` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tytul` varchar(255) NOT NULL,
`tresc` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;Standardowa tabela z unikalnym ID, tytułem i treścią.
Jeśli stworzyliśmy już tabelę w bazie danych czas zrobić plik strony.class.php. To plik w którym będą trzymane wszystkie funkcje klasy Strony.
<?php
class Strony {
// Hasło do panelu admina
private $haslo = 'haslo123';
// Host bazy danych
private $dbhost = 'localhost';
// Użytkownik bazy danych
private $dbuser = 'root';
// Hasło do bazy danych
private $dbpass = '';
// Nazwa bazy danych
private $dbname = 'test';
function __construct() {
mysql_connect( $this->dbhost, $this->dbuser, $this->dbpass ) or die(mysql_error());
mysql_select_db( $this->dbname ) or die(mysql_error());
mysql_query("SET NAMES utf8");
mysql_query("SET CHARACTER SET utf8");
mysql_query("SET collation_connection = utf8_polish_ci");
}
function __destruct() {
mysql_close();
}
// inne funkcje
}
?>W powyższym kodzie stworzyliśmy klasę Strony wraz z prywatnymi zmiennymi (co one przechowują jest opisane w komentarzach). Dodatkowo w konstruktorze klasy jest połączenie z bazą danych. Przy połączeniu ustawiamy kodowanie na UTF-8 gdyż jest ono bardzo zalecane i będziemy z niego korzystać w tym tutorialu. W destruktorze rozłączamy się z bazą danych. Tam gdzie jest zaznaczone komentarzem będziemy wklejać inne funkcje.
Przy okazji chciałbym polecić program Notepad++ który wspiera kodowanie UTF-8 :) Program jest po polsku
Tak więc połączenie z bazą danych już mamy to teraz wyświetlimy sobie listę stron:
function lista() {
$result = mysql_query("SELECT id, tytul FROM strony ORDER BY id DESC"); // 1
if(mysql_num_rows($result) > 0) { // 2
while($row = mysql_fetch_array($result)) { // 3
echo '<a href="index.php?page='.$row['id'].'">'.$this->stripslashes_deep($row['tytul']).'</a><br>'; // 4
}
} else {
echo '<p>Brak stron!</p>';
}
}- Standardowe zapytanie do bazy danych. Pobieramy ID i tytuł sortując wg ID zaczynając od największego.
- Jeśli zapytanie zwróciło jakieś wyniki.
- Wyświetlamy je w pętli while.
- Tworzymy odsyłacz do strony. Korzystamy z funkcji stripslashes_deep którą podam na końcu. Jest to to samo co zwykłe stripslashes z tym że obsługuje tablice.
Teraz funkcja pokazująca stronę:
function pokaz($id) {
$row = $this->strona($id);
echo '<h2>'.$row['tytul'].'</h2>';
echo '<p>'.$row['tresc'].'</h2>';
}Kod bardzo prosty. Pobieramy dane o stronie do tablicy $row. Tytuł wyświetlamy w nagłówku h2 a treść w paragrafie.
Następnie funkcja potrzebna żeby działała powyższa czyli strona()
function strona($id) {
$id = (int)$id; // 1
$result = mysql_query("SELECT * FROM strony WHERE id = '$id'"); // 2
if(mysql_num_rows($result) > 0) { // 3
$row = mysql_fetch_array($result); // 4
return $this->stripslashes_deep($row); // 5
} else {
echo '<p>Taka strona nie istnieje!</p>';
return false; // 6
}
}- Rzutujemy ID na liczbę (zabezpieczenie).
- Tworzymy zapytanie na stronę z podanym ID.
- Jeśli wynik zwrócił jakieś dane...
- Pobieramy je do tablicy asocacyjnej.
- I zwracamy wyniki przekonwertowane przez funkcję stripslashes_deep.
- Jeśli taka strona nie istnieje wyświetlamy komunikat i zwracamy nieprawdę (false).
To by było tyle funkcji wyświetlających. Teraz czas na panel administratora.
function admin() {
if(!isset($_SESSION['admin']) || $_SESSION['admin'] != true) {
$this->admin_logowanie();
return;
}
switch($_GET['akcja']) {
case 'dodaj':
$this->admin_dodaj();
break;
case 'edytuj':
$this->admin_edytuj($_GET['id']);
break;
case 'usun':
$this->admin_usun($_GET['id']);
break;
default:
$this->admin_lista();
}
}Funkcja bardzo prosta. Na początek sprawdzamy czy użytkownik jest zalogowany i jesli nie to wywołujemy funkcję admin_logowanie(). Następnie zależnie od akcji w adresie wywołujemy przypisane funkcje. Domyślnie jest to lista wszystkich stron.
function admin_logowanie() {
if(isset($_POST['haslo'])) {
if($_POST['haslo'] == $this->haslo) $_SESSION['admin'] = true;
else echo '<p>Hasło niepoprawne!</p>';
}
if(!isset($_SESSION['admin']) || $_SESSION['admin'] != true) {
echo '<form action="" method="POST">
<label>Hasło:</label><br>
<input type="password" name="haslo"><br>
<input type="submit" value="Zaloguj">
</form>';
} else {
echo '<p>Jesteś zalogowany! <a href="admin.php">Przejdź do strony głównej</a>.';
}
}Funkcja na logowanie. Myślę że jest bardzo prosta i nie wymaga komentarza.
function admin_lista() {
$result = mysql_query("SELECT id, tytul FROM strony ORDER BY id DESC");
if(mysql_num_rows($result) > 0) {
echo '<table>';
while($row = mysql_fetch_array($result)) {
echo '<tr>
<td>'.$this->stripslashes_deep($row['tytul']).'</td>
<td>
<a href="admin.php?akcja=edytuj&id='.$row['id'].'">Edytuj</a> |
<a href="admin.php?akcja=usun&id='.$row['id'].'">Usuń</a>
</td>
</tr>';
}
echo '</table>';
} else {
echo '<p>Brak stron!</p>';
}
echo '<p><a href="admin.php?akcja=dodaj">Dodaj nową stronę</a></p>';
}Funkcja bardzo podobna do funkcji lista() z tym że wyniki są wyświetlane w tabeli wraz z linkami do edycji i usuwania. Na dole link do dodawania nowej strony.
Funkcja na dodawanie strony:
function admin_dodaj() {
if(isset($_POST['tytul']) && isset($_POST['tresc'])) { // 1
$tytul = $this->czysc($_POST['tytul']);
$tresc = $this->czysc($_POST['tresc']); // 2
$result = mysql_query("INSERT INTO strony (`tytul`, `tresc`) VALUES ('$tytul', '$tresc')"); // 3
if($result) {
$id = mysql_insert_id();
echo '<p>Dodano poprawnie! <a href="index.php?page='.$id.'">Przejdź do strony</a></p>'; // 4
}
} else { // 5
echo '<form action="" method="POST">
<label>Tytuł:</label><br>
<input type="text" name="tytul" style="width:500px"><br>
<label>Treść:</label><br>
<textarea style="width:500px" rows="10" name="tresc" id="tresc"></textarea>
<input type="submit" value="Wyślij">
</form>';
}
}- Jeśli jest podany tytuł i treść.
- Czyścimy zmienne funkcją czysc() która dodaje slashe do ` i ' - aby nam się nie psuło zapytanie.
- Wykonujemy zapytanie na dodawanie rekordu.
- Jeśli zapytanie przebiegnie poprawnie to pobieramy ID dodanej strony i wyświetlamy do niej link wraz z stosownym komunikatem.
- Jeśli nie wysłaliśmy formularza to go wyświetlamy.
function admin_edytuj($id) {
$id = (int)$id;
if(isset($_POST['tytul']) && isset($_POST['tresc'])) {
$tytul = $this->czysc($_POST['tytul']);
$tresc = $this->czysc($_POST['tresc']);
$result = mysql_query("UPDATE strony SET tytul = '$tytul', tresc = '$tresc' WHERE id = '$id'");
if($result) {
echo '<p>Zaktualizowano poprawnie! <a href="index.php?page='.$id.'">Przejdź do strony</a></p>';
}
} else {
$row = $this->strona($id);
echo '<form action="" method="POST">
<label>Tytuł:</label><br>
<input type="text" name="tytul" style="width:500px" value="'.$row['tytul'].'"><br>
<label>Treść:</label><br>
<textarea style="width:500px" rows="10" name="tresc" id="tresc">'.$row['tresc'].'</textarea>
<input type="submit" value="Wyślij">
</form>';
}
}Podobna funkcja do tej wyżej na edycję strony. Wszystko jest praktycznie tak samo tylko że wykonujemy zapytanie UPDATE a nie INSERT. Jeśli formularz nie został jeszcze wysłany to go wyświetlamy z wypełnionymi polami. Korzystamy tutaj też z funkcji strona()
function admin_usun($id) {
$result = mysql_query("DELETE FROM strony WHERE id = '$id'");
if($result) {
echo '<p>Pomyślnie usunięto stronę! <a href="admin.php">Wróć do strony głównej</a>.</p>';
}
}Bardzo prosta funkcja na usuwanie strony. Raczej nic tu trudnego nie ma i obejdzie się bez komentarza ;)
No i to by było na tyle. Jeszcze tylko funkcje pomocnicze czysc() i stripslashes_deep()
function czysc($tresc) {
$tresc = mysql_real_escape_string($tresc);
return $tresc;
}
function stripslashes_deep($value) {
$value = is_array($value) ?
array_map(Array($this, 'stripslashes_deep'), $value) :
stripslashes($value);
return $value;
}Funkcja czysc() to tak jakby alias dla funkcji mysqlrealescape_string(). Istnieje ona ponieważ ma krótszą nazwę oraz zawsze możemy coś jeszcze dodać zmieniając kod tylko w jednym miejscu.
Co do stripslashesdeep() to jeśli $value jest tablicą to używamy na niej funkcji arraymap (dla każdej wartości w tablicy zostanie wywołana funkcja w pierwszym parametrze funkcji). Jeśli $value nie jest tablicą to używamy zwykłego stripslashes. Funkcja została zaczerpnięta z manuala pod funkcją stripslashes.
Ciekawostka: Jeśli w funkcji w której podajemy nazwę funkcji (preg_replace, array_map itd) chcemy użyć funkcji należącej w jakiejś klasie używamy tablicy. Pierwsza wartość to odwołanie (np. $this) a druga to nazwa funkcji. Przykład w powyższej funkcji stripslashes_deep.
Dobra, klasę już mamy, teraz trzeba ją wywołać. Więc stworzymy sobie plik index.php a w nim:
<html>
<head>
<title>Moja strona</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<?php
include "strony.class.php";
$strony = new Strony;
if(isset($_GET['page'])) $strony->pokaz($_GET['page']);
else $strony->lista();
?>
</body>
</html>Jak widać standardowy szablon HTML, kodowanie UTF-8. Używając PHP załączamy plik z klasą. Tworzymy nowy obiekt i jeśli jest używana zmienna $GET['page'] to wywołujemy funkcję pokaz() ze zmienną $GET w parametrze. W przeciwnym wypadku wyświetlamy listę stron (można tam na przykład znając ID kontretnej strony wstawić $strony->pokaz(123); gdzie 123 to ID strony głównej).
Teraz panel administratora - plik admin.php:
<?php session_start(); ?>
<html>
<head>
<title>Panel administratora</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="http://js.nicedit.com/nicEdit-latest.js" type="text/javascript"></script>
<script type="text/javascript">bkLib.onDomLoaded(function(){new nicEditor({fullPanel : true}).panelInstance('tresc'); });</script>
</head>
<body>
<?php
include "strony.class.php";
echo '<a href="admin.php"><h3>Panel administratora</h3></a>';
$strony = new Strony;
$strony->admin();
?>
</body>
</html>Na początek startujemy sesje aby było możliwe logowanie. Jak widać jest też standardowy szablon HTML. Ale tutaj jest mały dodatek - edytor tekstowy WYSIWYG Nicedit. Nie musimy nic pobierać ponieważ edytor jest na zewnętrzym serwerze ;)
W środku strony ładujemy plik z klasą, wyświetlamy napis "Panel administratora", tworzymy nowy obiekt klasy i wywołujemy funkcję admin().
No i to by było na tyle ;) Mamy już własny system podstron w PHP!