HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpModerate

A take on DB Abstraction

Submitted by: @import:stackexchange-codereview··
0
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

Solution

Maybe you could extract the common massaging before call_user_func_array in _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.