Location: PHPKode > scripts > Class.DB.php > class-db-php/Class.DB.php
<?php
/**
 * @author Ron Barnett <hide@address.com> 
 * @copyright Ron Barnett <hide@address.com> - distributed under the LGPL
 * @version Release 1.0
 * @package adb
 * @access public a csv based database featuring Read, Write, & Append File methodss
 * together with array based Find, Update, Delete and  Encrypyion methods
 */
// //////////////////////////////////////////////////////////////////////
/**
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
// //////////////////////////////////////////////////////////////////////
class DB {
    // Public vars
    var $dataFile = "data.dat";
    var $dir = "data";
    var $assoc = false ;
    var $cryptKey = false;
    var $db ;
    var $newrows ;
    var $error = false;
    var $lastUpd = "";
    var $written = 0;

    function DB($df = '', $dd = '', $as = false, $ck = false) 
    // Class constructor
    {
        $this->newrows = array();
        $this->db = array();

        if ($df != '') {
            $this->dataFile = $df;
        } 
        if ($dd != '') {
            $this->dir = $df;
        } 
        if ($as !== false) {
            $this->assoc = $as;
        } 
        if ($ck !== false) {
            $this->cryptKey = $ck;
        } 
    } 
    function readDB() 
    // Returns true for success or false for error
    {
        $cf = "$this->dir/$this->dataFile";
        $row = 0;
        $this->lastUpd = @filemtime($cf) or $this->error = "Cannot get timestamp for $cf\n";
        $fp = @fopen($cf, 'rb') ;
        if (is_resource($fp)) {
            while ($data = fgetcsv ($fp, 1024, ",")) {
                if ($this->cryptKey) {
                    for ($n = 0;$n < count($data);$n++) {
                        $this->decrypt($data[$n], $this->cryptKey);
                    } 
                } 
                if (($this->assoc === true) && ($row == 0)) {
                    $num = count ($data);
                    $key = $data;
                    $row = 1;
                } else {
                    $num = count ($data);
                    $tmp = array() ;
                    for ($n = 0 ;$n < $num ; $n++) {
                        if ($this->assoc === true) {
                            $k = strtolower($key[$n]) ;
                        } else {
                            $k = $n;
                        } 
                        $d = $data[$n] ;
                        $tmp[$k] = $d ;
                    } 
                    $this->db[] = $tmp ;
                } 
            } 
            $this->db = array_change_key_case($this->db, CASE_LOWER);
            return @fclose($fp);
        } else { // is resource
            $this->error .= "DB: Cannot open $cf\n" ;
            return false;
        } 
    } 

    function appendDB() 
    // appends data from newrows  array to file
    // Returns true for success or false for error
    {
        if ($this->rowstowrite() == 0) {
            // $this->error = "DB::appendDB : Nothing to append !";
            return false;
        } 
        $tmp = '';
        $this->written = 0;
        for ($n = 0;$n < count($this->newrows);$n++) {
            $tmp .= $this->package($this->newrows[$n]);
            $this->written++ ;
        } 
        $cf = "$this->dir/$this->dataFile";
        $fp = @fopen($cf, 'ab') ;
        if (is_resource($fp)) {
            if (!@fwrite($fp, $tmp)) {
                $this->error = "DB:: appendDB:Cannot Write to $cf\n";
                @fclose($fp);
                return false;
            } 
            $this->newrows = array();
            return @fclose($fp);
        } else {
            $this->error = "DB::appendDB:Cannot Open:$cf";
            return false;
        } 
    } 
    function delete($rownumber, $n = 1) 
    // Returns true for success or false for error
    {
        $key_index = array_keys(array_keys($this->db), $rownumber);
        array_splice($this->db, $key_index[0], 1);
        if (!$this->db) {
            $this->error = "DB::delete: Delete $n  row from  $rownumber  Failed" . $this->rowCount();
            return false;
        } else {
            return true;
        } 
    } 
    function update($rownumber, $aValues) 
    // Returns true for success or false for error
    {
        $aValues = array_change_key_case($aValues, CASE_LOWER);
        while (list($key, $val) = each($aValues)) {
            if (@array_key_exists($key, $this->db[$rownumber])) {
                // echo "found key $key new value=> $val<br />";
                $this->db[$rownumber][$key] = $val;
            } else {
                $this->error = "DB::update: Array key [$key] Not Found in Row [$rownumber]";
                return false;
            } 
        } // while
        return true;
    } 
    function append() 
    // Returns number of lines appended to $this->db
    {
        $n = $this->rowstowrite();
        foreach($this->newrows as $new) {
            $this->db[] = $new;
        } 
        $this->newrows = array();
        return $n;
    } 
    function find($aValues) 
    // returns an array of rownumbers that match the
    // key/value pairs supplied as argument
    // false on failure to find any matches
    // case and space insensitive
    {
        $afound = false;
        $n = 0;
        $target = count($aValues); 
        // echo "Target = $target <pre>";
        // print_r($aValues);
        // echo "</pre>";
        foreach($this->db as $record) {
            // echo $n."<br />";
            $found = 0;
            reset($aValues);
            while (list($key, $val) = each($aValues)) {
                if ((array_key_exists($key, $record)) && (strcasecmp(trim(onespace($record[$key])), trim(onespace($val))) == 0)) {
                    // echo "$key => [$val]	 record[$n] ?= [".$record[$key]."]<br />";
                    $found += 1;
                } else {
                    $found = 0;
                    continue 1;
                } 
            } // while
            if ($found == $target) {
                // echo 'Matched<br />';
                $afound[] = $n;
            } 
            $n++;
        } 
        return $afound;
    } 

    function writeDB($append = false, $force = false)
    { 
        // writes/appends DB  array to  file
        // true on sucsess / false on error
        $cf = "$this->dir/$this->dataFile";
        if (! $force) {
            if ($this->lastUpd != filemtime($cf)) {
                $this->error = "DB::writeDB: $cf Updated by others since last read";
                return false;
            } 
        } 
        $mode = ($append ? 'ab+' : 'wb+');
        if ($this->assoc) {
            $loop = 0;
        } else {
            $loop = 1;
        } 
        $fp = @fopen($cf, $mode);
        $tmp = '';
        if (is_resource($fp)) {
            foreach($this->db as $row) {
                if (($loop == 0) && (!$append)) {
                    $loop = 1;
                    $tmp .= $this->package(array_keys($row));
                    $tmp .= $this->package($row);
                    $this->written++ ;
                } else {
                    $test = implode(' ', $row);
                    if (trim($test) > '') { // row is not null
                        $tmp .= $this->package($row);
                        $this->written++ ;
                    } 
                } 
            } 
            if ($this->written == 0) { // stop it squaking
                $tmp .= " ";
            } 
            if (!@fwrite($fp, $tmp)) {
                $this->error = "DB::writeDB:Cannot Write to $cf (" . $this->written . " Rows )";
                @fclose($fp);
                return false;
            } 
        } else {
            $this->error = "DB::writeDB:Cannot open $cf as file resource";
            return false;
        } 
        return @fclose($fp);
    } 
    function writeable()
    {
        $cf = "$this->dir/$this->dataFile";
        if (!is_writeable($cf)) {
            return false;
        } else {
            return true;
        } 
    } 
    function rowCount()
    { 
        // returns number of rowss in database
        return count($this->db);
    } 
    function rowstowrite()
    { 
        // returns number of rowss in newrows (append) database
        return count ($this->newrows);
    } 
    function package($aData)
    { 
        // packages an array of data into a formatted string
        if ($this->cryptKey) {
            while (list($key, $val) = each($aData)) {
                $this->encrypt($aData[$key], $this->cryptKey);
            } // while
        } 
        return '"' . implode ('","', $aData) . '"' . "\n";
    } 
    function xpackage($aData)
    { 
        // packages an array of data into a formatted string
        return '"' . implode ('","', $aData) . '"' . "\n";
    } 
    // Encryption & Decryption Routines
    function encrypt(&$txt, $key) 
    // encrypt / obfuscate data
    {
        srand((double)microtime() * 1000000);
        $encrypt_key = md5(rand(0, 32000));
        $ctr = 0;
        $tmp = "";
        $tx = $txt;
        for ($i = 0;$i < strlen($tx);$i++) {
            if ($ctr == strlen($encrypt_key))
                $ctr = 0;
            $tmp .= substr($encrypt_key, $ctr, 1) . (substr($tx, $i, 1) ^ substr($encrypt_key, $ctr, 1));
            $ctr++;
        } 
        $txt = base64_encode($this->krypt($tmp, $key));
    } 

    function decrypt(&$txt, $key) 
    // reverse the obfuscation
    {
        $tx = $this->krypt(base64_decode($txt), $key);
        $tmp = "";
        for ($i = 0;$i < strlen($tx);$i++) {
            $md5 = substr($tx, $i, 1);
            $i++;
            $tmp .= (substr($tx, $i, 1) ^ $md5);
        } 
        $txt = $tmp;
    } 

    function krypt($txt, $crypt_key) 
    // Inner function for encryption/decryption
    {
        $md5 = md5($crypt_key);
        $ctr = 0;
        $tmp = "";
        for ($i = 0;$i < strlen($txt);$i++) {
            if ($ctr == strlen($md5)) $ctr = 0;
            $tmp .= substr($txt, $i, 1) ^ substr($md5, $ctr, 1);
            $ctr++;
        } 
        return $tmp;
    } 
} 
function onespace($a) 
// reduces multiple spaces to a single space character
{
    $b = str_replace('  ', ' ', $a);
    return $b;
} 

class DBe extends DB {
    var $unpacked = '';
    function unpackDB()
    {
        if (($this->readDB() === true) && (count($this->db) >= 1)) {
            // echo $this->cryptKey?$this->cryptKey:'';
            foreach ($this->db as $row) {
                $this->unpacked .= $this->xpackage ($row);
            } 
        } 
        return $this->unpacked;
    } 
} 

?>
Return current item: Class.DB.php