patternphpModerate
A take on DB Abstraction
Viewed 0 times
takeabstractionstackoverflow
Problem
It's a little bit more code but I wanted to show the full class. I highlight the points I'd like input after the source.
I've cut comments since they where not in English and translated the important ones.
The class is inspired by PearDb (too old) and Zend_DB (to cluttered / unfinished at the time) and is used in a inhouse application. I know it's not ideal to write your own database handler (I'd go so far to say it's pretty pointless).
```
oStatement = $oDb->prepare($sQuery);
$this->sQuery = $sQuery;
if($this->oStatement === false) {
switch($oDb->errno) {
case 1054:
throw new DbNoSuchFieldException($oDb->error, $oDb->errno);
case 1146:
throw new DbNoSuchTableException($oDb->error, $oDb->errno);
default:
throw new DbException(
"Prepared Statement could not be created: ".
$oDb->error." (".$oDb->errno."). Query was: '$sQuery'",
$oDb->errno
);
}
}
}
/**#@+
*
* @param mixed $mParams,...
*/
public function execute() {
$this->_execute(func_get_args());
$this->_done();
}
/**
* @return null|bool|int|string|float
*/
public function getOne() {
$this->_execute(func_get_args());
$this->_fetchRow();
if(isset($this->aResultSet[0][$this->aFieldnames[0]])) {
return $this->aResultSet[0][$this->aFieldnames[0]];
}
return null;
}
/**
* @return array
*/
public function getCol() {
$this->_execute(func_get_args());
$this->_fetchAll();
$sIndex = $this->aFieldnames[0];
$aReturn = array();
foreach($this->aResultSet as $aResultRow) {
$aReturn[] = $aResultRow[$sIndex];
}
return $aReturn;
}
/**
* @return array
*/
publi
I've cut comments since they where not in English and translated the important ones.
The class is inspired by PearDb (too old) and Zend_DB (to cluttered / unfinished at the time) and is used in a inhouse application. I know it's not ideal to write your own database handler (I'd go so far to say it's pretty pointless).
```
oStatement = $oDb->prepare($sQuery);
$this->sQuery = $sQuery;
if($this->oStatement === false) {
switch($oDb->errno) {
case 1054:
throw new DbNoSuchFieldException($oDb->error, $oDb->errno);
case 1146:
throw new DbNoSuchTableException($oDb->error, $oDb->errno);
default:
throw new DbException(
"Prepared Statement could not be created: ".
$oDb->error." (".$oDb->errno."). Query was: '$sQuery'",
$oDb->errno
);
}
}
}
/**#@+
*
* @param mixed $mParams,...
*/
public function execute() {
$this->_execute(func_get_args());
$this->_done();
}
/**
* @return null|bool|int|string|float
*/
public function getOne() {
$this->_execute(func_get_args());
$this->_fetchRow();
if(isset($this->aResultSet[0][$this->aFieldnames[0]])) {
return $this->aResultSet[0][$this->aFieldnames[0]];
}
return null;
}
/**
* @return array
*/
public function getCol() {
$this->_execute(func_get_args());
$this->_fetchAll();
$sIndex = $this->aFieldnames[0];
$aReturn = array();
foreach($this->aResultSet as $aResultRow) {
$aReturn[] = $aResultRow[$sIndex];
}
return $aReturn;
}
/**
* @return array
*/
publi
Solution
Maybe you could extract the common massaging before call_user_func_array in
Probably not worth it, good enough as-is.
This is one of the most readable bits of PHP I've ever seen, should be even better with the original comments.
_execute and _prepareFetch into a helper?private function _execute($aArgs) {
/// [...]
$aRefArgs = array();
foreach(array_keys($aArgs) as $mIndex) {
$aRefArgs[$mIndex] = &$aArgs[$mIndex];
}
array_unshift($aRefArgs, str_repeat("s", $iArgs));
// Needs References
call_user_func_array(array($this->oStatement, "bind_param"), $aRefArgs);
///-^ This part...
/// [...]
private function _prepareFetch() {
/// [...]
$this->aResultRow = array_fill(0, count($this->aFieldnames), null);
// Ugly but 'bind_result' forces you to pass references
$aRefs = array();
foreach ($this->aResultRow as $iIndex => &$rmValue) {
$aRefs[$iIndex] = &$rmValue;
}
call_user_func_array(array($this->oStatement, "bind_result"), $this->aResultRow);
///-^ ... matches this one loosely.
/// [...]Probably not worth it, good enough as-is.
This is one of the most readable bits of PHP I've ever seen, should be even better with the original comments.
Code Snippets
private function _execute($aArgs) {
/// [...]
$aRefArgs = array();
foreach(array_keys($aArgs) as $mIndex) {
$aRefArgs[$mIndex] = &$aArgs[$mIndex];
}
array_unshift($aRefArgs, str_repeat("s", $iArgs));
// Needs References
call_user_func_array(array($this->oStatement, "bind_param"), $aRefArgs);
///-^ This part...
/// [...]
private function _prepareFetch() {
/// [...]
$this->aResultRow = array_fill(0, count($this->aFieldnames), null);
// Ugly but 'bind_result' forces you to pass references
$aRefs = array();
foreach ($this->aResultRow as $iIndex => &$rmValue) {
$aRefs[$iIndex] = &$rmValue;
}
call_user_func_array(array($this->oStatement, "bind_result"), $this->aResultRow);
///-^ ... matches this one loosely.
/// [...]Context
StackExchange Code Review Q#146, answer score: 15
Revisions (0)
No revisions yet.