- Controller directory structure changed.All MVC files grouped by Controller Name.
- Loader class completely changed, some loader functions declared as static
we use loader class like this loader::database(), loader::library(), loader::helper()
- Added DB and DBFactory classes under the database folder.Added most known PDO functions.
- Added Errors.php to library.Added Exceptions and Errors Handler.
- Added Model Class we can use database functions from now on.
- Added Helper function, added helpers directories under the /base and /application directories
- Simple Memory test
Directory Structure: Look at conrollers folder all MVC files grouped by controller names
Writing DB Class:
We use PDO class for DB implementations because of PDO a C extension so it works very fast unlike other DB classes like ADO, MDB2, custom db classes etc..
And PDO support a lot of database drivers:
| Driver name | Supported databases |
|---|---|
| PDO_DBLIB | FreeTDS / Microsoft SQL Server / Sybase |
| PDO_FIREBIRD | Firebird/Interbase 6 |
| PDO_IBM | IBM DB2 |
| PDO_INFORMIX | IBM Informix Dynamic Server |
| PDO_MYSQL | MySQL 3.x/4.x/5.x |
| PDO_OCI | Oracle Call Interface |
| PDO_ODBC | ODBC v3 (IBM DB2, unixODBC and win32 ODBC) |
| PDO_PGSQL | PostgreSQL |
| PDO_SQLITE | SQLite 3 and SQLite 2 |
| PDO_4D | 4D |
First of all we need to extend to PDO Class.Look at this article http://www.phpjack.com/content/extendingpdo
now you can understand me.
Look at my db class.
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC Minimalist Software for PHP 5.2.4 or newer
*
*
* @package Obullo
* @author Obullo.com
* @subpackage Base.database
* @copyright Copyright (c) 2009 Ersin Güvenç.
* @license http://www.opensource.org/licenses/gpl-3.0.html GPL
* @since Version 1.0
* @filesource
*/
/**
* DB Class.
*
* Extending PDO Class.
*
* @package Obullo
* @subpackage Base.database
* @category Database
* @version 0.1
*/
Class DBException extends CommonException {}
// predefined db constants
define('assoc','assoc');
define('obj','obj');
define('bound','bound');
define('col','col');
define('num','num');
// paramater types
define('p_int','int');
define('p_str','str');
define('p_bool','bool');
Class DB_Results
{
// Factory fetch type
static function fetch($type='')
{
switch ($type)
{
case 'assoc':
return PDO::FETCH_ASSOC;
break;
case 'obj':
return PDO::FETCH_OBJ;
break;
//get column names and column nubers togetger
case 'bound':
return PDO::FETCH_BOUND;
break;
//get just column info
case 'col':
return PDO::FETCH_COLUMN;
break;
case 'num':
return PDO::FETCH_NUM;
break;
default:
return PDO::FETCH_ASSOC;
}
} //end fecth.
static function type($type='')
{
switch ($type)
{
// integer
case 'int':
return PDO::PARAM_INT;
break;
// string
case 'str':
return PDO::PARAM_STR;
break;
// boolean
case 'bool':
return PDO::PARAM_BOOL;
break;
default:
return PDO::PARAM_STR;
}
}
} //end class.
Class OB_DB_active_record extends PDO {
/**
*
* @todo code igniter query builder functions
* we will implement it later.
*/
function select(){}
function from(){}
}
Class DB extends OB_DB_active_record
{
/**
* Parent Query pdo query result
*
* @var object
*/
private $PQ = '';
/**
* sql string
*
* @var string
*/
private $sql = '';
/**
* prepare switch
*
* @var boolean
*/
private $prepare = FALSE;
/**
* Prepare options
*
* @var mixed
*/
private $p_opt = array();
function __construct($dsn, $user = NULL, $pass = NULL, $options = NULL)
{
parent::__construct($dsn, $user, $pass, $options);
//throw new DBException('SQLSTATE: test error!');
}
// PDO prepare function.
function prepare($options=array())
{
$this->p_opt = $options;
$this->prepare = TRUE;
}
// Direct or prepared query
function query($sql)
{
if($this->prepare)
{
$this->PQ = parent::prepare($sql,$this->p_opt);
return NULL;
}
$this->PQ = parent::query($sql);
$this->sql = $sql;
return $this;
}
// Execute prepared query
function exec($array=NULL)
{
$this->PQ->execute($array);
// reset prepare variable
$this->prepare = FALSE;
return NULL;
}
// Alias of PDO_Statement::bindVal()
function bval($param,$val,$type='')
{
$this->PQ->bindValue($param,$val,DB_Results::type($type));
}
// Get available drivers on your host
function drivers()
{
foreach(PDO::getAvailableDrivers() as $driver)
{
echo $driver.'<br />';
}
}
// Get results as associative array
function assoc()
{
$assoc = $this->PQ->fetch(PDO::FETCH_ASSOC);
return $assoc;
}
// Get result as object
function obj()
{
$object = $this->PQ->fetch(PDO::FETCH_OBJ);
return $object;
}
// Same as object
function row()
{
$object = $this->PQ->fetch(PDO::FETCH_OBJ);
return $object;
}
// Get all results by assoc, object or what u want
function all($type=NULL)
{
$constant = DB_Results::fetch($type);
$all = $this->PQ->fetchAll($constant);
return $all;
}
// Get column numbers, results in assoc
function num()
{
$num = $this->PQ->fetch(PDO::FETCH_NUM);
return $num;
}
// Number of rows
function num_rows()
{
$num = $this->PQ->rowCount();
return $num;
}
// Get column names and numbers (both)
function both()
{
$both = $this->PQ->fetch(PDO::FETCH_BOTH);
return $both;
}
// CRUD OPERATIONS not implemented YET.
function update(){}
// http://tr.php.net/manual/en/pdostatement.bindvalue.php
function insert(){}
// PDO exec() functionuna bak affected rows a otomatik dönüyor.
function delete(){}
function last_id(){}
} //end class.
We need a DB Factory class because we have a lot of db drivers, we gonna go write it..
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC Framework software for PHP 5.2.4 or newer
*
* @package Obullo
* @author Obullo.com
* @subpackage Base.database
* @copyright Copyright (c) 2009 Ersin Güvenç.
* @license http://www.opensource.org/licenses/gpl-3.0.html GPL
* @since Version 1.0 @alpha
* @filesource
*/
/**
* OB_DBFactory Class
*
* Factory PDO drivers.
*
* @package Obullo
* @subpackage Base.database
* @category Database
* @version 0.1
*/
Class DBFactoryException extends CommonException {}
Class OB_DBFactory
{
public static function Connect()
{
require_once(APP.'config/database'.EXT);
extract($db['default']);
if(empty($dbdriver))
throw new DBFactoryException('Please set a valid DB driver from config database file!');
switch (strtoupper($dbdriver)) {
// FreeTDS / Microsoft SQL Server / Sybase
case 'DBLIB':
$dbh = new DB("dblib:host=$hostname:$dbh_port;dbname=$database;charset=$char_set","$username","$password");
break;
// Firebird/Interbase 6
case 'FIREBIRD':
$dbh = new DB("firebird:dbname=$database","$username", "$password");
break;
// IBM DB2
case 'IBM':
$dbh = new DB("ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=$database;"."HOSTNAME=$hostname;PORT=$dbh_port;PROTOCOL=TCPIP;", "$username", "$password");
break;
// IBM Informix Dynamic Server
case 'INFORMIX':
$dbh = new DB("informix:host=$hostname; service=9800;
database=$database; server=ids_server; protocol=onsoctcp;EnableScrollableCursors=1", "$username", "$password");
break;
// MySQL 3.x/4.x/5.x
case 'MYSQL':
$dbh = new DB("mysql:host=$hostname;dbname=$database","$username","$password",
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES $char_set"));
break;
// Oracle Call Interface
case 'OCI':
$dbh = new DB("oci:dbname=$hostname/$database;charset=$char_set", "$username", "$password");
break;
// ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
case 'ODBC':
$dbh = new DB("odbc:Driver={SQL Native Client};Server=$hostname;Database=$database;Uid=$username;Pwd=$password;");
break;
// PostgreSQL
case 'PGSQL':
$dbh = new DB("pgsql:dbname=$database;user=$username;password=$password;host=$hostname");
break;
// SQLite 3 and SQLite 2
case 'SQLITE':
$dbh = new DB("sqlite:$database");
break;
// 4D
case '4D':
$dbh = new DB("4D:host=$hostname;charset=$char_set","$username","$password");
break;
default:
throw new DBFactoryException('This DB Driver does not support!');
} //end switch.
// We set exception attribute for showing the pdo exceptions errors
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
return $dbh;
} //end function.
} //end class.
Writing Model:
We have a database handle and we can write the model class after that we rewrite the loader class for loader::database() functionality and for assigning libraries to model class.
Model class related with loader class so you can’t understand it exactly without looking at loader class.
Please first download source code and look at loader class same time.
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC Framework software for PHP 5.2.4 or newer
*
* @package Obullo
* @author Obullo.com
* @subpackage Base.libraries
* @copyright Copyright (c) 2009 Ersin Güvenç.
* @license http://www.opensource.org/licenses/gpl-3.0.html GPL
* @since Version 1.0 @alpha
* @filesource
*/
/**
* Model Class.
*
* Main model class.
*
* @package Obullo
* @subpackage Base.libraries
* @category Libraries
* @version 0.1
*/
Class Model {
public $cm; // called model
function __construct()
{
// assign obullo libraries to all called models
$this->_asn_lib();
// this is just called model name
$this->cm = ucfirst(get_class($this));
}
function _asn_lib()
{
$OB = OB_instance();
// declared objects
$dec_ob = array_keys(get_object_vars($OB));
//print_r($dec_ob); open this line you can see the declared objects.
//exit;
//for using to declared objects and variables inside model that we assign before
//we must assign them again inside to model class.
foreach ($dec_ob as $key)
{
if(!isset($this->$key) AND $key != $this->cm AND $key != 'db')
{
$this->$key = $OB->$key;
}
}
} // end func.
}
// END Model Class
Rewriting loader class:
Static functions very important in PHP5 these functions consumes very less memory so i changed loader class completely as static.And we will rewrite the loader class with model and database functions.
Espcecially model(), library(), database() and helpers() functions contains very less code this is for just reduce the server memory consumption model and database functions very important. i worked about 5 days just for writing a good database() function. I think its very special.
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 Minimalist software for PHP 5.2.4 or newer
*
* @package Obullo
* @author Obullo.com
* @subpackage Base.libraries
* @copyright Copyright (c) 2009 Ersin Güvenç.
* @license http://www.opensource.org/licenses/gpl-3.0.html GPL
* @filesource
*/
/**
* Loader Class (Obullo Loader Pattern)
*
* Load obullo library,model and view files
*
* @package Obullo
* @subpackage Base.libraries
* @category Loader
* @version 0.1
* @version 0.2 added model and load db function
* @version 0.3 added static properties for database(),model(),library()
* added is_load_DB variable (Model database load on/off).
*/
Class LoaderException extends CommonException {}
Class loader {
// construct
function __construct(){}
// disable clone
private function __clone(){}
// loader::library('class');
// Load classes from application/libraries
// directory.
public static function library($class)
{
if ($class == '')
return FALSE;
// Instantiate the Super Object.
$OB = OB_instance();
// Lazy Loading
if (class_exists($class) AND isset($OB->$class) AND is_object($OB->$class))
return FALSE;
$PublicVar = strtolower($class);
$Clasname = ucfirst($PublicVar);
$OB->$PublicVar = Register($class);
if($OB->$PublicVar === NULL)
throw new LoaderException('Unable to locate the library file: '.$class);
//from now on we can use own library
//like $this->Myclass->myMethod
// assign all libraries to all models
// support for loader::libray() func. inside from
// public model functions
self::asn_to_models();
}
// loader::view('view_');
// Don't declare this func as static
// because of ability to use $this->var
public function view($view, $data=array(), $string=false)
{
$file = VIEW . DIRECTORY_SEPARATOR . $view . EXT;
if(sizeof($data) > 0)
extract($data, EXTR_SKIP);
//foreach($data as $key=>$value) $$key = $value;
if (file_exists($file)) {
if($string) {
//get file as a srtring.
ob_start();
include($file);
$content = ob_get_contents();
ob_end_clean();
return $content;
} else {
// just include file.
include($file);
}
} else {
throw new LoaderException('Unable to locate the view: '.$file);
}
}
// loader::model('model_');
// Model pattern
public static function model($model)
{
if ($model == '')
return;
$model_name = strtolower($model);
// Controller directory support for model
// if user provide path separator like this loader::model(blog/model_blog)
if (strpos($model_name, '/') == TRUE)
{
$paths = explode('/',$model_name); // path[0] = controller name
$model_name = array_pop($paths);
$path = implode('/',$paths).'/';
// if requested path in same controller
if($path[0] == $GLOBALS['controller'])
{
// Load user called current path like current_controller/model_test
$MODEL_PATH = MODEL.$path.$model_name.EXT;
// if requested path from another controller
} else {
// Load user called another_controller/model_test
$MODEL_PATH = CONTROLLER_PATH.$path.$model_name.EXT;
}
} else {
// Load current controller model
$MODEL_PATH = MODEL.$model_name.EXT;
}
if ( ! file_exists($MODEL_PATH))
throw new LoaderException('Unable to locate the model: '.$model_name);
$OB = OB_instance();
if (isset($OB->$model_name))
throw new LoaderException('This model already loaded before: '.$model_name);
require($MODEL_PATH);
$model = ucfirst($model_name);
$OB->$model_name = new $model(); //Register($class); we don't need it
if($OB->mod_DB)
{
// Lazy Loading. (Prevent to Loading Db Class and Prevent Connect to Db more than one time)
if (class_exists('DB') AND isset($OB->db) AND is_object($OB->db)) {
$OB->$model_name->db = $OB->db;
} else
{
require(BASE.'database/DB'.EXT);
require(BASE.'database/DBFactory'.EXT);
// Connect to PDO.
// Good work.
// we must assign db object for each model
// $OB->db = OB_DBFactory::Connect();
$OB->$model_name->db = OB_DBFactory::Connect();
echo 'DB class initalized one time!';
}
} else {
// if model hasn't got loader::database() word remove db object.
$OB->$model_name->db = NULL;
}
// Reset db load variable loading for other models.
$OB->mod_DB = FALSE;
// assign all loaded libraries inside to current model
// loader::library() support for Model_x { function __construct() { loader::library() }}
$OB->$model_name->_asn_lib();
// store loaded obullo models
$OB->om[] = $model_name;
//print_r($OB->om);
}
// (c) Obullo database load pattern
// loader::database();
// This function just load database class
// When you use it inside from model like this loader::database();
// load_DB var turns to true and it tells to model function this
// model use the database class
// so less code and more functionality
public static function database()
{
$OB = OB_instance();
// For php 5.3.0 and upper versions maybe
// we can use get_called_class() func.
$trace = debug_backtrace();
// if model contains loader::database() func
// load_DB = true else return to false.
$OB->mod_DB = FALSE;
foreach($trace as $t)
{
if(isset($t['object']))
{
if($t['object'] instanceof Model)
$OB->mod_DB = TRUE;
}
}
unset($trace); // reset var, prevent memory consumption
if (class_exists('DB') AND isset($OB->db) AND is_object($OB->db))
return FALSE;
require(BASE.'database/DB'.EXT);
require(BASE.'database/DBFactory'.EXT);
// Extends to PDO.
$OB->db = OB_DBFactory::Connect();
echo 'DB class initalized one time!';
}
// loader::helper();
// We have three helper directory unlike CI
// Base/helpers --> system helpers
// App/helpers --> common application helpers
// Controllers/controller_name/helper_name.php --> controller helpers
public static function helper($helper)
{
// if user provide path separator like this loader::helper(blog/helper_blog)
if (strpos($helper, '/') == TRUE)
{
$paths = explode('/',$helper); // path[0] = controller name
$helper_name = array_pop($paths);
$path = implode('/',$paths).'/';
$helper_name = strtolower('helper_'.str_replace('helper_', '', $helper_name)).EXT;
if(file_exists(CONTROLLER_PATH.$path.$helper_name))
{
include(CONTROLLER_PATH.$path.$helper_name);
} else
{
throw new LoaderException('Unable to locate the helper: '.$helper_name);
}
return;
}
$helper = strtolower('helper_'.str_replace('helper_', '', $helper)).EXT;
// Check system helper
if(file_exists(BASE.'helpers/'.$helper))
{
include(BASE.'helpers/'.$helper);
// Check application helper
} elseif(file_exists(APP.'helpers/'.$helper))
{
include(APP.'helpers/'.$helper);
// Check controller helper
} elseif(file_exists(CONTROLLER.$helper))
{
include(CONTROLLER.$helper);
// If file not exists
} else
{
throw new LoaderException('Unable to locate the helper: '.$helper);
}
}
// loader::dir();
// show directory list of current controller
public static function dir()
{
if(is_readable(CONTROLLER))
{
// opendir function
$handle = opendir(CONTROLLER);
echo '<br />Directory Listing of <b>'.CONTROLLER.'</b><br/>';
// running the while loop
while ($file = readdir($handle))
echo $file.'<br/>';
// close dir
closedir($handle);
} else {
throw new LoaderException($GLOBALS['controller']. ' directory is not readable! ');
}
}
// @ Support for loader::libray() inside from public model functions
// If you declare a library like this loader::library();
// inside from model __construct() it works good this ok
// because loader::model() function already loads it via $OB->$model_name->_asn_lib();
// but when u declare it inside a model function it will not work
// so you will get an error: Undefined property: Model_test::$myclass
// This function prevent the error and assigns all library files to model
private static function asn_to_models()
{
$OB = OB_instance();
if (count($OB->om) == 0)
return;
foreach ($OB->om as $model_name)
$OB->$model_name->_asn_lib();
}
} //end of the class.
Writing Exceptions and Errors (base/libraries/Errors.php)
We have CommonExceptions class for catching our exceptions it defined in libraries/errors.php, this class extends to Exception class
and we don’t need try / catch blocks from index.php because we use set_exception_handler() function this function catch all exception errors automatically like set_error_handler() function.So less code and more functionality.
if( !defined('BASE') ) exit('Access Denied!');
/**
* Obullo Framework (c) 2009.
*
* PHP5 MVC Framework software for PHP 5.2.4 or newer
*
* @package obullo
* @filename base/libraries/Errors.php
* @author obullo.com
* @copyright Ersin Güvenç (c) 2009.
* @since Version 1.0
* @filesource
* @license
*/
/*
* Predefined error constants
* http://usphp.com/manual/en/errorfunc.constants.php
* *
1 E_ERROR
2 E_WARNING
4 E_PARSE
8 E_NOTICE
16 E_CORE_ERROR
32 E_CORE_WARNING
64 E_COMPILE_ERROR
128 E_COMPILE_WARNING
256 E_USER_ERROR
512 E_USER_WARNING
1024 E_USER_NOTICE
2048 E_STRICT
4096 E_RECOVERABLE_ERROR
8192 E_DEPRECATED
16384 E_USER_DEPRECATED
30719 E_ALL
*/
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
Class CommonException extends Exception {}
// Obullo error template for error handling.
function Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, $type)
{
$msg = '<div style=\'width:50%;padding:5px;background-color:#eee;\'>';
$msg.= '<b>[Obullo]['. ucwords(strtolower($type)).']:</b>'.$errstr.'<br />';
$msg.= '<b>File:</b> '.$errfile."<br />";
$msg.= '<b>Line:</b> '.$errline;
$msg.= '</div>';
echo $msg;
}
// Obullo error template for exceptions.
function Obullo_ExceptionHandler($e)
{
$type = 'General';
if(substr($e->getMessage(),0,3) == 'SQL')
$type = 'Database';
$msg = '<div style=\'width:50%;padding:5px;background-color:#eee;\'>';
$msg.= '<b>['. $type .' Error]: </b>'.$e->getMessage().'<br />';
$msg.= '<b>Code:</b> '.$e->getCode()."<br />";
$msg.= '<b>File:</b> '.$e->getFile()."<br />";
$msg.= '<b>Line:</b> '.$e->getLine();
$msg.= '</div>';
echo $msg;
}
/*
* Main error handler function.
*/
function Obullo_ErrorHandler($errno, $errstr, $errfile, $errline)
{
if (($errno & error_reporting()) == 0) return;
switch ($errno)
{
case E_ERROR:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "ERROR");
break;
case E_WARNING:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "WARNING");
break;
case E_PARSE:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "PARSE ERROR");
break;
case E_NOTICE:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "NOTICE");
break;
case E_CORE_ERROR:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "CORE ERROR");
break;
case E_CORE_WARNING:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "CORE WARNING");
break;
case E_COMPILE_ERROR:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "COMPILE ERROR");
break;
case E_USER_ERROR:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "USER FATAL ERROR");
exit();
break;
case E_USER_WARNING:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "USER WARNING");
break;
case E_USER_NOTICE:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "USER NOTICE");
break;
case E_STRICT:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "STRICT ERROR");
break;
case E_RECOVERABLE_ERROR:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "RECOVERABLE ERROR");
break;
case E_DEPRECATED:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "DEPRECATED ERROR");
break;
case E_USER_DEPRECATED:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "USER DEPRECATED ERROR");
break;
case E_ALL:
Obullo_ErrorTemplate($errno, $errstr, $errfile, $errline, "ERROR");
break;
}
/* Don't execute PHP internal error handler */
return true;
}
// Catch all errors !
set_error_handler("Obullo_ErrorHandler");
set_exception_handler('Obullo_ExceptionHandler');
Test model_test.php and we can do some PDO queries !!
look at test/test.php controller and run the index.php file.
Class Model_test extends Model
{
function __construct()
{
// Call the Model constructor
parent::__construct();
// Load database connection
loader::database();
// Using library from model
loader::library('myclass');
}
/**
* Test Function
* @link http://tr.php.net/manual/en/pdostatement.fetch.php
*/
function test_function()
{
echo '<b>Using library from model_test:</b> successful!<br />';
echo '<b>Using database from library:</b> successful!<br />';
$this->myclass->testDB();
/*---------- Prepared Query ----------*/
echo '<br /><b>Prepared Query:</b><br />';
$this->db->prepare(); // tell to db class use pdo prepare
$this->db->query("SELECT * FROM articles WHERE article_id=:id
OR link=:code");
$this->db->bval(':id', $id=1, p_int); //INTEGER
// alias of PDOStatement::bindValue();
$this->db->bval(':code',$code='i-see-dead-people', p_str);
//STRING // alias PDOStatement::bindValue();
//$this->db->param(':colour', $colour, PDO::PARAM_STR);
//alias of pdo::bindParam()
$this->db->exec();
$a = $this->db->all(assoc); // or obj
print_r($a);
$this->db->exec();
$a = $this->db->row(); // or obj
echo '<br />'.$a->title;
/*---------- Prepared Query ----------*/
/*------- Without bindvalue ----------*/
echo '<br /><br /><b>Without bindvalue Query:</b> <br />';
$this->db->prepare(); // tell to db class use pdo prepare
$this->db->query("SELECT * FROM articles WHERE article_id=:id");
$this->db->exec(array(':id'=>1));
$a = $this->db->assoc();
print_r($a).'<br />';
// change the value
$this->db->exec(array(':id'=>2));
$b = $this->db->row();
echo '<br />'.$b->article;
/*------- Without bindvalue ----------*/
/*-- Direct Query and Next Row Example --*/
echo '<br /><br /><b>Direct Query:</b> <br />';
$res = $this->db->query("SELECT * FROM articles");
$a = $res->num_rows();
echo $a.'<br /><br />';
$b = $res->assoc(); // NEXT ROW
print_r($b).'<br />';
$c = $res->obj(); //object // NEXT ROW
echo $c->article.'<br /><br />';
$d = $res->all(assoc); //or obj // NEXT ROW
'<br />'.print_r($d).'<br /><br />';
/*-- Direct Query and Next Row Example --*/
} //end func.
} //end class
and Model test result:
Memory testing:
Now we can do a simple memory test to learn how fast our framework?
Code Igniter memory test (php4, None mysql query just var_dump($this->db)):
Obullo framework memory test (php5 and 4 mysql query,no router class yet) :
Sorry only registered users can download it , Please first Register!
Download Obullo Framework 1.0 @alpha 1 (pdo bug fixed)




sounds nice but error when running
[Obullo][Strict Error]:Declaration of DB::prepare() should be compatible with that of PDO::prepare()
File: C:\wamp\www\obullo\base\database\DB.php
Line: 269
Fatal error: Undefined class constant ‘MYSQL_ATTR_INIT_COMMAND’ in C:\wamp\www\obullo\base\database\DBFactory.php on line 73
thanks your feedback i didn’t test it under the php 5.3.0
so you need do some changes..
1 - open DB.php change prepare function name as _prepare
2 - open test/model_test.php change all $this->prepare lines as $this->_prepare
3 - open DBFactory.php remove completely ‘mysql’ part and add this lines …
$dbh = new DB("mysql:host=$hostname;dbname=$database","$username","$password");$dbh->query('SET NAMES utf8');
now it works also with 5.3.0
thanks for your quick reply, looking forward to playing around with this (btw remember to change your download.zip if you get the chance)
Great work!
I observe some weeks of development of this project.
And I think, that this framework is a grand tool for anyone web-developer…