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ć.