Wykład 3 - WGan.pl

advertisement
Tworzenie Aplikacji Internetowych
dr Wojciech M. Gańcza
3
Zasięg zmiennych
W PHP skrypt tworzący stronę
zachowuje się jak program
 Gdy generowanie strony się kończy –
program się kończy
 Wszystkie zmienne przestają istnieć
 Wszystkie zasoby otwarte lub
utworzone przez skrypt – są
zamykane lub usuwane
 A czasem warto coś zapamiętać…

Sesja
Jeśli informacje powinny przetrwać do
następnej strony – możemy użyć sesji
 Do obsługi sesji służą polecenia

session_start
 session_register
 I inne (->manual php)


Oraz globalna tablica asocjacyjna


$_SESSION
Dane sesji obsługiwane są jako
cookie.
Ograniczenia sesji
Sesja dotyczy pojedynczego
użytkownika – nie można dzielić
danych pomiędzy różnych
użytkowników
 Sesja wygasa – po krótkim okresie
nieaktywności – tracimy informacje
zawarte w sesji
 Sesja wymaga akceptowania cookie

Inne sposoby pamiętania

Zamiast w sesji możemy pamiętać
dane
W ukrytych elementach formularza (nie
można dzielić z innymi)
 W plikach (podobnie – problem
wielodostępu)
 W bazie danych – tu jest najlepiej: dane
mają strukturę i wszyscy mają dostęp –
serwer bazy danych rozwiązuje konflikty
wielodostępu

Baza danych
W bazie dane podzielone są na tabele
 Każda tabela zawiera rekordy o takiej
samej strukturze
 Dane w bazie są chronione – by
uzyskać dostęp musimy się
autoryzować
 Baza zapewnia mechanizmy
wyszukiwania danych
 Wiele baz zapewnia tranzakcyjność

Dostęp do danych
Mimo, że PHP zapewnia spory
repertuar funkcji do obsługi bazy –
wszystkie operacje możemy
wykonywać komunikując się w języku
SQL (sequence query language)
 Język ten składa się tylko z kilku
poleceń
 Musimy jednak wcześniej nawiązać
połączenie z bazą danych

Połączenie - przykład
Wszystkie polecenia jakie będziemy
omawiali – dotyczą serwera MySQL
 Połączenie – mysql_connect

Nazwa serwera
 Identyfikator użytkownika
 Hasło autoryzujące użytkownika

Wartości połączenia mogą być
określone w konfiguracji PHP
 Funkcja zwraca identyfikator
połączenia – który można zapamiętać

Pytanie SQL

Do przesłania zapytania służy
polecenie mysql_query
Tekst zapytania (string)
 Opcjonalnie – identyfikator połączenia

Jeśli nie określimy połączenia –
będzie użyte ostatnio nawiązane
 Wynikiem może być identyfikator
recordsetu zawierającego wynik
działania zapytania
 Zapytanie może też nic nie zwracać

Inne funkcje
W manualu PHP można znaleźć sporo
innych funkcji – jednak nie będziemy
ich używać.
 Zamiast tego – skorzystamy z poleceń
języka SQL
 Przykład – zamiast wyboru bazy
użyjemy „use nazwa_bazy”
 Warto poinformować bazę w jakim
kodowaniu będą przychodzić
polecenia „set names utf8;”

Klasa połączenia
class DatabaseAccess
{
var $connection;
function DatabaseAccess()
{
//…
}
function query($query)
{
//…
}
}
Konstruktor
Czy do konstruktora powinniśmy
przekazywać parametry połączenia?
 Tak – bo to on decyduje z jakim
serwerem i jaką bazą należy się
połączyć
 Nie – bo różne serwery baz danych
wymagają różnego określenia
parametrów połączenia – a chcemy
mieć możliwość podmienienia
połączenia

Klasa określająca konfigurację
class DatabaseConfiguration
{
var $database_server;
var $database_user;
var $database_password;
var $database_name;
function DatabaseConfiguration()
{
$this->database_server
= "localhost";
$this->database_user
= "root";
$this->database_password = "";
$this->database_name
= "UUK";
}
};

Definicje obiektu konfiguracji po prostu dołączamy do plików
włączanych w skrypt.
Konstruktor
function DatabaseAccess()
{
$config = new DatabaseConfiguration();
$this->connection = mysql_connect(
$config->database_server,
$config->database_user,
$config->database_password);
mysql_query("set names utf8;");
mysql_query("use " .
$config->database_name . ";",
$this->connection);
}

Przy połączeniu wybieramy bazę i ustawiamy
sposób komunikacji! Po konstrukcji dostęp do bazy
ma być przygotowany
Metoda query()

Wystarczyłoby napisać
function query($query)
{
return mysql_query(
$query, $this->connection));
}

Jednak sposób czytania zasobu
zwracanego przez mysql_query – jest
typowy dla serwera MySQL!
Recordset
Dodajmy klasę recordset
implementującą źródło danych
 Zapytanie może zwrócić pusty zbiór
danych – musimy się na to
przygotować (zwraca false zamiast
identyfikatora zasobu)
 Metoda mysq_fetch_row zwraca
tablicę lub false gdy nie ma więcej
danych – a to za pózno (eof powinien
zgłosić true przed pobraniem

Recordset…
class Recordset
{
var $recordset;
var $record ;
function Recordset($records)
{ …}
function get()
{…}
};
function eof()
{…}
Recordset…
function Recordset($records)
{
$this->recordset = $records;
if (gettype($records) != "resource")
{
$this->record = false;
}
else
{
$this->get();
}
}
Recordset…
function get()
{
$previousRecord = $this->record;
$this->record = ($this->recordset
? mysql_fetch_row($this->recordset)
: false);
return $previousRecord;
}
function eof()
{
return ($this->record
? false
: true);
}
Teraz możemy:

… zakończyć pisanie dostępu do bazy
danych:
function query($query)
{
return new Recordset(
mysql_query($query,
$this->connection));
}

Klasy DatabaseAccess i Recordset –
powinny być umieszczone w jednym pliku.
Konstrukcja bazy
W czasie pracy nad programem
często testujemy
 Testy często polegają na zmianie
danych
 Testy powinny być powtarzalne
 Dane powinno się łatwo przywracać

Z kopii zapasowej, lub
 Przy użyciu skryptów tworzących


Wole to drugie rowzwiązanie
Konstrukcja bazy
Bazę tworzymy poleceniem SQL
‘create database nazwabazy;’
 Po utworzeniu – powinniśmy przejść
do tej bazy
 Całą bazę danych możemy usunąć
poleceniem ‘drop database
nazwabazy’
 Jeśli coś jest tworzone poleceniem
create – to jest usuwane przez drop

Konstrukcja bazy …
Tabele konstruujemy poleceniem
‘create table nazwatabeli ( pola i inne
elementy tabeli);’
 Tabelę usuwamy poleceniem ‘drop
table nazwatabeli’.
 Usunięcie tabeli bezpowrotnie usuwa
wszystkie zawarte w niej dane
 Różne serwery stosują różną składnię
do określenia pól i innych elementów
tabeli

Klasy tworzące bazę
DBDatabaseCreator – tworzy pustą
bazę
 DBTableCreator – tworzy tabelę
pozwalając dodawać pole po polu
 DBFieldTypes – zawiera określenia
typów pól zrozumiałych przez bazę
 Wszystkie operacje tworzenia bazy
muszą być wykonane jedynie przy
użyciu tych klas

DBFieldTypes
class DBFieldTypes
{
var $primaryKey;
var $refrence;
var $title;
var $name;
var $description;
var $money;
function DBFieldTypes()
{
$this->primaryKey = "INTEGER NOT NULL
AUTO_INCREMENT PRIMARY KEY";
$this->reference = "INTEGER";
$this->title = "VARCHAR(160)";
$this->name = "VARCHAR(64)";
$this->description = "VARCHAR(255)";
$this->money = "REAL";
}
}
DBDatabaseCreator
class DBDatabaseCreator
{
var $database;
function DBDatabaseCreator(&$database)
{
$this->database = &$database;
}
function createDatabase($name)
{
$this->database->query("create database
$name default character set utf8;");
$this->database->query("set names utf8;");
$this->database->query("use $name;");
}
}
DBTableCreator
class DBTableCreator
{
var $database;
var $fieldTypes;
var $definitionOfTable;
function DBTableCreator(&$database)
{
$this->database = &$database;
$this->fieldTypes= new DBFieldTypes();
$this->definitionOfTable = "";
}
DBTableCreator …
function startTable($name)
{
$this->definitionOfTable =
"create table
$name (" . $name . "ID " .
$this->fieldTypes->primaryKey;
}
function addField($name, $type)
{
$this->definitionOfTable .= ", " .
$name . " " .
$this->fieldTypes->$type;
}
DBTableCreator …
function createTable()
{
$this->database->query(
$this->definitionOfTable .
") DEFAULT CHARSET utf8;");
}
function createIndex($tableName,
$fieldName)
{
$this->database->query("create index
${tableName}${fieldName} on
${tableName}($fieldName);");
}
W następnym odcinku
Poprawiamy konstruktor bazy
 Tworzymy bazę
 Wypełniamy bazę
 Tworzymy pierwszy widok danych z
bazy
 Poznajemy ciekawe konstrukcje
języka SQL
 Dowiemy się dlaczego nasza baza jest
określana jako relacyjna

Download