Klasa obsługi bazy danych , wstęp do Implementacji.

Krzysztof Jagielski
05.09.2015

Aby przedstawić w prosty sposób implementacje, stworzymy klasę obsługi baz danych. W tym celu, przyda nam się plik konfigurujący ową klasę.

<?php
$config['db']['host'] = 'localhost';
$config['db']['port'] = 3306; //domyslny port MySQL
$config['db']['user'] = 'uzytkownik';
$config['db']['password'] = 'haslo';
$config['db']['name'] = 'nazwa_bazy';
?>



Zastanówmy się jak poprawnie powinna być zbudowana klasa służąca połączeniom z bazy danych. Hm... Konstruktor powinien nawiązywać połączenie z bazą danych, natomiast destruktor zamknąć je.

<?php
require_once('config.php');

class Database {
private $connect;

  public function __construct() {
  global $config; //dostęp do globalnej tablicy config
  $this -> connect = @mysql_connect($config['db']['host'] .":". $config['db']['port'] ."," . $config['db']['user'] ."," . $config['db']['password']);
   $this -> connect .= @mysql_db_name($config['db']['name']);
    if(! is_resource($this -> connect)) {
         throw new Exception("Nie można nawiązać połączenia z bazą         korzystając z podanych danych! ". E_USER_ERROR);
   }

}

public function __destruct() {
   if(is_resource($this -> connect)) {
       @mysql_close($this -> connect);
    }
}
}
?>



No tak nasza klasa łączy się z bazą przy tworzeniu nowego jej egzemplarza i rozłącza po wykorzystaniu jej. Przydałyby się funkcje wykonujące operacje na bazie. Stwórzmy więc odpowiednią funkcje.

public function select($sql) {
      $res = @mysql_query($sql, $this -> connect);
       if(! is_resource($res)) {
            $error = mysql_error($this -> connect);
              throw new Exception($error);
        }

        $arrayReturn = array();
          while( ($row = mysql_fetch_assoc($res))) {
                $arrayReturn[] = $row;
           }
     return $arrayReturn;
}



Funkcja ta zwraca dwuwymiarową tablicę, gdzie każdy wiersz zwrócony przez SQL odpowiada pierwszemu wymiarowi tablicy, a drugi wymiar zwraca nazwa pola z bazy.

Teraz wypadałoby napisać funkcję, która dodawałaby rekordy do bazy.

public function insert($table, $arrayFieldValues) {
$values = array_keys($arrayFieldValues);

//Tworzy tablicę wartość, która zostanie
// dołączona do VALUES

$escapeVals = array();
foreach($values as $val) {
if(! is_numeric($val)) {
//cytuje dane

$val = "'" . mysql_escape_string($val) . "'";
}

$escapeVals[] = $val;
}

//Tworzy polecenie SQL
$sql = " INSERT INTO " . $table . "(" . $fields . ") VALUES('". $escapeVals ."')";
$res = mysql_query($sql);
if(! is_resource($res)) {
$error = mysql_error($this -> connect) . " " . $sql;
throw new Exception($error);
}

return mysql_affected_row($res);
}




Powyższa metoda przyjmuje jako parametry nazwę tabeli oraz tablicę, które pola w danej tablicy mają być zmienione. Odpowiada za dodanie nowego rekordu.

Teraz napiszemy funkcję aktualizująca dane w tabeli, przyjmuje podobne argumenty co funkcja insert() .

public function update($table, $arrayFieldValues, $arrayConditions = false) {

//tworzy tabelę dla SET
$arrayUpdates = array();
foreach($arrayFieldValues as $field => $val) {
if(!is_numeric($val)){
$val = "'" . mysql_escape_string($val) . "'";
}

$arrayUpdates[] = "$field = $val";
}


//Sprawdza czy podano warunki, dla których rekordów wartość pola w tabeli
// ma być zmieniona.
if ( $arrayConditions == false) {
$sql = "UPDATE " . $table . " SET ". $arrayUpdates ."";
$res = mysql_query($sql);

if(! is_resource($res)) {
   $error =  mysql_error($this -> connect) . " " . $sql;
   throw new Exception($error);
}

return mysql_affected_rows($res);

} else {


//jeśli zastosowano WHERE

$arrayWhere = array();
foreach($arrayConditions as $field => $val) {
   if(! is_numeric($val)) {
         $val = "'" . mysql_escape_string($val) . "'";
  }
$arrayWhere[] = "$field = $val";
}

$sql = "UPDATE " . $table . " SET ". $arrayUpdates ." WHERE ". $arrayWhere ."";

$res = mysql_query($sql);

if(! is_resource($res)) {
   $error =  mysql_error($this -> connect) . " " . $sql;
   throw new Exception($error);
}

return mysql_affected_rows($res);

}
}



Funkcja, którą napisaliśmy sprawdza czy zostały przesłana warunki do pól , które mają być zmienione. Jak tak , zmienia tylko te pola, a jak nie, zmienia wszystkie w tabeli. Napiszemy teraz funkcję kasującą rekordy, które spełnią podany w skrypcie warunek.

public function delete($table, $arrayConditions) {

$arrayWhere= array();

foreach($arrayConditions as $field => $val) {
if(! is_numeric($val)) {
$val = "'" . mysql_escape_string($val) . "'";
}

$arrayWhere[] = "$field = $val";

}

$sql = "DELETE FROM " . $table . " WHERE " . $arrayWhere . ";
$res = mysql_query($sql);

if(! is_resource($sql)) {
    $error = mysql_error($this -> connect) . " " . $sql;
    throw new Exception($error);
}
return mysql_affected_rows($res);
}



I gotowe. Nasza klasa prezentuje sie tak:

<?php
require_once('config.php');

class Database {
private $connect;

  public function __construct() {
  global $config; //dostęp do globalnej tablicy config
  $this -> connect = @mysql_connect($config['db']['host'] .":". $config['db']['port'] ."," . $config['db']['user'] ."," . $config['db']['password']);
   $this -> connect .= @mysql_db_name($config['db']['name']);
    if(! is_resource($this -> connect)) {
         throw new Exception("Nie można nawiązać połączenia z bazą         korzystając z podanych danych! ". E_USER_ERROR);
   }

}

public function __destruct() {
   if(is_resource($this -> connect)) {
       @mysql_close($this -> connect);
    }
}

public function select($sql) {
      $res = @mysql_query($sql, $this -> connect);
       if(! is_resource($res)) {
            $error = mysql_error($this -> connect);
              throw new Exception($error);
        }

        $arrayReturn = array();
          while( ($row = mysql_fetch_assoc($res))) {
                $arrayReturn[] = $row;
           }
     return $arrayReturn;
}

public function insert($table, $arrayFieldValues) {
$values = array_keys($arrayFieldValues);

//Tworzy tablicę wartość, która zostanie
// dołączona do VALUES

$escapeVals = array();
foreach($values as $val) {
if(! is_numeric($val)) {
//cytuje dane

$val = "'" . mysql_escape_string($val) . "'";
}

$escapeVals[] = $val;
}

//Tworzy polecenie SQL
$sql = " INSERT INTO " . $table . "(" . $fields . ") VALUES('". $escapeVals ."')";
$res = mysql_query($sql);
if(! is_resource($res)) {
$error = mysql_error($this -> connect) . " " . $sql;
throw new Exception($error);
}

return mysql_affected_row($res);
}

public function update($table, $arrayFieldValues, $arrayConditions = false) {

//tworzy tabelę dla SET
$arrayUpdates = array();
foreach($arrayFieldValues as $field => $val) {
if(!is_numeric($val)){
$val = "'" . mysql_escape_string($val) . "'";
}

$arrayUpdates[] = "$field = $val";
}


//Sprawdza czy podano warunki, dla których rekordów wartość pola w tabeli
// ma być zmieniona.
if ( $arrayConditions == false) {
$sql = "UPDATE " . $table . " SET ". $arrayUpdates ."";
$res = mysql_query($sql);

if(! is_resource($res)) {
   $error =  mysql_error($this -> connect) . " " . $sql;
   throw new Exception($error);
}

return mysql_affected_rows($res);

} else {


//jeśli zastosowano WHERE

$arrayWhere = array();
foreach($arrayConditions as $field => $val) {
   if(! is_numeric($val)) {
         $val = "'" . mysql_escape_string($val) . "'";
  }
$arrayWhere[] = "$field = $val";
}

$sql = "UPDATE " . $table . " SET ". $arrayUpdates ." WHERE ". $arrayWhere ."";

$res = mysql_query($sql);

if(! is_resource($res)) {
   $error =  mysql_error($this -> connect) . " " . $sql;
   throw new Exception($error);
}

return mysql_affected_rows($res);

}
}


public function update($table, $arrayFieldValues, $arrayConditions = false) {

//tworzy tabelę dla SET
$arrayUpdates = array();
foreach($arrayFieldValues as $field => $val) {
if(!is_numeric($val)){
$val = "'" . mysql_escape_string($val) . "'";
}

$arrayUpdates[] = "$field = $val";
}


//Sprawdza czy podano warunki, dla których rekordów wartość pola w tabeli
// ma być zmieniona.
if ( $arrayConditions == false) {
$sql = "UPDATE " . $table . " SET ". $arrayUpdates ."";
$res = mysql_query($sql);

if(! is_resource($res)) {
   $error =  mysql_error($this -> connect) . " " . $sql;
   throw new Exception($error);
}

return mysql_affected_rows($res);

} else {


//jeśli zastosowano WHERE

$arrayWhere = array();
foreach($arrayConditions as $field => $val) {
   if(! is_numeric($val)) {
         $val = "'" . mysql_escape_string($val) . "'";
  }
$arrayWhere[] = "$field = $val";
}

$sql = "UPDATE " . $table . " SET ". $arrayUpdates ." WHERE ". $arrayWhere ."";

$res = mysql_query($sql);

if(! is_resource($res)) {
   $error =  mysql_error($this -> connect) . " " . $sql;
   throw new Exception($error);
}

return mysql_affected_rows($res);

}
}

}
?>



Można ją wykrozystać np. tak:

<?php

require_once('class.Database.phpm');

try {
$objDB = new Database();
} catch (Exception $e) {
echo $e -> getMessage();
exit(1);
}

try {
$table = "mojatabela";
  $objDB -> insert($table, array('mojepole' => 'wartosc_mojego_pola'));
  $data = $objDB -> select("SELECT * FROM mojatabela");
   var_dump($data);
  $objDB -> update($table, array('mojepole' => 'inna_wartosc'), array('mojepole => 'wartosc_mojego_pola'));
  $data = $objDB -> select("SELECT * FROM mojatabela");
   var_dump($data);
$objDB -> delete($table, array('mojawartosc' => 'inna_wartosc');
} catch (Exception $e) {
echo "błąd wykonania zapytania" . " ";
echo $e -> getMessage();
}
?>



Funkcja insert, tworzy nowe pole, następnie update zmienia to pole, by polecenie delete mogło owe pole skasować. Dzięki wcześniej napisanej klasie możemy korzystać wygodnie, praktycznie bez korzystania z zapytań SQL.

Pisane z palca, wiec parę błędów może być.

Zgłoś swój pomysł na artykuł

Więcej w tym dziale Zobacz wszystkie