PHP Data Acces Object
Een data acces object is een class die je database crud acties (create, read, update, delete) makkelijker maakt en database tabellen kan omzetten maar objecten. Let op: tenminste PHP 5.3 nodig Hoe gebruik je dit script? Allereert moet je de database gegevens aanpassen in class db. Zorg dat alle classes worden ingeladen (dmv autoloading of include). Stel je hebt een tabel voorbeeld, dan maak je hiervoor een nieuwe class aan. (Zie voorbeeldtabel.txt). Deze moet altijd class dao extenden, zodat hij de functionaliteit van dao overneemt. Als je de class voorbeeld hebt aan gemaakt met de volgende 2 properties: public $table, public $primary key dan is hij klaar voor gebruik. Probeer eens: $voorbeeld = new voorbeeld(); $voorbeeld->variabel1 = 'Test'; $voorbeeld->create(); $voorbeeld->variabel1 = 'Test2'; $voorbeeld->update(); $voorbeeld->delete(); Met deze 5 regels hebben we 3 queries uitgevoerd, een insert, een update en een delete! Nu hebben we alleen de Read functie nog, werkt ook vrij makkelijk. Bijvoorbeeld: $voorbeeld = new voorbeeld(1); Nu krijg je het voorbeeld object met primarykey 1 terug. Liever een array met meerdere objecten? Dan kan je de getArObj() method gebruiken. Deze method accepteerd 4 parameters. Filter, Filter Manier, Sorteer en Limiet. Op de volgende manier haal je bijvoorbeeld alle voorbeeld objecten op met status aangemeld, aflopend gesorteerd: Als er ngo vragen zijn over het gebruik schroom niet een berichtje te sturen. Indien je bugs/fouten tegenkomt ook graag even doorgeven dan haal ik ze eruit! Hoop dat jullie er iets aan hebben!
<?php
class db {
const HOSTNAME = 'localhost';
const DATABASE = 'hostname';
const PASSWORD = 'password';
const USER = 'user';
private static $instance = false;
public $oMysqli = false;
private $arResult;
public static $queryLog;
public static $log = true;
/**
* Connects to database if there is no connection;
* @param bool $autocommit
* @todo implement autocommit
* @throws Exception
*/
private function __construct( ){
if(!$this->oMysqli){
$this->oMysqli = new mysqli(db::HOSTNAME,db::USER, db::PASSWORD, db::DATABASE);
if(mysqli_connect_errno())
throw new Exception('Cannot connect to database: '.$this->oMysqli->error);
}
}
/**
* Creates instance if there is none
* @return $instance
*/
public function get( ){
if(!self::$instance)
self::$instance = new self();
return self::$instance;
}
/**
* Returns the total query time
*/
public static function getTotalQueryTime(){
$total = 0;
foreach (self::$queryLog as $key => $log){
if($key == 'exectime'){
$total += (int) $log;
}
}
return $total;
}
/**
* Performs a database query
* @throws Exception
*/
public function query( $query ){
$starttime = $this->timeToFloat ();
$this->arResult = $this->oMysqli->query($query);
$endtime = $this->timeToFloat ();
$exectime = ($endtime - $starttime);
if(self::$log){
self::$queryLog[] = array (
'query' => $query,
'exectime' => $exectime,
'affected_rows' => $this->oMysqli->affected_rows,
'last_insert_id' => $this->oMysqli->insert_id );
}
return $this;
}
/**
* Returns the query result
* @param boolean $objects
*/
public function allAssoc( $objects = false ){
$arAssoc = array();
while($result = $this->arResult->fetch_assoc()){
if($objects){
$oRes = new stdClass();
foreach($result as $key => $value)
$oRes->$key = $value;
$arAssoc[] = $oRes;
} else
$arAssoc[] = $result;
}
return $arAssoc;
}
public function __get($name){
return $this->oMysqli->$name;
}
/**
* Magic method to inherit
* all mysqli's functionalities
* @param string $name
* @param string/array $args
*/
public function __call($name , $args ){
if(sizeof($args) == 1)
$args = array_shift($args);
return $this->oMysqli->$name($args);
}
/**
* returns time as a float
*/
private function timeToFloat() {
$time = microtime ();
$time = explode ( " ", $time );
$time = $time [1] + $time [0];
return $time;
}
/**
* List of reserved mysql words
* used by the query builder to put
* backticks around m if they occur
*/
public static $reservedMysqlWords = array (
'accessible',
'add',
'all',
'alter',
'analyze',
'and',
'as',
'asc',
'asensitive',
'before',
'between',
'bigint',
'binary',
'blob',
'both',
'by',
'call',
'cascade',
'case',
'change',
'char',
'character',
'check',
'collate',
'column',
'condition',
'connection',
'constraint',
'continue',
'convert',
'create',
'cross',
'current_date',
'current_time',
'current_timestamp',
'current_user',
'cursor',
'database',
'databases',
'day_hour',
'day_microsecond',
'day_minute',
'day_second',
'dec',
'decimal',
'declare',
'default',
'delayed',
'delete',
'desc',
'describe',
'deterministic',
'distinct',
'distinctrow',
'div',
'double',
'drop',
'dual',
'each',
'else',
'elseif',
'enclosed',
'escaped',
'exists',
'exit',
'explain',
'false',
'fetch',
'float',
'float4',
'float8',
'for',
'force',
'foreign',
'from',
'fulltext',
'goto',
'grant',
'group',
'having',
'high_priority',
'hour_microsecond',
'hour_minute',
'hour_second',
'if',
'ignore',
'in',
'index',
'infile',
'inner',
'inout',
'insensitive',
'insert',
'int',
'int1',
'int2',
'int3',
'int4',
'int8',
'integer',
'interval',
'into',
'is',
'iterate',
'join',
'key',
'keys',
'kill',
'label',
'leading',
'leave',
'left',
'like',
'limit',
'linear',
'lines',
'load',
'localtime',
'localtimestamp',
'lock',
'long',
'longblob',
'longtext',
'loop',
'low_priority',
'master_ssl_verify_server_cert',
'match',
'mediumblob',
'mediumint',
'mediumtext',
'middleint',
'minute_microsecond',
'minute_second',
'mod',
'modifies',
'natural',
'no_write_to_binlog',
'not',
'null',
'number',
'numeric',
'on',
'optimize',
'option',
'optionally',
'or',
'order',
'out',
'outer',
'outfile',
'precision',
'primary',
'procedure',
'purge',
'range',
'read',
'read_only',
'read_write',
'reads',
'real',
'references',
'regexp',
'release',
'rename',
'repeat',
'replace',
'require',
'reserved',
'restrict',
'return',
'revoke',
'right',
'rlike',
'schema',
'schemas',
'second_microsecond',
'select',
'sensitive',
'separator',
'set',
'show',
'smallint',
'spatial',
'specific',
'sql',
'sql_big_result',
'sql_calc_found_rows',
'sql_small_result',
'sqlexception',
'sqlstate',
'sqlwarning',
'ssl',
'starting',
'straight_join',
'table',
'terminated',
'then',
'tinyblob',
'tinyint',
'tinytext',
'to',
'trailing',
'trigger',
'true',
'undo',
'union',
'unique',
'unlock',
'unsigned',
'update',
'upgrade',
'usage',
'use',
'using',
'utc_date',
'utc_time',
'utc_timestamp',
'values',
'varbinary',
'varchar',
'varcharacter',
'varying',
'when',
'where',
'while',
'with',
'write',
'xor',
'year_month',
'zerofill',
'__class__',
'__compiler_halt_offset__',
'__dir__',
'__file__',
'__function__',
'__method__',
'__namespace__',
'abday_1',
'abday_2',
'abday_3',
'abday_4',
'abday_5',
'abday_6',
'abday_7',
'abmon_1',
'abmon_10',
'abmon_11',
'abmon_12',
'abmon_2',
'abmon_3',
'abmon_4',
'abmon_5',
'abmon_6',
'abmon_7',
'abmon_8',
'abmon_9',
'abstract',
'alt_digits',
'am_str',
'array',
'assert_active',
'assert_bail',
'assert_callback',
'assert_quiet_eval',
'assert_warning',
'break',
'case_lower',
'case_upper',
'catch',
'cfunction',
'char_max',
'class',
'clone',
'codeset',
'connection_aborted',
'connection_normal',
'connection_timeout',
'const',
'count_normal',
'count_recursive',
'credits_all',
'credits_docs',
'credits_fullpage',
'credits_general',
'credits_group',
'credits_modules',
'credits_qa',
'credits_sapi',
'crncystr',
'crypt_blowfish',
'crypt_ext_des',
'crypt_md5',
'crypt_salt_length',
'crypt_std_des',
'currency_symbol',
'd_fmt',
'd_t_fmt',
'day_1',
'day_2',
'day_3',
'day_4',
'day_5',
'day_6',
'day_7',
'decimal_point',
'default_include_path',
'die',
'directory_separator',
'do',
'e_all',
'e_compile_error',
'e_compile_warning',
'e_core_error',
'e_core_warning',
'e_deprecated',
'e_error',
'e_notice',
'e_parse',
'e_strict',
'e_user_deprecated',
'e_user_error',
'e_user_notice',
'e_user_warning',
'e_warning',
'echo',
'empty',
'enddeclare',
'endfor',
'endforeach',
'endif',
'endswitch',
'endwhile',
'ent_compat',
'ent_noquotes',
'ent_quotes',
'era',
'era_d_fmt',
'era_d_t_fmt',
'era_t_fmt',
'era_year',
'eval',
'extends',
'extr_if_exists',
'extr_overwrite',
'extr_prefix_all',
'extr_prefix_if_exists',
'extr_prefix_invalid',
'extr_prefix_same',
'extr_skip',
'final',
'foreach',
'frac_digits',
'function',
'global',
'grouping',
'html_entities',
'html_specialchars',
'implements',
'include',
'include_once',
'info_all',
'info_configuration',
'info_credits',
'info_environment',
'info_general',
'info_license',
'info_modules',
'info_variables',
'ini_all',
'ini_perdir',
'ini_system',
'ini_user',
'instanceof',
'int_curr_symbol',
'int_frac_digits',
'interface',
'isset',
'lc_all',
'lc_collate',
'lc_ctype',
'lc_messages',
'lc_monetary',
'lc_numeric',
'lc_time',
'list',
'lock_ex',
'lock_nb',
'lock_sh',
'lock_un',
'log_alert',
'log_auth',
'log_authpriv',
'log_cons',
'log_crit',
'log_cron',
'log_daemon',
'log_debug',
'log_emerg',
'log_err',
'log_info',
'log_kern',
'log_local0',
'log_local1',
'log_local2',
'log_local3',
'log_local4',
'log_local5',
'log_local6',
'log_local7',
'log_lpr',
'log_mail',
'log_ndelay',
'log_news',
'log_notice',
'log_nowait',
'log_odelay',
'log_perror',
'log_pid',
'log_syslog',
'log_user',
'log_uucp',
'log_warning',
'm_1_pi',
'm_2_pi',
'm_2_sqrtpi',
'm_e',
'm_ln10',
'm_ln2',
'm_log10e',
'm_log2e',
'm_pi',
'm_pi_2',
'm_pi_4',
'm_sqrt1_2',
'm_sqrt2',
'mon_1',
'mon_10',
'mon_11',
'mon_12',
'mon_2',
'mon_3',
'mon_4',
'mon_5',
'mon_6',
'mon_7',
'mon_8',
'mon_9',
'mon_decimal_point',
'mon_grouping',
'mon_thousands_sep',
'n_cs_precedes',
'n_sep_by_space',
'n_sign_posn',
'namespace',
'negative_sign',
'new',
'noexpr',
'nostr',
'old_function',
'p_cs_precedes',
'p_sep_by_space',
'p_sign_posn',
'path_separator',
'pathinfo_basename',
'pathinfo_dirname',
'pathinfo_extension',
'pear_extension_dir',
'pear_install_dir',
'php_bindir',
'php_config_file_path',
'php_config_file_scan_dir',
'php_datadir',
'php_debug',
'php_eol',
'php_extension_dir',
'php_extra_version',
'php_int_max',
'php_int_size',
'php_libdir',
'php_localstatedir',
'php_major_version',
'php_maxpathlen',
'php_minor_version',
'php_os',
'php_output_handler_cont',
'php_output_handler_end',
'php_output_handler_start',
'php_prefix',
'php_release_version',
'php_sapi',
'php_shlib_suffix',
'php_sysconfdir',
'php_version',
'php_version_id',
'php_windows_nt_domain_controller',
'php_windows_nt_server',
'php_windows_nt_workstation',
'php_windows_version_build',
'php_windows_version_major',
'php_windows_version_minor',
'php_windows_version_platform',
'php_windows_version_producttype',
'php_windows_version_sp_major',
'php_windows_version_sp_minor',
'php_windows_version_suitemask',
'php_zts',
'pm_str',
'positive_sign',
'print',
'private',
'protected',
'public',
'radixchar',
'require_once',
'seek_cur',
'seek_end',
'seek_set',
'sort_asc',
'sort_desc',
'sort_numeric',
'sort_regular',
'sort_string',
'static',
'str_pad_both',
'str_pad_left',
'str_pad_right',
'switch',
't_fmt',
't_fmt_ampm',
'thousands_sep',
'thousep',
'throw',
'try',
'unset',
'var',
'yesexpr',
'yesstr' )
;
}
?>
<?php
/**
* @package Simple MVC
* @version 1.0
*
* Data Acces Object for PHP.
* Provides simple crud actions
* - Create
* - Read
* - Update
* - Delete()
*
* @todo
* Implement support for multiple primary keys
* Implement support for updating individual fields
* Implement validation before creation
*
* */
abstract class dao {
const WHERE_IN = 2;
const WHERE_NOT = 4;
const ORDER_DESC = 8;
const ORDER_ASC = 16;
public $arAssoc = array ();
public static $arTableFields = array(
);
/**
* Returns an array of objects
*
* @param $filter array
* @param $filterWay array
* @param $orderField array
*/
public static function getArObj($filter = array(), $filterWay = array(), $orderField = array(), $limit = array()) {
$oObj = new static ();
$query = queryBuilder::buildSelect ( $db, $oObj->table, $filter, $filterWay, $orderField , $limit);
$res = $db->query ( $query )->allAssoc ();
return $this->createObjects($res);
}
/**
* Creates a new objects and returns
* the created one
*/
public function create(){
$query = queryBuilder::buildInsert($db, $this);
$db->query($query);
$query2 = queryBuilder::simpleSelect($this->table, $this->primaryKey, $db->insert_id);
$res = $db->query($query2)->allAssoc();
$this->fillObject($res);
}
/**
* Updates an object
*/
public function update(){
$query = queryBuilder::buildUpdate($db, $this);
$db->query($query);
$query2 = queryBuilder::simpleSelect($this->table, $this->primaryKey, $db->insert_id);
$res = $db->query($query2)->allAssoc();
$this->fillObject($res);
}
/**
* Deletes an object
*/
public function delete(){
$query = queryBuilder::buildDelete($db, $this);
$db->query($query);
}
/**
* Creates an array of objects
* @param array $res
* @return array
*/
private function createObjects($res = array()){
$arObj = array();
foreach($res as $row){
$oObj = new static ();
foreach($row as $key=>$value)
$oObj->arAssoc [$key] = $value;
$arObj [] = $oObj;
}
return $arObj;
}
private function fillObject($res = array()){
foreach($res as $row){
foreach($row as $key=>$value)
$this->arAssoc [$key] = $value;
$this->arAssoc ['saved'] = true;
}
}
public function __get($name) {
switch ($name){
case 'saved':
return empty($this->arAssoc['saved']) ? false : true;
default :
return $this->arAssoc [$name];
}
}
public function __construct($primaryKey = null) {
if(! is_null ( $primaryKey )){
$query = queryBuilder::buildSelect ($db, $this->table, array ( $this->primaryKey => $primaryKey ) );
$res = $db->query ( $query )->allAssoc ();
if(! empty ( $res )){
foreach($res as $row){
foreach($row as $key=>$value)
$this->arAssoc [$key] = $value;
$this->arAssoc ['saved'] = true;
}
} else {
$this->arAssoc['saved'] = false;
}
}
$this->getTableFields();
}
private function getTableFields(){
if(empty(self::$arTableFields)){
$db = db::get();
$res = $db->query("SHOW FIELDS FROM ".$this->table)->allAssoc();
if(!empty($res)){
foreach($res as $row){
self::$arTableFields [$row['Field']] = $row['Field'];
}
}
}
}
public function __set($name, $val) {
$this->arAssoc [$name] = $val;
}
}
<?php
/**
* Class queryBuilder
* @uses db
*
*/
class queryBuilder {
/**
* Builds a simple select query
* with a WHERE, IN, NOT IN
* ORDER ASC, DESC and LIMIT
*
*
* @param $table string
* @param $filter array
* @param $filter_way array
* @param $order_field array
* @throws Exception
* @return $string;
* @return &reference $db
*/
public static function buildSelect(&$db, $table, $filter = array(), $filter_way = array(), $order_field = array(), $limit = array()) {
$db = db::get ();
// First part of select
$q = "SELECT * FROM " . $db->real_escape_string ( $table ) . " ";
// Build the where
if(! empty ( $filter )){
$q .= 'WHERE ';
$c = 1;
foreach($filter as $field=>$val){
$q .= $db->real_escape_string ( $field ) . ' ';
if(array_key_exists ( $field, $filter_way )){
switch ($filter_way [$field]){
case dao::WHERE_IN :
if(! is_array ( $filter [$field] ))
throw new Exception ( 'Filter for' . $field . 'expects an array as parameter' );
$q .= 'IN (';
$i = 1;
foreach($filter [$field] as $value){
$q .= "'" . $db->real_escape_string ( $value ) . "'";
$q .= ($i == sizeof ( $filter [$field] ) ? '' : ',');
$i ++;
}
$q .= ') ';
break;
case dao::WHERE_NOT :
if(! is_array ( $filter [$field] ))
throw new Exception ( 'Filter for' . $field . 'expects an array as parameter' );
$q .= 'NOT IN (';
$i = 1;
foreach($filter [$field] as $value){
$q .= "'" . $db->real_escape_string ( $value ) . "'";
$q .= ($i == sizeof ( $filter [$field] ) ? '' : ',');
$i ++;
}
$q .= ') ';
break;
}
}else{
$q .= "= '" . $db->real_escape_string ( $val ) . "' ";
}
if($c != sizeof ( $filter )){
$q .= 'AND ';
}
$c ++;
}
}
if(!empty($order_field)){
switch($order_field[0]){
case dao::ORDER_ASC:
$q .= 'ORDER BY '.key($order_field[0]) . ' ASC';
break;
case dao::ORDER_DESC:
$q .= 'ORDER BY '.key($order_field[0]) . ' DESC';
break;
}
}
return $q;
}
public static function buildInsert(&$db, $oTable ){
$db = db::get();
$q = "INSERT INTO ".$oTable->table." ";
$class = get_class($oTable);
$q .= '(';
$i = 1;
foreach($class::$arTableFields as $key => $value){
if($oTable->primaryKey == $class::$arTableFields[$key])
continue;
if(empty($oTable->arAssoc[$key]))
continue;
if(in_array($key, db::$reservedMysqlWords))
$key = "`".$key."`";
$q .= $key;
$q .= ($i == sizeof($oTable->arAssoc) ? '' : ',');
$i++;
}
$q.= ')';
$q.= ' VALUES (';
$i = 1;
foreach($class::$arTableFields as $key => $value){
if($oTable->primaryKey == $class::$arTableFields[$key])
continue;
if(empty($oTable->arAssoc[$key]))
continue;
$q .= (!empty($oTable->arAssoc[$key]) ? (is_numeric($oTable->arAssoc[$key]) ? $oTable->arAssoc[$key] : "'".$db->real_escape_string($oTable->arAssoc[$key])."'" ) : "' '");
$q .= ($i == sizeof($oTable->arAssoc) ? '' : ',');
$i++;
}
$q.= ') ';
return $q;
}
public static function buildUpdate(&$db, $oTable ){
$db = db::get();
$q = "UPDATE ".$oTable->table." ";
$class = get_class($oTable);
$q .= 'SET ';
$i = 1;
foreach($class::$arTableFields as $key => $value){
if($oTable->primaryKey == $class::$arTableFields[$key])
continue;
if(empty($oTable->arAssoc[$key]))
continue;
if(in_array($key, db::$reservedMysqlWords))
$key = "`".$key."`";
$q .= $key .' = '. (!empty($oTable->arAssoc[$key]) ? (is_numeric($oTable->arAssoc[$key]) ? $oTable->arAssoc[$key] : "'".$db->real_escape_string($oTable->arAssoc[$key])."'" ) : "' '");
$q .= ($i == sizeof($oTable->arAssoc) ? '' : ',');
$i++;
}
$q .= ' WHERE ' . $oTable->primaryKey . ' = ' .$oTable->arAssoc[$oTable->primaryKey];
return $q;
}
public static function buildDelete(&$db, $oTable ){
$db = db::get();
$q = "DELETE FROM ".$oTable->table." ";
$q .= ' WHERE ' . $oTable->primaryKey . ' = ' .$oTable->arAssoc[$oTable->primaryKey];
return $q;
}
public static function simpleSelect($table, $primkey, $val){
return 'SELECT * FROM '.$table.' WHERE '.$primkey . ' = ' . $val ;
}
}
class voorbeeldtabel extends dao {
public $table = 'voorbeeld';
public $primaryKey = 'id';
}
Reacties
0