[b]./test.php[/b]
<?
include ("classes/class.database.php");

$arr = array();
$arr['host'] = "localhost";
$arr['user'] = "test";
$arr['pass'] = "";
$arr['db']   = "test";


$db = new db($arr,TRUE);
$db->set_errorfile("mijn_error_bestand.txt",TRUE);

$db->query("SELECT * FROM ideas");
while ($res = $db->fetch_assoc())
{
  print_r($res)."\n\n\n\n";
}

print_r($db->get_stats());

echo $db->insert_id();

unset($db); //connectie is gesloten
?> 
[b]./classes/class.database.php[/b]
<?
require ("classes/interface.database.php");
require ("classes/class.foutmelding.php");

/********************************************
*                                           *
* Deze class is geschreven door Flance,     *
* ookwel bekend als Jordi Betting. Deze     *
* class mag onbeperkt gebruikt worden,      *
* en ook onbeperkt gepubliceerd worden      *
* zolang deze notitie blijft staan.         *
*                                           *
* Het is niet toegestaan om deze class te   *
* verhandelen.                              *
*                                           *
********************************************/

class db implements databaseInterface
{
  //
  // Variables
  //
  private $rConnect,$bShowError,$sLastQuery,$rLastQuery = NULL;
  private $sErrorFile;
  private $bConnected = FALSE;
  private $iQuery = 0;
  private $iExecStart;
  
  //
  // Constructor - makes connection - Set default data
  //
  public function __construct($aConndata,$bError=FALSE)
  {
    $this->iExecStart = microtime(TRUE);
    $this->bShowError = $bError;
    $max_parameters = 2; //het maximaal mogelijk aantal parameters
    $this->set_errorfile();
    try
    {
      //
      // If the connection data is not an array
      //
      if(!is_array($aConndata))
      {
        //
        // Display error message
        //
        throw new Foutmelding("<i>DBclass</i> : constructor : Eerste parameter, de database connectie data, moet in een array gegeven worden.",3);
      }
      //
      // If the connection data is invalid
      //
      if(count($aConndata) != 4)
      {
        //
        // Display error message
        //
        throw new Foutmelding("<i>DBclass</i> : constructor : Eerste parameter, de database connectie data, heeft een onjuist aantal waarden.",3);
      }
      //
      // If second parameter isn't even a booleaan (noob!)
      //
      if(!is_bool($bError))
      {
        //
        // Display error message
        //
        throw new Foutmelding("<i>DBclass</i> : constructor : Tweede parameter moet boolean zijn..",1);
        $bError=FALSE;
      }

      //
      // If there is an invalid amount of parameters
      //
      if(func_num_args() > $max_parameters)
      {
        throw new Foutmelding("<i>DBclass</i> : constructor : Er zijn te veel parameters meegegeven.",1);
      }
      
      $this->rConnect = @mysql_connect($aConndata['host'],$aConndata['user'],$aConndata['pass']);
      //
      // If connecting failed
      //
      if(!$this->rConnect)
      {
        throw new Foutmelding("<i>DBclass</i> : constructor : Kan geen verbinding met database maken.",3);
      }
      //
      // if selecting database failed
      //
      if(!@mysql_select_db($aConndata['db']))
      {
         throw new Foutmelding("<i>DBclass</i> : constructor : Kan de database niet selecteren, controleer of de gebruiker de juiste permissies heeft.",3);
      }
      $this->bConnected = TRUE;
    }
    catch (Foutmelding $error)
    {
      echo $error; // het geven van de melding ( __toString() ) 
      //
      // If error type is a Warning
      //
      if ( $error->getCode() == 3 )
      {          
        $error->setShowTrace($this->bShowError);
        $error->traceError();
        echo '<b>Het laden is stopgezet wegens een fatale error. Neem contact op met de webmaster en vernoem de bovenstaande error. Bedankt.</b>';
        exit;
        //
        // Stop everything and DIE!
        //
      }
    }
  }

  
  
  //
  // Destructor, will be executed when class is destroyed or at the end of the page automaticly, returns an array with stats
  //
  public function __destruct()
  {
    $this->is_connected();
    @mysql_close($this->rConnect);
    $this->bConnected=FALSE;
    $this->free_result();
    RETURN $this->get_stats();
  }
  
  
  
  //
  // Function to calc the execution time from the beginning of the class till the moment this function is called
  //
  private function calcExecTime()
  {
    RETURN round(microtime(TRUE)-$this->iExecStart,6);
  }
    
  
  //
  // Function gives class stats in an array
  //
  public function get_stats()
  {
      $status = explode("  ", mysql_stat());
      RETURN array($this->iQuery,$this->calcExecTime(),$status);
  }
  
  
  //
  // checks if this thing is connected
  //
  private function is_connected()
  {
    // in princiepe kan deze functie nooit wat doen aangezien de database connectie al gecheckt word bij het connecten
    if ($this->bConnected === FALSE)
    {
      echo "<b>It's not possible to execute mysql functions if there is no connection.</b>";
      exit;
    }
    RETURN NULL;
  }
  
  
  
  public function set_errorfile($sFile="classes/error.database.php",$bCheck=FALSE)
  {
    try
    {
      //
      // If user want to check wheter file exists and is writable
      //
      if($bCheck === TRUE)
      {
        //
        // Do the check
        //
        if(file_exists($sFile) && is_writable($sFile))
        {
          //
          // If it is, save settings and return TRUE
          //
          $this->sErrorFile = $sFile;
          RETURN TRUE;
        }
        else
        {
          //
          // File does not exist or is nog writable - Return FALSE
          //
          throw new Foutmelding("<i>DBclass</i> : set_errorfile() : Het opgegeven bestand bestaat niet of is niet beschrijfbaar",1);
        }
      }
      else
      {
        $this->sErrorFile = $sFile;
        RETURN TRUE;
      }
    }
    catch (Foutmelding $error)
    {
      //
      // GRML! There is an error
      //
      echo $error;
      if ( $error->getCode() == 3 )
      {          
        $error->setShowTrace($this->bShowError);
        $error->traceError();
        echo '<b>Het laden is stopgezet wegens een fatale error. Neem contact op met de webmaster en vernoem de bovenstaande error. Bedankt.</b>';
        exit;
        //
        // Stop everything
        //
      }
    }
  }
  
  
  

  
  //
  // Query - executes a query
  //
  public function query ($sQuery, $iImportant=0)
  {
    $this->is_connected();
    try
    {
      //
      // The possible query error
      //
      $query_error = "<i>DBclass</i> : query() : Query heeft gefaalt. Bekijk het error log voor meer informatie.";
      //
      // If the importancy is not a number
      //
      if (!is_int($iImportant))
      {
        //
        // Do the query
        //
        $this->query($sQuery);
        //
        // Leave a message....bleeb
        //
        throw new Foutmelding("<i>DBclass</i> : query() : Het errorlevel is ongeldig (geen INTEGER).",0);
      }
      //
      // Do query
      //
      $this->sLastQuery = $sQuery;
      $this->rLastQuery = @mysql_query($sQuery);
      //
      // If query failed
      //
      if($this->rLastQuery === FALSE)
      {
        //
        // Shout an error
        //
        throw new Foutmelding($query_error,$iImportant);
      }
      //
      // Everything went oke, return query result and count the query
      //
      $this->iQuery++;
      RETURN $query;
    }
    //
    // If an error was thrown
    //
    catch (Foutmelding $error)
    {
      //
      // Get the error
      //
      if (ereg($query_error,$error))
      {
        //
        // If error is the mysql_error, proceed to the error function
        //
        $this->sql_error("Query mislukt. Zie het logbestand voor meer informatie.");
      }
      else
      {
        //
        // or show the error
        //
        $this->sql_error("Query mislukt. Zie het logbestand voor meer informatie.");
        echo $error;
        $error->setShowTrace(FALSE);
        $error->traceError();        
      }
      //
      // It went wrong, so return that
      //
      RETURN FALSE;
    }
  }
  
  

  
  //
  // Fetch_object()
  //
  public function fetch_object($rQuery='ding')
  {
    //
    // Check if there is a connection
    //
    $this->is_connected();
    //
    // If no resource query is given, use the last executed
    //
    if ($rQuery==='ding')
    {
      $rQuery=$this->rLastQuery;
    }
    /*commentaar omdat als je een error gaat gooien je bij while() een 4e result krijgt als er 3 results zijn.
    try
    {
      //
      // Execute function
      //
      $result = @mysql_fetch_object($rQuery);
      if ($result === FALSE)
      {
        //
        // Damn, it didn't work
        //
        throw new Foutmelding("<i>DBclass<i> : fetch_object() : Het was niet mogelijk om van de query een object te vormen, zie het logbestand voor meer informatie.",1);
      }
      RETURN $result;
    }
    catch(Foutmelding $error)
    {
      //
      // Do the error stuff
      //
      $this->sql_error("Fout bij converteren query naar object");
      echo $error;
    }*/
    RETURN @mysql_fetch_object($rQuery);
  }    
  
  
  
  
  
    
  //
  // Fetch_array()
  //
  public function fetch_array($rQuery='ding',$result_type=MYSQL_BOTH)
  {
    //
    // Is there a line between the class and the database?
    //
    $this->is_connected();
    //jippie, there is
    if ($rQuery==='ding')
    {
      //
      // If no resource query was given, use last executed query.
      //
      $rQuery=$this->rLastQuery;
    }
    /* commentaar omdat als je een error gaat gooien je bij while() een 4e result krijgt als er 3 results zijn.
    try
    {
      $result = @mysql_fetch_array($rQuery,$result_type);
      if ($result === FALSE)
      {
        throw new Foutmelding ("<i>DBclass</i> : fetch_array() / fetch_assoc() / fetch_row() : Not able to convert resource into array",1);
      }
      RETURN $result;
    }
    catch(Foutmelding $error)
    {
      $this->sql_error("Fout bij converteren query naar array");
      echo $error;
    }*/
    RETURN @mysql_fetch_array($rQuery,$result_type);
  }  
  
  
  
  //
  // fetch_assoc() - gives you a beautifull array with required data
  //
  public function fetch_assoc($rQuery='ding')
  {
    RETURN $this->fetch_array($rQuery,MYSQL_ASSOC);
  }  
  
  
  //
  // Fetch row - gives an array with numeric keys
  //
  public function fetch_row($rQuery='ding')
  {
    RETURN $this->fetch_array($rQuery,MYSQL_NUM);
  }
  
  
  
  
  //
  // insert_id - RETURNS LAST INSERTED ID
  //
  public function insert_id()
  {
    $this->is_connected();
    $ii = @mysql_insert_id();
    if (!$ii)
    {
      $this->sql_error("Kon het laatst ingevoegde id nummer niet detecteren");
      RETURN FALSE;
    }
    else
    {
      RETURN $ii;
    }
  }
  
  
  
  //
  // affected_rows
  //
  public function affected_rows()
  {
    $this->is_connected();
    $ar = @affected_rows();
    if(!$ar)
    {
      $this->sql_error("Kon het aantal beinvloedde rijen niet tellen");
      RETURN FALSE;
    }
    else
    {
      RETURN $ar;
    }
  }
  
  
  
  //
  // Counts the number of rows of the last SELECT query
  //
  public function num_rows($rQuery='ding')
  {
    $this->is_connected();
    if ($rQuery='ding')
    {
      $rQuery = $this->$rLastQuery;
    }
    try
    {
      $num = @mysql_num_rows($rQuery);
      if ($num === FALSE)
      {
        throw new Foutmelding ("<i>DBclass</i> : num_rows() : Het aantal rijen konden niet geselecteerd worden");
      }
      RETURN $num;
    }
    catch(Foutmelding $error)
    {
      $this->sql_error("Tellen van rijen uit SELECT mislukt. Zie het logbestand voor meer informatie.",1);
      echo $error; 
      RETURN FALSE;     
    }
  }
  
  
  //
  // Function to free last result
  //
  public function free_result()
  {
    @mysql_free_result();
    $this->rLastQuery = NULL;
    RETURN TRUE;
  }
  
  
    
  
  //
  // Sql_error - shows a nice error and log it to a given file.
  //
  private function sql_error($sMelding="Geen error vermelding gegeven")
  {
    //
    // Code for a new line and a seperation line
    //
    $nl ="
";
    $lijn="|-*************************************************************************-|";
    //
    // Push all possible data in a variable
    //
    $errorlog  = $nl.$lijn.$nl.$nl."General Error information:".$nl.$nl;
    #$errorlog .= "Info about last query: ".mysql_info($this->rConnect).$nl;
    $errorlog .= "MySQL protocol version: ".mysql_get_proto_info().$nl;
    $errorlog .= "MySQL host info: ".mysql_get_host_info().$nl;
    $errorlog .= "MySQL Client info: ".mysql_get_client_info().$nl;
    $errorlog .= $nl;
    $errorlog .= "Info about last query:".$nl;
    $errorlog .= "Given reason: ".$sMelding.$nl;
    $errorlog .= "Query: ".$this->sLastQuery.$nl;
    $errorlog .= "MySQL Error: ".mysql_error().$nl;
    $errorlog .= "MySQL ErrorNumber: ".mysql_errno().$nl;
    $errorlog .= $nl;
    $errorlog .= "MySQL Server stats:".$nl;
    
    $mysql_stat = mysql_stat($this->rConnect);
    $mysql_stat = $status = explode('  ',$mysql_stat);
    foreach($mysql_stat AS $key => $value)
    {
      $errorlog .= "        - ".$value.$nl;
    }
    $errorlog .= $nl;
    $errorlog .= "User information:".$nl;
    $errorlog .= "Ip Adress: ".$_SERVER['REMOTE_ADDR'].$nl;
    $errorlog .= "Remote host: ".$_SERVER['REMOTE_HOST'].$nl;
    $errorlog .= "Referer: ".$_SERVER['HTTP_REFERER'].$nl;
    $errorlog .= "Browser/OS: ".$_SERVER['HTTP_USER_AGENT'].$nl;
    $errorlog .= "Request page: ".$_SERVER['REQUEST_URI'].$nl;
    $errorlog .= "Request Time: ".time().$nl;
    $errorlog .= $nl;
    
    
    try
    {
      //
      // if log file is not writable
      //
      if(!is_writable($this->sErrorFile))
      {
        echo $this->sErrorFile;
        //
        // Damn, show an error
        //
        throw new Foutmelding("<i>DBclass</i> : sql_error() : Error bestand is niet beschrijfbaar, geef deze de juiste permissies.",3);
      }
      //
      // Try to write all information to file
      //
      $fp = fopen($this->sErrorFile, "a");
      $fw = fwrite($fp,$errorlog);
      fclose($fp);
      if($fw===FALSE)
      {
        //
        // Writing didn't work, put error on page
        //
        throw new Foutmelding("<i>DBclass</i> : sql_error() : Error bestand is wel beschrijfbaar maar de error wegschrijven is mislukt.",3);
      }
      RETURN TRUE;
    }
    catch (Foutmelding $error)
    {
      //
      // OOPS, an error occured, print it
      //
      echo $error;
      $error->setShowTrace($this->bShowError);
      $error->traceError();
      RETURN FALSE;
    }
    
  }
}

?> 
[b]./classes/interface.database.php[/b]

<?
interface databaseInterface
{
  public function __construct($aConndata,$bError=FALSE);
  public function __destruct();
  public function get_stats(); 
  public function set_errorfile($sFile="classes/error.database.php",$bCheck=FALSE); 
  public function query($sQuery, $iImportant=0); 
  public function fetch_object($rQuery='ding');
  public function fetch_array($rQuery='ding',$result_type=MYSQL_BOTH);
  public function fetch_row($rQuery='ding');
  public function fetch_assoc($rQuery='ding');
  public function insert_id();
  public function affected_rows();
  public function free_result();
}
?>

[b]./classes/class.foutmelding.php[/b]

<?php
include ("classes/interface.foutmelding.php");

class Foutmelding extends Exception implements foutmeldingInterface
{
  // variabelen initialiseren
  protected  $sFoutMelding; // string | de geformatteerde output error
  private    $bShowTrace;   // bool   | traceErrors aan of uit
  
  const NEWLINE = "<br />\n"; // een handige constante
  
  public function __construct( $message, $code = 0 )
  {
    parent::__construct( $message, $code ); // parent constructor initialiseren

    $this->bShowTrace = false; // standaard geen trace

    switch ( parent::getCode() ) // maak verschillende errorcodes
    {
        case 0:
            $this->sFoutMelding = '<b>Warning</b>';
            break;
        case 1:
            $this->sFoutMelding = '<b>Common error</b>';
            break;
        case 2:
            $this->sFoutMelding = '<b>User error</b>';
            break;
        case 3:
            $this->sFoutMelding = '<b>Fatal error</b>';
            break;
        default:
            $this->sFoutMelding = '<b>Unknown error</b>';
            break;
    }
    
    $aFatalError = array(1,2);
    // als de error fataal is, loggen we m in apache's errorlog
    if ( in_array( parent::getCode(), $aFatalError ) )
    {
      $sLogMessage = $this->message.' in file '.$_SERVER['SCRIPT_NAME'].' on line '.$this->line;
      error_log( $sLogMessage );
      // in de logfile vinden we dit terug:
      // [Sun Feb 06 10:49:52 2005] [error] de opgegeven melding in file /pad/naar/bestand/bestand.php on line xx
    }    
  }
  // __toString() is een vaste (overschrijfbare) string output van de melding
  public function __toString()
  {
    $this->sFoutMelding .= ': '.$this->message.self::NEWLINE;
    return $this->sFoutMelding;
  }
  
  // een set-functie om uitgebreide fouten te laten zien.
  public function setShowTrace( $pBool )
  {
    if ( is_bool( $pBool ) )
      $this->bShowTrace = $pBool;
  }

  // een eigen functie bakken om een debug_backtrace te doen
  public function traceError()
  {
    if ( $this->bShowTrace == true )
    {
      foreach ( $this->getTrace() as $aErrorTrace )
      {
        $aArguments = array();

        $sFormatErrorString  = 'Error thrown in file '.$this->file.' on line '.$this->line.self::NEWLINE.
        self::NEWLINE.
        'Error triggered by <b>function '.$aErrorTrace['function'].'('.implode(', ',$aArguments).');</b>'.self::NEWLINE.
        'In file '.$_SERVER['SCRIPT_NAME'].' on line '.$aErrorTrace['line'].self::NEWLINE;
        echo $sFormatErrorString;
      }
    }
  }
}
?> 

[b]./classes/interface.foutmelding.php[/b]

<?
interface foutmeldingInterface
{
  public function __construct($message, $code = 0);
  public function __toString();
  public function setShowTrace($pBool);
  public function traceError();
}
?>

[b]./classes/error.foutmelding.php[/b]

<?
die ("Protected error log");

/* Let op, hier eindigd de code

Veel plezier ermee.