Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
1
Komunikacja między klientem, a skryptem PHP, oraz operacje na plikach
Zasady tworzenia stron w PHP z jednym plikiem głównym
Aplikacje oraz strony WWW bardzo często tworzy się tak, że do jednego dokumentu głównego,
dołączane są pozostałe dokumenty / pliki w zależności od potrzeb i wymagań funkcjonalnych serwisu
WWW, czy aplikacji. Z reguły plikiem głównym jest plik "index.php". Aby do tego pliku dołączyć
dodatkowy skrypt używa się wbudowanych funkcji PHP tj.: include('NazwaPliku.php') lub
require('NazwaPliku.php'). Najważniejszą różnicą pomiędzy obiema funkcjami jest to, że przy
wykorzystaniu require(), plik zostanie zawsze wstawiony. Stanie się tak nawet, jeśli funkcję tą
umieści się wewnątrz instrukcji warunkowej, której warunek nie zostanie spełniony. W takim samym
przypadku korzystając z funkcji include() plik nie zostanie wstawiony ponieważ to polecenie
w wyniku nie spełnienia warunku nie zostanie zinterpretowane. Drugą różnicę stanowi ilość dołączeń
pliku przy wielokrotnym wykonaniu funkcji. Kiedy parser PHP napotka funkcję include() wtedy
wstawia aktualną zawartość pliku, natomiast w przypadku kolejnych wywołań funkcji require()
zostaną użyte dane wstawione w za pierwszym razem. Stanie się tak nawet, jeśli parser PHP
ponownie napotka funkcję require() odnoszącą się do tego samego pliku. Rozróżnia się jeszcze
funkcje include_once() i require_once(), które wstawiają plik tylko podczas pierwszego
wystąpienia. Przykładowy plik "index.php" mógłby wyglądać tak:
require_once('./biblioteki/biblioteka1.php');
if (isset($_GET['modul']) && $_GET['modul'] == 'strona_glowna')
{
include('./moduly/modul_strona_glowna.php');
}
Funkcja isset() służy do sprawdzania czy zmienna podana w parametrze funkcji istnieje.
Zwraca wartość true jeśli zmienna istnieje lub false jeśli nie. W powyższym przykładzie jeśli istnieje
element tablicy $_GET['modul'] i ten element zawiera wartość "strona_glowna" wtedy
dołączony zostanie plik "./moduly/modul_strona_glowna.php". Zamiast instrukcji if()
możliwe jest użycie instrukcji switch() aby np. dołączyć większą liczbę plików w zależności od
wartości zmiennej $_GET['modul']. Poniżej przykład
Podczas projektowania aplikacji internetowych oraz stron WWW korzysta się ze wzorców
projektowych. Jednym z powszechnie znanych i stosowanych wzorców tworzenia stron w PHP jest
wzorzec MVC oraz wzorce od niego pochodne. Aplikacja napisana według wzorca MVC się na
3 warstwy:
warstwa modelu - służy wyłącznie do pozyskiwania danych,
warstwa kontrolera - decyduje, który model i widok ma być użyty w danym momencie,
warstwa widoku - zajmuje się wyłącznie wyświetlaniem danych z dostarczonych z modelu.
2
Metody GET i POST protokołu HTTP
Do odbierania żądań służą dwie predefiniowane tablice asocjacyjne: $_GET[] i $_POST[].
W tablicy $_GET[] przechowywane są zmienne zawarte w adresie URL strony po znaku zapytania,
np. adres "http://localhost/index.php?modul=strona_glowna&akcja=pokaz" zawiera
dwie zmienne "modul" i "akcja", które mają odpowiednio wartości "strona_glowna"
i "pokaz".
Kod: echo 'Moduł to '.$_GET['modul'].', a akcja to '.$_GET['akcja'];
dla powyższego adresu URL wyświetli napis:
"Moduł to strona_glowna, a akcja to pokaz";
Z tablicy $_POST[] korzysta się w identyczny sposób, natomiast zmienne w niej przechowywane
nie są częścią adresu URL. Tablicę $_POST[] wykorzystuje się z reguły do przesyłania danych
z formularzy HTML.
Poniżej znajduje się kod skryptu, który za pomocą formularza HTML (plik formularz.php)
pobiera od użytkownika Imię i Nazwisko, a potem je wyświetla.
// Plik formularz.php
<form action="index.php" method="POST">
<div><span>Imię: </span>
<input type="text" name="imie" value="" /></div>
<div><span>Nazwisko: </span>
<input type="text" name="nazwisko" value="" /></div>
<div><input type="submit" value="Wyślij" /></div>
</form>
// Plik index.php
<?php
if (isset($_POST['imie']) && isset($_POST['nazwisko']))
{
echo $_POST['imie'] . ' ' . $_POST['nazwisko'];
}
else
{
include('formularz.php');
}
?>
Po uruchomieniu skryptu (pliku index.php) zostanie sprawdzone czy istnieją dwa elementy
tablicy $_POST: "imie" i "nazwisko". Jeśli nie istnieją to do dokumentu zostanie wstawiony
plik z formularzem. Po uzupełnieniu formularza i naciśnięciu przycisku "Wyślij" wszystkie dane
z tego formularza zostaną wysłane do skryptu "index.php" (action="index.php") za pomocą
metody POST (method="POST"). Adres widoczny w przeglądarce w ogóle się nie zmieni, warunek
zostanie spełniony, ponieważ teraz elementy tablicy $_POST[] istnieją i zostanie wyświetlona ich
zawartość. Jeśli w polu "Imię" zostało wpisane "Anna", a w polu "Nazwisko" - "Kowalski" to
wyświetlony zostanie napis "Anna Kowalski".
Jeśli dane z formularza przesyłane były metodą GET to adres w przeglądarce wyglądałby tak:
http://localhost/index.php?imie=Anna&nazwisko=Kowalski.
3
Formularz internetowy umożliwia również przesyłanie użytkownikowi plików na serwer. Taki
formularz należy uzupełnić o pole "input" typu "file" i dołożyć atrybut
enctype="multipart/form-data do znacznika <form>.
// Plik formularz.php
<form action="index.php" method="POST" enctype="multipart/form-data">
<div><span>Opis obrazka: </span>
<input type="text" name="opis" value="" /></div>
<div>
<input type="file" name="plik" accept="image/jpeg,image/gif" />
</div>
<div><input type="submit" value="Wyślij" /></div>
</form>
// PLik index.php
<?php
if (is_uploaded_file($_FILES['plik']['tmp_name'])) {
$max = 1024 * 2; // 2MB
$wielkosc_pliku = $_FILES['plik']['size'];
$typ_pliku = $_FILES['plik']['type'];
$nazwa_pliku = $_FILES['plik']['name'];
$tymczasowa_nazwa_pliku = $_FILES['plik']['tmp_name'];
$miejsce_docelowe = './obrazki/' . $nazwa_pliku;
if ($wielkosc_pliku <= 0) {
echo 'Plik jest pusty.';
}
elseif ($wielkosc_pliku > $max) {
echo 'Plik jest za duży maksymalnie można wysłać ' . $max . '.';
}
elseif (file_exists($miejsce_docelowe)) {
echo 'Wczytywany plik już istnieje na serwerze.';
}
else {
if (!@move_uploaded_file($tymczasowa_nazwa_pliku, $miejsce_docelowe))
echo 'Podana lokalizacja nie istnieje';
else
echo 'Przesyłanie pliku zakończyło się pomyślnie.';
}
}
?>
Funkcja is_uploaded_file() sprawdza czy plik został przesłany przez formularz. Wszystkie
informacje o przesłanych plikach znajdują się w predefiniowanej tablicy $_FILES[]. Tablica zawiera
tyle elementów ile jest pól typu "file" w formularzu HTML. Informację dotyczące konkretnego
pliku przesłanego na serwer zawarte są w podtablicy każdego elementu tablicy $_FILES[]. Poniżej
opis paru pól tej podtablicy:
$_FILES['NazwaPolaTypuFile']['name'] - nazwa przesyłanego pliku;
$_FILES['NazwaPolaTypuFile']['tmp_name'] - tymczasowa nazwa pliku na serwerze.
Plik po przesłaniu trafia do tymczasowego katalogu.
$_FILES['NazwaPolaTypuFile']['size'] - wielkość pliku w bajtach;
$_FILES['NazwaPolaTypuFile']['type'] - typ pliku w formacie MIME, np.: image/gif, image/jpeg;
Po sprawdzeniu czy wielkość pliku mieści się w określonych granicach i czy taki plik nie znajduje
się już w katalogu docelowym, można plik bezpiecznie przenieść z katalogu tymczasowego do
4
katalogu docelowego. Należy pamiętać, że do katalogu docelowego skrypt musi mieć dostęp, czyli
muszą być ustawione właściwe prawa dostępu - dotyczy to np. systemu Linux.
Mechanizm Sesji
Protokół HTTP jest protokołem bezstanowym, co oznacza, że serwer rozpatruje każde żądanie
indywidualnie nie korelując go z konkretnym użytkownikiem. Jest to kłopotliwe w przypadku
wszelkiego rodzaju systemów autoryzacji i wtedy właśnie można wykorzystać mechanizm sesji. Aby
rozpocząć sesję wystarczy użyć funkcji session_start(). Funkcja ta musi zostać użyta przed
wysłaniem jakichkolwiek informacji do klienta, dotyczy to nawet informacji pochodzących z nagłówka
HTML. Wszystkie dane sesji przechowywane są w predefiniowanej tablicy $_SESSION[].
Poniżej znajduje się prosty przykład pokazujący ilość odświeżeń danej strony.
<?php
session_start();
if (!isset($_SESSION['licznik'])) $_SESSION['licznik'] = 1;
else $_SESSION['licznik'] = $_SESSION['licznik'] + 1;
echo 'Ilość odświeżeń strony podczas aktualnej sesji: '.
$_SESSION['licznik'] . '<br />';
?>
Na początku sprawdzane jest, czy istnieje zmienna sesyjna $_SESSION[licznik]. Jeśli nie
istnieje to zostaje utworzona poprzez przypisanie do niej wartości początkowej 1. W przeciwnym
razie, czyli jeśli zmienna taka już istnieje to jej wartość jest zwiększana o jeden. Następnie
wyświetlana jest wartość tej zmiennej, która reprezentuje ilość odświeżeń danej strony. Poniżej
przykład zresetowania takiego licznika:
<?php
session_start();
if (isset($_GET['resetuj']) && isset($_SESSION['licznik']))
unset($_SESSION['licznik']);
if (!isset($_SESSION['licznik'])) $_SESSION['licznik'] = 1;
else $_SESSION['licznik'] = $_SESSION['licznik'] + 1;
echo 'Ilość odświeżeń strony od ostatniego resetu: '.$_SESSION['licznik'];
echo '<br />';
echo '<a href="index.php?resetuj=tak">Resetuj licznik</a>';
?>
W powyższym kodzie dodano linię, w której następuje sprawdzenie, czy istnieje zmienna
$_GET['resetuj'] oraz czy istnieje zmienna $_SESSION['licznik']. Jeśli oba warunki są
spełnione to zmienna sesyjna $_SESSION['licznik'] usuwana jest z tablicy. Następnie jeśli
zmienna $_SESSION['licznik'] nie istnieje ustawia się jej wartość początkową. W ostatniej linii
kodu znajduje się hiperłącze, przez które można zresetować licznik odwiedzin.
5
Podstawowe operacje na plikach tekstowych i binarnych
Wszystkie funkcje do obsługi plików (oprócz tej otwierającej plik) jako parametr pobierają
deskryptor, czyli tzw. „wskaźnik do pliku”. Jest to wartość zmiennej identyfikująca plik otwarty
w systemie. Taki wskaźnik jest niezbędny ponieważ skrypt może korzystać jednocześnie z wielu
plików i na wszystkich przeprowadzać operacje, takie jak odczyt, czy zapis.
Poniżej znajduje się przykład jak odczytać plik tekstowy linia po linii:
$plik = @fopen('nazwa_pliku.txt', 'r');
if ($plik) {
while (!feof($plik)) {
$linia = fgets($plik);
echo $linia . '<br />';
}
fclose($plik);
}
Funkcja fopen() służy do otwarcia pliku i zwraca uchwyt do niego - deskryptor. Pierwszym
parametrem funkcji jest nazwa otwieranego pliku, a drugim tryb jego otwarcia. Aby móc odczytać
plik drugi parametr musi mieć wartość "r". W pętli while()pobierane są kolejne linie tekstu z pliku
za pomocą funkcji fgets(). Pętla wykonuje się tak długo, aż funkcja eof() zwróci wartość false.
Następnie plik zostaje zamknięty po wykonaniu funkcji fclose().
Poniżej przykład jak odczytać całą zawartości pliku tekstowego do zmiennej:
$nazwaPliku = 'nazwa_pliku.txt';
$plik = fopen($nazwaPliku, 'r');
$zawartosc_pliku = fread($plik, filesize($nazwaPliku));
fclose($plik);
echo 'Zawartość pliku tekstowego "' . $nazwaPliku . '":<br />' .
$zawartosc_pliku;
Funkcja filesize() zwraca wielkość pliku w bajtach. Funkcja fread() odczytuje z pliku
określoną ilość bajtów zadaną w drugim parametrze, a więc w powyższym przypadku odczytany
zostanie cały plik.
Zapisywanie do pliku zawartości tablicy:
$tablica = array('linia pierwsza', 'linia druga', 'linia trzecia');
$plik = @fopen('nazwa_pliku.txt', 'w');
foreach ($tablica as $linia) {
fwrite($plik, $linia . "\r\n");
}
fclose($plik);
Aby zapisać dane do pliku należy drugi parametr funkcji fopen() ustawić na wartość "w", jeśli
plik nie istnieje to zostanie utworzony. Następnie w pętli foreach() za pomocą funkcji fwrite()
zapisywana jest zawartość tablicy. Aby każda wartość elementu tablicy była zapisana w osobnej linii
należy dołączyć do tej wartości znaki końca linii. W systemie Windows jest to "\r\n", a w systemach
takich jak Linux "\n".
Aby odczytać lub zapisać plik binarny wystarczy drugi parametr funkcji fopen() zamienić na
"rb" dla odczytu lub "wb" dla zapisu.
6
Wyszukiwanie plików i katalogów
Listowanie zawartości katalogu:
$katalog = '.';
$tablica = scandir($katalog);
foreach ($tablica as $nazwa)
{
if (is_dir($nazwa)) echo '[' . $nazwa . ']<br />';
else echo $nazwa . '<br />';
}
Powyższy przykład wyświetla zawartość bieżącego katalogu. Wszystkie nazwy katalogów zostaną
umieszczone w kwadratowym nawiasie. Funkcja is_dir() sprawdza, czy podany element jest
katalogiem. Jako katalogi zostaną także wyświetlone dwa specjalne katalogi. Pierwszy reprezentujący
bieżący katalog, który jest opisany symbolem kropki ".", oraz drugi opisany przez dwie kropki "..",
który reprezentuje katalog nadrzędny.