349 lines
8.2 KiB
PHP
349 lines
8.2 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Speicherung in einer MySQL-Datenbank
|
||
|
*
|
||
|
* Der Zugriff auf die Datenbank erfolgt über CRUD ZugriffsFunktionen
|
||
|
* - create
|
||
|
* - retrieve
|
||
|
* - update
|
||
|
* - del
|
||
|
* - query
|
||
|
*
|
||
|
* Weiterhin gibt es:
|
||
|
* - clear_table
|
||
|
* - optimize_table
|
||
|
*
|
||
|
* @version 0.2.1
|
||
|
*/
|
||
|
class fl_data_access_mysql extends fl_data_access_database implements data_access {
|
||
|
protected $connection;
|
||
|
public $database;
|
||
|
|
||
|
public $table_prefix = '';
|
||
|
|
||
|
public $true_value = 1;
|
||
|
public $false_value = 0;
|
||
|
|
||
|
public function __construct($config) {
|
||
|
$this->table_prefix = (string) $config['table_prefix'];
|
||
|
$this->_open_db($config['host'], $config['database'], $config['user'], $config['pass']);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbankeintrag erzeugen
|
||
|
*
|
||
|
* Die create-Methode bietet eine Schnittstelle, um Daten zur Datenbank
|
||
|
* hinzuzufügen.
|
||
|
*
|
||
|
* @param string $table Tabellenname
|
||
|
* @param array $data assoziatives Array, das die Daten enthält.
|
||
|
* @param string $type Art der Einfügeoperation (INSERT, INSERT IGNORE, REPLACE)
|
||
|
* @return string Ergebnis der Datenbankoperation
|
||
|
*/
|
||
|
public function create($table, array $data, $type='INSERT') {
|
||
|
$data_length = count($data);
|
||
|
$i = 0;
|
||
|
|
||
|
switch ( strtoupper($type) ) {
|
||
|
case 'IGNORE':
|
||
|
case 'INSERT IGNORE':
|
||
|
$type = 'INSERT IGNORE';
|
||
|
break;
|
||
|
|
||
|
case 'REPLACE':
|
||
|
case 'INSERT':
|
||
|
$type = strtoupper($type);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
$type = 'INSERT';
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
$sql = $type . " INTO ".$this->get_table_name($table)." SET ";
|
||
|
foreach ($data as $field=>$content) {
|
||
|
$this->_secureFieldContent($content);
|
||
|
|
||
|
$sql .= " ".$field."='".$content."'";
|
||
|
if ( ( $data_length - 1 ) > $i++ )
|
||
|
$sql .= ",";
|
||
|
}
|
||
|
|
||
|
$result = $this->query($sql);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbankeintrag holen
|
||
|
*
|
||
|
* Die retrieve-Methode bietet eine Schnittstelle, um Daten aus der
|
||
|
* Datenbank zu lesen.
|
||
|
*
|
||
|
* @param string $table Tabellenname
|
||
|
* @param string $field Feldnamen, die abgefragt werden
|
||
|
* @param string $condition Bedigungen, nach denen die Tabellenzeilen ausgewählt werden
|
||
|
* @param string $order Sortierungsreihenfolge
|
||
|
* @param string $limit maximale Anzahl von Zeilen
|
||
|
* @return array Assoziatives Array mit den Daten.
|
||
|
*/
|
||
|
public function retrieve($table, $field='*', $condition='', $order='', $limit='') {
|
||
|
if ( $limit == '') {
|
||
|
$sql_limit = FALSE;
|
||
|
} elseif ( strpos($limit, ',') === FALSE ) {
|
||
|
$sql_limit = '0,' . $limit;
|
||
|
} else {
|
||
|
$sql_limit = $limit;
|
||
|
}
|
||
|
|
||
|
$sql = "SELECT ".$field." FROM ".$this->get_table_name($table);
|
||
|
if ( !empty($condition) )
|
||
|
$sql .= " WHERE ".$condition;
|
||
|
if ( !empty($order) )
|
||
|
$sql .= " ORDER BY ".$order;
|
||
|
if ( $sql_limit !== FALSE )
|
||
|
$sql .= " LIMIT ".$sql_limit;
|
||
|
|
||
|
$result = $this->query($sql);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbankeintrag aktualisieren
|
||
|
*
|
||
|
* Die update-Methode bietet eine Schnittstelle, um Daten in der Datenbank
|
||
|
* zu aktualisieren. Dies ist die vermutlich die häufigste Form der
|
||
|
* Speicherung.
|
||
|
*
|
||
|
* @param string $table Tabellenname
|
||
|
* @param array $data assoziatives Array, das die Daten enthält.
|
||
|
* @param int $id id des Datenbankeintrages
|
||
|
* @param string $id_field Feldname des id-Feldes
|
||
|
* @param boolean $all Alle Zeilen verändern
|
||
|
*
|
||
|
* @return string Ergebnis der Datenbankoperation
|
||
|
*/
|
||
|
public function update($table, array $data, $id, $id_field='id', $all=FALSE) {
|
||
|
$data_length = count($data);
|
||
|
$i = 0;
|
||
|
|
||
|
$sql = "UPDATE ".$this->get_table_name($table)." SET".PHP_EOL;
|
||
|
foreach ($data as $field=>$content) {
|
||
|
$this->_secureFieldContent($content);
|
||
|
|
||
|
$sql .= " ".$field."='".$content."'";
|
||
|
if ( ($data_length - 1 ) > $i++ )
|
||
|
$sql .= ",";
|
||
|
}
|
||
|
if ( !$all ) {
|
||
|
$sql .= " WHERE ".$id_field."='".$id."'";
|
||
|
}
|
||
|
|
||
|
$result = $this->query($sql);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbankeintrag löschen
|
||
|
*
|
||
|
* Die del-Methode bietet eine Schnittstelle, um Daten aus der Datenbank
|
||
|
* zu löschen.
|
||
|
*
|
||
|
* @param string $table Tabellenname
|
||
|
* @param int $id id des Datenbankeintrages
|
||
|
* @return boolean Ergebnis der Datenbankoperation
|
||
|
*/
|
||
|
public function del($table, $id) {
|
||
|
if ( !is_numeric($id) ) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
$sql = "DELETE FROM ".$this->get_table_name($table)."
|
||
|
WHERE id='".$id."' LIMIT 1";
|
||
|
|
||
|
$result = $this->query($sql);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbank-Ergebnisse in richtige Typen umwandeln
|
||
|
*
|
||
|
* @param string table
|
||
|
* @param array $result
|
||
|
* @return array
|
||
|
* @todo Funktion fuer MySQL umarbeiten
|
||
|
*/
|
||
|
public function convert_result($table, $result) {
|
||
|
return $result;
|
||
|
|
||
|
$table = $this->get_table_name($table);
|
||
|
$converted = $result;
|
||
|
|
||
|
$sql = <<<SQL
|
||
|
SELECT column_name AS col, CASE
|
||
|
WHEN data_type = 'numeric' THEN 'float'
|
||
|
ELSE data_type
|
||
|
END AS type
|
||
|
FROM information_schema.columns
|
||
|
WHERE table_name='{$table}'
|
||
|
AND data_type IN ('boolean', 'integer', 'numeric');
|
||
|
SQL;
|
||
|
$types = $this->query($sql);
|
||
|
|
||
|
foreach ( $result as $row_num => $rows ) {
|
||
|
foreach ( $types as $type ) {
|
||
|
$col = $type['col'];
|
||
|
$new_type = $type['type'];
|
||
|
$converted[$row_num][$col] = settype($row[$col], $new_type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $converted;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Tabelle leeren
|
||
|
*
|
||
|
* @param string $table Tabellennname
|
||
|
* @return boolean
|
||
|
*/
|
||
|
public function clear_table($table) {
|
||
|
$sql = 'TRUNCATE TABLE '.$this->get_table_name($table);
|
||
|
|
||
|
$result = (boolean) $this->query($sql);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Tabelle optimieren
|
||
|
*
|
||
|
* @param string $table Tabellenname
|
||
|
* @return boolean
|
||
|
*/
|
||
|
public function optimize_table($table) {
|
||
|
$sql = 'OPTIMIZE TABLE ' . $this->get_table_name($table);
|
||
|
|
||
|
$result = (boolean) $this->query($sql);
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbankabfrage als SQL abgeben
|
||
|
*
|
||
|
* @param string $sql
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public function query($sql) {
|
||
|
return $this->_query_db($sql);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Zuletzt eingefügte ID zurückgeben
|
||
|
*
|
||
|
* @param string $table
|
||
|
* @return integer
|
||
|
*/
|
||
|
public function last_insert_id($table) {
|
||
|
return mysql_insert_id($this->connection);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Eindeutigen Bezeichner für eine Tabelle zurückgeben
|
||
|
*
|
||
|
* @param string $table
|
||
|
* @return string
|
||
|
*/
|
||
|
public function get_table_name($table) {
|
||
|
return $this->table_prefix . $table;
|
||
|
}
|
||
|
|
||
|
// interne Funktionen
|
||
|
/**
|
||
|
* Datenbankverbindung öffnen
|
||
|
*
|
||
|
* @param string $host
|
||
|
* @param string $db
|
||
|
* @param string $user
|
||
|
* @param string $pass
|
||
|
*/
|
||
|
private function _open_db($host, $db, $user, $pass) {
|
||
|
if ( !extension_loaded('mysql') ) {
|
||
|
die("PHP-Erweiterung 'mysql' nicht geladen");
|
||
|
}
|
||
|
|
||
|
$this->connection = @mysql_connect( $host, $user, $pass)
|
||
|
OR die("Keine Verbindung zur Datenbank möglich. Fehlermeldung: ".mysql_error($this->connection));
|
||
|
$this->database = $db;
|
||
|
|
||
|
mysql_query('SET NAMES "utf8"', $this->connection);
|
||
|
|
||
|
$this->_select_db();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbank auswählen
|
||
|
*/
|
||
|
private function _select_db() {
|
||
|
mysql_select_db($this->database)
|
||
|
OR die("Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenbank abfragen
|
||
|
*
|
||
|
* @param mixed $sql String oder Array, das die SQL-Abfragen enthält
|
||
|
* @todo Funktion überarbeiten
|
||
|
* @return mixed
|
||
|
*/
|
||
|
private function _query_db($sql) {
|
||
|
$this->_select_db();
|
||
|
|
||
|
if ( is_array($sql) ) {
|
||
|
foreach ( $sql as $nr => $query ) {
|
||
|
$output[$nr] = $this->query( $query );
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
$this->log_query($sql);
|
||
|
|
||
|
$output = array();
|
||
|
$aktionen = array('UPDATE','DELETE', 'ALTER ', 'CREATE', 'DROP T', 'TRUNCA', 'REPLAC', 'OPTIMI');
|
||
|
|
||
|
$abfrage = is_string($sql) ? trim($sql) : $this->error('Fehlerhafte Daten', $sql);
|
||
|
|
||
|
$result = mysql_query($abfrage, $this->connection) OR $this->error(mysql_error($this->connection), $sql);
|
||
|
|
||
|
$abfragetyp = strtoupper(substr($abfrage,0,6));
|
||
|
|
||
|
if ( ( in_array($abfragetyp,$aktionen) ) ) {
|
||
|
$output = ( $result )? TRUE: FALSE;
|
||
|
} elseif ( ($abfragetyp == 'INSERT') ) {
|
||
|
$output = ( $result )? $this->last_insert_id(): FALSE;
|
||
|
} else {
|
||
|
while($row = mysql_fetch_assoc($result)) {
|
||
|
$output[] = $row;
|
||
|
}
|
||
|
}
|
||
|
unset($abfragetyp);
|
||
|
unset($aktionen);
|
||
|
|
||
|
}
|
||
|
return $output;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Feldinhalte gegen Hackingversuche schützen
|
||
|
*
|
||
|
* Dies sind nur grundlegende Schutzmaßnahmen
|
||
|
*
|
||
|
* @param mixed &$var
|
||
|
*/
|
||
|
private function _secureFieldContent(&$var){
|
||
|
if ( is_array($var) ) {
|
||
|
$varvalue = var_export($var, TRUE);
|
||
|
$this->error('Array sollte gespeichert werden.', $varvalue );
|
||
|
}
|
||
|
$var = mysql_real_escape_string($var, $this->connection);
|
||
|
}
|
||
|
}
|
||
|
?>
|