Scripts

Class: Databases

Ik heb deze class geschreven omdat ik ten eerste aan het experimenteren ben met OOP en ik makkelijk van database zou willen wisselen. Dus als ik over 2 weken denk van: Laat ik nu eens MySQLi gebruiken i.p.v. MySQL dan schrijf ik die class (door het gebruikenv an de bestaande class) en verander het type en mijn systeem werkt op MySQLi. Hoe simpel kan het zijn. Dus je kan óók tussen PostgreSQL en MySQL switchen (voor zover de sql code hetzelfde blijft). Verdere documentatie zit in de code. Ik heb dit script óók op phpfreakz gepost (dus het is géén rip). Ik post deze hier omdat ik zelf geen class kan vinden die je zo kunt uitbreiden en er geen kan vinden die query's opslaat. Je hoeft dus niet per sé een resource mee te geven omdat het script deze zelf opslaat en gebruikt (van de laatste query).

class-databases
Uitleg
------
[code]<?php
//Voorbeeld om zelf een child class te maken:
class mysqliDatabase extends databaseCore {
	//Declare alle abstracte functies (ev. meer)
}
//Je kan type veranderen (bij getConnection) in mysqli en het script zoekt het verder uit.

############################################################################

//class opzetten (port & socket worden in de MySQL variant niet gebruikt.
$db = databaseCore::getConnection(array(
											'type' 		=> 'mysql', //Hier de prefix van de child class. 
											'host' 		=> '', 
											'port'		=> '', //Wordt niet gebruikt bij mysql, voeg toe bij host.
											'socket' 	=> '', //Wordt niet gebruikt bij mysql, gebruik host.
											'user' 		=> '', 
											'password' 	=> '', 
											'dbname' 	=> ''
										), [$debug=false[, $connect=true]]);

//Query uitvoeren (retourneert het result)
$db->query($sqlCode);

//Meerdere query's uitvoeren (kunnen zoveel query's in als je wilt)
$db->multiQuery($sqlCode[, $...  ]);

//Rijen ophalen (zonder een argument wordt de laatste query gebruikt)
$db->fetch([$result]);

//Aantal rijen tellen (zonder een argument wordt de laatste query gebruikt)
$db->numRows([$result]);

//Geeft het aantal results van de laatste UPDATE, INSERT etc. query terug.
$db->affectedRows();

//Escaped zodat het veilig is in te voegen (zoals mysql_real_escape_string)
$db->escape($str);

//Geeft laatste insert id terug (zoals mysql_insert_id)
$db->insertId();

//Retourneert de SQL code of het RESULT van een query die is uitgevoerd
$db->getQuery($id); //id begint altijd met een q of een r, q staat voor de sql code, r staat voor het result. Daarna wordt een integer verwacht (het echte id)

//Aantal query's dat is uitgevoerd.
$db->getQueryTime();

//Retourneert de waarde van $this->debug
$db->getDebug();

//Veranderd het debug variabel
$db->setDebug($str); //Str kan zij: true, false of switch

//Verbinding maken
$db->connect(); //Gebruik deze alleen als je het standaard verbinden hebt uitgeschakeld. Anders wordt dit automatisch gedaan!
?>[/code]

Voorbeeld.php
-------------
[code]<?php
require_once('databasecore.class.php');
require_once('mysqldatabase.class.php');

try {
   	$db = databaseCore::getConnection(array(
												'type' 		=> 'mysql', 
												'host' 		=> 'HOST', 
												'user' 		=> 'USER', 
												'password' 	=> 'PASSWORD', 
												'dbname' 	=> 'DATABASE_NAME'
											), true, false);
    $db->query("SELECT * FROM test");
    while($row = $db->fetch()) {
        echo $row['name'].' zegt: '.$row['message'].'<br />';
    }
    echo 'Total messages: '.$db->numRows().'<br />';
} catch(Exception $e) {
    echo $e->getMessage().'<br />Code: '.$e->getCode().'<br />Line: '.$e->getLine().'<br />File: '.$e->getFile();
    if($e->getCode() > 100) {
        exit;
    }
}

try {
    $db->multiQuery(    "UPDATE status SET sitestatus = 'offline' WHERE id = 1",
                        "INSERT INTO users(name, pass, email) VALUES ('Pietje', '".md5('Dit_is_een_slecht_wachtwoord')."', '".$db->escape('[email protected]')."')",
                        "UPDATE users SET ip = '".$_SERVER['REMOTE_ADDR']."' WHERE name = 'Pietje'",
						"SELECT * FROM test"
                    );
	while($row = $db->fetch()) {
        echo $row['name'].' zegt: '.$row['message'].'<br />';
    }
} catch(Exception $e) {
    echo $e->getMessage().'<br />Code: '.$e->getCode().'<br />Line: '.$e->getLine().'<br />File: '.$e->getFile();
    if($e->getCode() > 100) {
        exit;
    }
}
?>[/code]

databasecore.class.php
-----------------------
[code]<?php
/**
 * databaseCore
 * @package databaseConnector
 * @author Tom Janssen
 * @copyright Copyright (c) 2009, Tom Janssen
 * @license Free to use under GNU General Public License {@link http://www.gnu.org/licenses/gpl.html}
 * @version 1.1.3
 */
abstract class databaseCore {
	/**
	 * General error level, generated by among other querys
	 */
	const GEN_ERROR = 100;
	/**
	 * General error level, generated by among other connection failure
	 */
	const CON_ERROR = 200;
	/**
	 * General error level, generated by among other setup failure
	 */
	const FAT_ERROR = 250;
	/**
     * Holds the link identifier
     * @access protected
     * @var mixed
     */
    protected $_dblink;
   
    /**
	 * Holds all the host settings before connecting
	 * @static
     * @access protected
     * @var array
     */
    static protected $_data = array 	(
								'type'		=> '',
								'host'		=> '',
								'port'		=> '',
								'socket'	=> '',
								'user'		=> '',
								'password'	=> '',
								'dbname'	=> ''
							);
	
	 /**
	 * Holds all the host settings that the user has given.
     * @access protected
     * @var array
     */
    protected $_userdata = array ();
   
    /**
     * Debug true or false. Default false.
     * @access protected
     * @var bool
     */
    protected $debug = false;
   
    /**
     * Holds all query's in order of executing
     * @access protected
     * @var array
     */
    protected $queryCache = array();
    /**
     * Holds the 'id' of the last query.
     * @access protected
     * @var int
     */
    protected $queryTime = 0; //Dit is het aantal querys dat is uitgevoerd.

    /**
     * Constructor, sets the connecting vars and connects. Also set debug to true.
     * @access public
     * @param bool $debug holds the debug choise
     */
    public function __construct($debug=false) {
        if($debug === true) {
            $this->debug = true;
        }
    }
	
	/**#@+
	 * @abstract
	 */
	/**
     * connect, called by functions who connect to MySQL.
     * @access protected
     */
	abstract public function connect();
	
    /**
     * checkConnection, checks if there is a connection.
     * @access protected
     * @return bool
     */
	abstract protected function checkConnection();
	
	/**
     * escape, alias of mysql_real_escape_string
     * @access public
     * @param string $toEcape string to escape with mysql_real_escape_string.
     * @return string
     */
    abstract public function escape($toEscape);
	
	/**
     * query, tries to execute a query.
     * @access public
     * @param string $sql SQL code to execute.
     * @return string
     */
    abstract public function query($sql);
	
	/**
     * multiQuery, excecutes so many query's if you want. Just add more SQL codes.
     * @access public
     * @param string $sql,.. you can add this parameter many times as you want.
     */
    abstract public function multiQuery();
	
	/**
     * fetch, if no parameter is given, use last query.
     * @access public
     * @param [string $query] contains a query resource or an query ID starting with a 'r'. Not required to be given.
     * @return array
     */
    abstract public function fetch();
	
	/**
     * numRows, if no parameter is given, use last query.
     * @access public
     * @param [string $query] contains a query resource or an query ID starting with a 'r'
     * @return int
     */
    abstract public function numRows();
	
	/**
     * affectedRows, gives affected rows from last UPDATE, INSERT etc. query.
     * @access public
     * @return int
     */
    abstract public function affectedRows();
	
	/**
     * insertId, gives last insert id.
     * @access public
     * @return int
     */
    abstract public function insertId();
	
	/**#@-*/ 
	
	/**
     * setDebug, change debug setting
     * @access public
     * @param bool $newValue sets debug on true or false.
     * @return bool
     */
    public function setDebug($newValue) {
        if($newValue === true || $newValue === false) {
            $this->debug = $newValue;
            return true;
        } elseif($newValue === 'switch') {
            if($this->debug === true) {
                $this->debug = false;
                return true;
            } elseif($this->debug === false) {
                $this->debug = true;
                return true;
            }
        }
       
        return false;
    }
   
    /**
     * getDebug, get the debug setting
     * @access public
     * @return bool
     */
    public function getDebug() {
        return $this->debug;
    }
   
    /**
     * getQueryTime, returns the $queryTime variable.
     * @access public
     * @return int
     */
    public function getQueryTime() {
        return $this->queryTime;
    }
   
    /**
     * getDebug, get the debug setting
     * @access public
     * @param string $id hold the ID starting with a 'q' or a 'r'.
     * @return array
     */
    public function getQuery($id) {
        $type = substr($id, 0, 1);
        if(ctype_digit(substr($id, 1)) && $id >= 0 && $type === 'q' || $type === 'r') {
            if($id <= $this->queryTime) {
                return $this->queryCache[$type][$id];
            }
        }
       
        //Return false in alle andere gevallen.
        return false;
    }

    /**
    * Hiermee selecteer je een database type.
	* @static
	* @since version 1.1
	* @param array $data contains all data wich are importent to connect.
    */
    static public function getConnection(array $data = null, $debug=false, $connect=true) {
		if(!!!($keys = array_diff_key($data, self::$_data))) {
			$data = array_merge(self::$_data, $data);
		} else {
			$_s = (count($keys) > 1) ? 's' : '';
			throw new Exception('Geen valid parameter '.$_s.': '.implode(', ', $keys), self::FAT_ERROR);   
		} 
				$class = $data['type'].'Database';
				if(class_exists($class, false) === true) {
					return new $class($data, $debug, $connect);
				}
			throw new Exception('Het type dat is opgegeven klopt niet. Gebruik een ander type aan of definieer deze class.', self::FAT_ERROR);
    }
}
?>[/code]

mysqldatabase.class.php
-----------------------
[code]<?php
/**
 * mysqlDatabase
 * @package databaseConnector
 * @author Tom Janssen
 * @copyright Copyright (c) 2009, Tom Janssen
 * @license  Free to use under GNU General Public License {@link http://www.gnu.org/licenses/gpl.html}
 * @version 1.1.3
 */
class mysqlDatabase extends databaseCore {
	/**
     * Constructor
     * @access public
     * @param array $data contains all needed data to set up a connection
     */
	public function __construct(array $data, $debug=false, $connect=true) {
		parent::__construct($debug);
		
		if(isset($data['host'], $data['user'], $data['password'], $data['dbname'])) {
			$this->_userdata = $data;
			
			if($connect === true) {
				try {
					$this->connect();
				} catch(Exception $e) {
					//Errors doorsturen.
					throw $e;
				}
			}
		} else {
			throw new Exception('Niet genoeg gegevens meegestuurd.', self::FAT_ERROR);
		}
	}
	
	/**
     * Connector, hiermee zet het script een connectie op met de eerder ingevoerde gegevens.
     * @access public
     */
	public function connect() {
		$this->_dblink = mysql_connect($this->_userdata['host'], $this->_userdata['user'], $this->_userdata['password']);
		
		if($this->_dblink === false) {
			$errorMessage = "Kon geen verbinding maken met de database maken.";
			if($this->debug === true) {
				$errorMessage .= "<br />".mysql_errno().": ".mysql_error();
			}
		} else {
			//Probeer nu de database te selecteren
			$dbbase = mysql_select_db($this->_userdata['dbname'], $this->_dblink);
			
			//Database select error handler
			if($dbbase === false) {
				$errorMessage = "Kon geen database selecteren.";
				if($this->debug === true) {
					$errorMessage .= "<br />".mysql_errno().": ".mysql_error();
				}
			}
		}
		
		if(isset($errorMessage)) {
			throw new Exception($errorMessage, self::FAT_ERROR);
		}
	}
	
	/**
     * checkConnection, checks if there is a connection, alias from mysql_ping.
	 * @access protected
     * @return bool
     */
	protected function checkConnection() {
		//Doe dit omdat als er nog geen connectie is er een lelijke error komt.
		if($this->_dblink !== NULL) {
			return mysql_ping($this->_dblink);
		}
		
		return false;
	}
	
	/**
     * escape, alias of mysql_real_escape_string
     * @access public
     * @param string $toEcape string to escape with mysql_real_escape_string.
     * @return string
     */
    public function escape($toEscape) {
		//Doe dit omdat als er nog geen connectie is er een lelijke error komt.
		if($this->_dblink !== NULL) {
	        return mysql_real_escape_string($toEscape, $this->_dblink);
		}
		
		return mysql_real_escape_string($toEscape);
    }
   
    /**
     * query, tries to execute a query.
     * @access public
     * @param string $sql SQL code to execute.
     * @return string
     */
    public function query($sql) {
        if($this->checkConnection() === true) {
            $this->queryTime++;
            $this->queryCache['q'][$this->queryTime] = $sql;
           
            $query = mysql_query($sql, $this->_dblink);
            if($query !== false) {
                $this->queryCache['r'][$this->queryTime] = $query;
                return $query;
            }
            $errorMessage = "Kon geen query verzenden.";
            $eC = self::GEN_ERROR;
            $this->queryCache['r'][$this->queryTime] = mysql_error($this->_dblink);
        } else {
            $errorMessage = "Kon geen verbinding vinden.";
            $eC = self::CON_ERROR;
        }
       
        if($this->debug === true && $eC != self::CON_ERROR) {
            $errorMessage .= "<br />".mysql_errno($this->_dblink).": ".mysql_error($this->_dblink);
        }
        throw new Exception($errorMessage, $eC);
    }
   
    /**
     * multiQuery, excecutes so many query's if you want. Just add more SQL codes.
     * @access public
     * @param string $sql,.. you can add this parameter many times as you want.
     */
    public function multiQuery() {
        if($this->checkConnection() === true) {
            $numArgs = func_num_args();
            if($numArgs === 1) {
                return $this->query(func_get_arg(0));
            }
                for($i = 0; $i < $numArgs; $i++) {
                    $this->queryTime++;
                    $this->queryCache['q'][$this->queryTime] = func_get_arg($i);
                   
                        $query = mysql_query($this->queryCache['q'][$this->queryTime], $this->_dblink);
                        if($query !== false) {
                            $this->queryCache['r'][$this->queryTime] = $query;
                        } else {
                            $errorMessage = "Kon de query met id #".$this->queryTime." niet verzenden!";
                            $this->queryCache['r'][$this->queryTime] = mysql_error($this->_dblink);
                           
                            if($this->debug === true) {
                                $errorMessage .= "<br />".mysql_errno($this->_dblink).": ".mysql_error($this->_dblink);
                            }
                            throw new Exception($errorMessage, self::GEN_ERROR);
                        }
                   
                    $query = NULL;
                }
        } else {
			//Errors onmogelijk omdat er geen verbinding is.
            $errorMessage = "Kon geen verbinding vinden.";
            throw new Exception($errorMessage, self::CON_ERROR);
        }
    }
   
    /**
     * fetch, if no parameter is given, use last query.
     * @access public
     * @param string $query contains a query resource or an query ID starting with a 'r'. Not required to be given.
     * @return array
     */
    public function fetch() {
            if(func_num_args() == 0) {
                $query = 'r'.$this->queryTime;
            } else {
                $query = func_get_arg(0);
            }
        if(preg_match('/r[0-9]/i', $query)) {
            $rQuery = $this->queryCache[substr($query, 0, 1)][substr($query, 1)];
        } else {
            $rQuery = $query;
        }
       
        $fQuery = mysql_fetch_assoc($rQuery);
        if($fQuery === false && trim(mysql_error($this->_dblink)) != '') {
            $errorMessage = "Kon de query niet fetchen.";
            if($this->debug === true) {
                $errorMessage .= "<br />".mysql_errno($this->_dblink).": ".mysql_error($this->_dblink);
            }
           
            throw new Exception($errorMessage, self::GEN_ERROR); //Function stops here.
        }
        return $fQuery; //Else return the fetched rows.
    }
   
    /**
     * numRows, if no parameter is given, use last query.
     * @access public
     * @param string $query contains a query resource or an query ID starting with a 'r'
     * @return int
     */
    public function numRows() {
            if(func_num_args() == 0) {
                $query = 'r'.$this->queryTime;
            } else {
                $query = func_get_arg(0);
            }
        if(preg_match('/r[0-9]/i', $query)) {
            $rQuery = $this->queryCache['r'][substr($query, 1)];
        } else {
            $rQuery = $query;
        }
       
        return mysql_num_rows($rQuery);
    }
	
	/**
     * affectedRows, alias of mysql_affected_rows
     * @access public
     * @return int
     */
	public function affectedRows() {
		$affectedRows =  mysql_affected_rows($this->_dblink);
		
		//Als de laatste query heeft gefaald returnt hij -1. Gewenste waarde is dan 0.
		if($affectedRows === -1) {
			return 0;
		}
		return $affectedRows;
	}
	
	/**
     * insertId, alias of mysql_insert_id
     * @access public
	 * @param mixed $tabel this will give the last auto_increment, if you specefy a tabel, this will be send with. Default: false.
     * @return int
	 * @since version 1.1.2
     */
	public function insertId($tabel=false) {
		if($this->checkConnection()) {
				$idQuery = "SELECT LAST_INSERT_ID() AS last_id";
				if($tabel !== false) {
					$idQuery .= " FROM ".$tabel;
				}
			try {
				$this->query($idQuery);
				$row = $this->fetch();
				return $row['last_id'];
			} catch(Exception $e) {
				throw $e;
			}
		} else {
			throw new Exception('Er is geen verbinding gevonden.', self::CON_ERROR);
		}
	}
}
?>[/code]

Reacties

0
Nog geen reacties.