Witaj, Gościu O nas | Kontakt | Mapa
Wortal Forum PHPEdia.pl Planeta Kubek IRC Przetestuj się!
Kategorie

Kategorie

Kategoria wyżej
O autorze

O autorze

Alan (LBO) Bem
Reklama

Reklama

Podobne Artykuły

Poniżej znajduje się lista podobnych artykułów:
Brak powiązanych artykułów

Budowa interfejsów bazodanowych

Ten artykuł poświęcony jest tworzeniu i używaniu interfejsów Baz Danych (DB Interfaces). Interfejsy te sprawiają, że rozbudowa aplikacji staje się łatwiejsza i szybsza. Dzieje się tak za sprawą umieszczenia kilku rozproszonych operacji DML (polecenia modyfikujące dane: wstaw, zmień, usuń - przyp. tłum.) w jednym współdzielonym narzędziu, jakim jest klasa. Klasa taka łączy przetwarzanie danych, ich integralność i ochronę w jednym instrumencie, który może być udostępniony poprzez aplikacje.

W ciągu ostatnich kilku lat powstało wiele narzędzi, zaradzających ograniczeniom PHP w czasie budowy dużych aplikacji, korzystającym z baz danych. Można je podzielić na dwie kategorie:

  • Warstwa bazodanowa
  • Generowanie HTML'a

Interfejsy Baz Danych są czymś nowym, narzędziem działającym pomiędzy logiką biznesową, a bazodanową.

Pod lupą

PHP zostało zaprojektowane jako "szybki i prosty" język służący do tworzenia dynamicznych stron internetowych. Jednakże, jego skalowalność jest znacznie obniżona, w przypadku dużych aplikacji, bez uprzedniej dużej ilości przygotowań i planowania. W czasie, gdy małe strony internetowe zbudowe przy pomocy PHP są "szybkie i proste", to aplikacje już niejednokrotnie stają się "szybkie i nieczytelne".

Kiedy aplikacja przekracza pewien rozmiar, reguły wg których powinna być zbudowana zmieniają się raptownie. Zasady projektowania małej strony HTML z odrobiną PHP znacznie się różnią od aplikacji, gdzie jej wielkość sięga 15 000 linijek kodu. Wraz ze wzrostem złożoności projektu, staje się on coraz trudniejszy w zarządzaniu. Chociaż język PHP został stworzony do wstawiania pomiędzy znaczniki HTML, ta zdolność staje się uciążliwa w czasie rozrastania się aplikacji.

Zagnieżdzony SQL podlega tym samym ograniczeniom co zagnieżdzony PHP. Im większy projekt, tym mniejsza łatwość zarządzania nim.

Rozwiązanie

Oddzielenie trzech głownych elementów aplikacji PHP jest najlepszym rozwiązaniem. Tymi elementami są:

  • Baza Danych
  • Logika aplikacji
  • Layout (wygląd w HTML)

Narzędzia takie jak ADODB, czy Smarty wspomagają wdrażanie tego pomysłu w życie. ADODB dostarcza aplikacji wsparcie przez wiele różnych baz danych. Smarty natomiast oddziela treść (logikę aplikacji) od wyglądu (layout).

Łatwiejszym we wdrożeniu rozwiązaniem jest użycie interfejsu bazodanowego w czasie działań na bazie danych. Interfejsy te odseparowują logikę bazy danych od logiki aplikacji. Ścislej mówiąc, odseparowują operacje DML od reszty kodu, co czyni go bardziej przejrzystym.

Najlepiej używać interfejsów, operując wyrażeniami DML bezpośrednio na tabelach. Zapewnia to lepszy poziom bezpieczeństwa i spójności danych.

Oto przykład w którym interfejs bazodanowy zastąpił zagnieżdżone operacje DML:

<?php

/* Update the client's contact information with the data from $_POST */  

$userID     = (int) $_POST['userID'];
$email      = trim(addslashes($_POST['email']));
$firstname  = trim(addslashes($_POST['firstname']));
$lastname   = trim(addslashes($_POST['lastname']));
$address1   = trim(addslashes($_POST['address1']));
$address2   = trim(addslashes($_POST['address2']));
$city       = trim(addslashes($_POST['city']));
$province   = trim(addslashes($_POST['province']));
$country    = trim(addslashes($_POST['country' ]));

$DML = 'UPDATE clients SET '.
       "email     = '$email',".
       "firstname = '$firstname',".
       "lastname  = '$lastname',".
       "address1  = '$address1',".
       "address2  = '$address2',".
       "city      = '$city',".
       "province  = '$province',".
       "country   = '$country',".
       "WHERE userID=$userID";
if ($db->Execute($DML))
{
    // do error handling
}

?>
<?php

$client = new Client();
$client->setUserID    ( $_POST['userID'   ]);
$client->setEmail     ( $_POST['email'    ]);
$client->setFirstname ( $_POST['firstname']);
$client->setLastname  ( $_POST['lastname' ]);
$client->setAddress1  ( $_POST['address1' ]);
$client->setAddress2  ( $_POST['address2' ]);
$client->setCity      ( $_POST['city'     ]);
$client->setProvince  ( $_POST['province' ]);
$client->setCountry   ( $_POST['country'  ]);

if ($client->submit($db) !== true)
{
    // do error handling
}

?>

Powyższy przykład demonstruje redukcje w logice aplikacji w stosunku do przykładu go poprzedzjącego. Interfejs zajmuje się komunikacją z bazą danych w czasie, gdy programista może się skupić jedynie na wynikach dokonanych operacji. Pisanie mniejszej ilości kodu w stosunku do tego samego zadania jest najbardziej korzystne, gdy różne części aplikacji używają tych samych poleceń DML. Wtedy zamiast powtarzania zapytań do bazy danych, można zwyczajnie użyć odpowiednich interfejsów.

Inną zaletą interfejsów bazodanowych jest mniejszy wpływ na aplikację zmian dokonanych w strukturze bazy. Zmiana w jednym tylko interfejsie jest dużo prostsza, niż wyszukiwanie i modyfikowanie kodu PHP i SQL w całym projekcie.

Tworzenie interfejsu bazodanowego

Istnieje kilka główmych wytycznych, którymi powinieneś się kierować w trakcie projektowania interfejsu.

  • Używaj programowania obiektowego z zachowaniem wszelkich jego zasad i przesłanek.
  • Czyń interfejs niezależnym i wyspecjalizowanym.
  • Oprzyj interfejs na standardowej budowie.
Uzywaj technik obiektowych

Każdy wymagany intefejs powinien być oparty na klasie. Klasa taka powinna być logicznym odwzorowaniem struktury odpowiedniej tabeli w bazie danych. Właściwości klasy reprezentują osobne kolumny w tabeli. Metody klasy powinny charakteryzować operacje DML i DQL (polecenia służące do pobierania danych - przyp. tłum.) na rekordach tabeli. Przykład poniżej ilustruje jak operacje DDL (polecenia służące do definiowania danych - przyp. tłum.) i DQL są zaimplementowane w metodach load(), submit() i delete().

<?php

class Client
    {
    
    var $clientID       = 0;
    var $firstName      = '';
    var $lastName       = '';
    var $emailAddress   = '';
    
    function Client() {}
    
    function load(&$db,$clientID)
    {
    $DQL = 'SELECT clientID,firstName,lastName,emailAddress '.
    'FROM client '.
    "WHERE clientID=$clientID";
    
    if ($row = $db->GetOne())
    {
    $clientID     = $row[ 'clientID'     ];
    $firstName    = $row[ 'firstName'    ];
    $lastName     = $row[ 'lastName'     ];
    $emailAddress = $row[ 'emailAddress' ];
    
    return true;
    } else {
    return false;
    }
    }
    
    function submit(&db)
    {
    // clean up the data.
    $clientID     = (int) $this->clientID;
    $firstName    = addslashes(trim( $firstName    ));
    $lastName     = addslashes(trim( $lastName     ));
    $emailAddress = addslashes(trim( $emailAddress ));
    
    if ($clientID == 0)
    {
    $DML = 'INSERT INTO client (clientID,firstName,lastName, '.
    'emailAddress) VALUES (NULL,'.
    "'$firstName','$lastName','$emailAddress')";
    
    if ($db->Execute($DML))
    {
    $this->clientID = $db->Insert_ID();
    return true;
    } else {
    return false;
    }
    } else {
    $DML = 'UPDATE client SET '.
    "firstName    = '$firstName    ,' ".
    "lastName     = '$lastName     ,' ".
    "emailAddress = '$emailAddress ,' ".
    "WHERE clientID= $clientID";
    
    if ($db->Execute($db))
    {
    return true;
    } else {
    return false;
    }
    }
    }
    
    function delete(&$db)
    {
    $DML = 'DELETE FROM client WHERE clientID='.$this->clientID;
    if ($db->Execute($db))
    {
    return true;
    } else {
    return false;
    }
    }
    
    function getClientID()
    {
    return $this->clientID;
    }
    function setClientID($clientID)
    {
    $this->clientID = $clientID;
    }
    
    function getFirstName()
    {
    return $this->firstName;
    }
    function setFirstName($firstName)
    {
    $this->firstName = $firstName;
    }
    
    function getLastName()
    {
    return $this->lastName;
    }
    function setLastName($lastName)
    {
    $this->lastName = $lastName;
    }
    
    function getEmailAddress()
    {
    return $this->emailAddress;
    }
    function setEmailAddress($emailAddress)
    {
    $this->emailAddress = $emailAddress;
    }
    }

?>
Niezależność i specjalizacja zadań

Buduj interfejs z zamiarem wykorzystania go w jednym konkretnym celu. Jest nim zazwyczaj tworzenie, aktualizowanie lub usuwanie wierszy z tablicy. Interfejsy bazodanowe powinny być samodzielne jak to tylko możliwe, ponieważ ułatwia to wykorzystywanie wielu z nich jednocześnie przy bardziej rozbudowanych zadaniach. Zespołowe użycie interfejsów jest znacznie uproszczone, kiedy każdy z nich ma ściśle określone zadania. (Zobacz przykład poniżej.)

Modelowanie interfejsów wg określonej konwencji

Posiadanie przez duże aplikacje wielu tabel w bazie danych, skutkuje w dużej liczbie interfejsów. Ich ustandaryzowana budowa ułatwia pracę i czyni szybszym zaznajomienie się z nimi. Stosuj stałe nazewnictwo, układ i sposób implementacji w celu uproszczenia ich (interfejsów) łączenia w czasie skomplikowanych działań.

Składamy wszystko w całość

Pojedynczy interfejs bazodanowy sam w sobie ma dosyć ograniczoną użyteczność. Jego możliwości zaobserujemy dopiero, kiedy uzyjemy go w wraz z pozostałymi interfejsami w celu wykonania bardziej złożonej operacji. Oto przykład, w którym korzystamy z kilku interfejsów, w celu dodania nowego postu do forum.

<?php
/* Notes:
   $db    - instance of ADOdb connection object.
   $user  - instance of the User DB Interface
   $topic - instance of the Topic DB Interface
*/
$db->StartTrans();

// update the user's total # of posts
$user->setNumPosts($user->getNumPosts() + 1);
$user->submit($db);

// update the topics # of messages
$topic->setNumMessages($topic->getNumMessage() + 1);
$topic->submit($db);

// create the new message
$message = new Message();
$message->setTopicID($topic->getTopicID());
$message->setTopic($_POST['userTopic']);
$message->setMessage($_POST['message']);
$message->setPoster($user->getUserID());
$message->submit($db);

$db->CompleteTrans();

?>
Wnioski

Ten artykuł miał na celu zapoznanie czytelnika z pojęciem interfejsu bazodanowego i jego użycia w aplikacjach. Gdy aplikacje PHP stają się coraz bardziej złożone, zarządzanie nimi - nieuchronnie - staje się trudniejsze. Interfejsy bazodanowe dostarczają mechanizmy i metodykę budowania rozbudowanych aplikacji znacznie łatwiej i szybciej.

O autorze
Informacje na podobny temat:
Wasze opinie
Wszystkie opinie użytkowników: (6)
Błąd...
Niedziela 24 Wrzesień 2006 9:06:04 am - Turgon

[code]
function submit(&db)
{
[ciach]
}
[/code]

a tak powinno być
[code]
function submit(&$db)
{
[ciach]
}
[/code]

Łączenie tabel
Czwartek 10 Sierpień 2006 2:19:28 pm - trax <admin_smc_at_o2.pl>

Artykuł w praktyczny sposób pokazuję jak uporać się z obsługą baz danych, prawda. Zauważmy jednak, że operacje wykonywane są na pojedynczych tabelach. Co się będzie działo, kiedy zażyczymy sobie wysłać do bazdy danych zaawansowane query, w którym wykożystać trzeba będzie kilka tabel, aby otrzymać precyzyjne informacje. Oczywiście może napisać klasę, która dziedziczyć będzie kilka klas odpowiadających interfejsom tabel, i wykonać kilka metod, ale wydaje mi się, że skrypt będzie wydajniejszy, gdy wykonamy jedno zapytanie do bazy, niz miało by być ich dziesięć. Czekam na kontynuację.

Active record
Niedziela 06 Sierpień 2006 8:09:42 pm - mieczyslaw83 <mieczyslaw83_at_wp.pl>

Przecież to jest właśnie Active Record???

cos nie tak
Poniedziałek 10 Lipiec 2006 12:44:41 pm - g00fy

jak poprzednicy uwazam ze ten sposob nie jest za dobrym rozwiazaniem ze wzgledow koncepcyjnych.
lepiej rozwazyc ORM. duzo lepsze rozwiazanie.

ActiveRecord
Sobota 08 Lipiec 2006 12:17:31 pm - kaczuuur <kaczuuur_at_op.pl>

Ja osobiście kożystam ze wzorca ActiveRecord do obsługi bazy danych ( został przedstawiony w PHP Solutions ). Jest znacznie bardziej uniwersalny i prostszy w zastosowaniu niż przykład podany w artykule.

Bazodabowe Interface
Czwartek 06 Lipiec 2006 10:29:13 pm - 060156 <060156_at_gmail.com>

To jakas tragedia konceptualna ...
Cos wydaje mi sie ze chyba raczej takich
bzdetow jako przyklady nie powinno sie zamieszczac tutaj, ktora ma sugerowac dobre wzory ...

Mentax.pl    NQ.pl- serwery z dodatkiem świętego spokoju...   
O nas | Kontakt | Mapa serwisu
Copyright (c) 2003-2017 php.pl    Wszystkie prawa zastrzeżone    Powered by eZ publish Content Management System eZ publish Content Management System