[PHP]ist meine Mysql/Sicherheits-klasse sicher/sinnvoll?

Matthiasnet

Well-known member
ID: 116869
L
14 August 2006
271
7
Hallo,

beschäftige mich in letzter Zeit intensiv mit OOP für PHP5 und Versuche Routinearbeiten in Klassen unterzubringen.
Zum einem habe ich eine MySql-Klasse erstellt und eine Sicherheitsklasse, die mich hoffentlich vor "den meisten" (alle kann man ja leider nie sagen) Hackerangriffe schützt....
Da ich mein Projekt und auch zukünftieg um diese Klasse erweitern möchte, würde ich mich sehr freuen,wenn sich jemand die Zeit nehmen könnte und mal drüberschauen könnte, ob diese so sinnvoll geschrieben ist.
Desweiteren würde ich mich auch über ein Statement freuen, ob ich mit der Sicherheitsklasse mehr oder weniger "sicher" programmieren kann.

Wie gesagt freue ich mich über jede Anwtort, ob Kritik/Verbesserungsvorschläg etc. ;)

Hier ein Online-Besipiel, dass ich erstellt habe: https://www.lachenundspass.de/labor/sicherheitstest.php

Aktualisiert:
config.php
PHP:
<?
define("HOST","localhost");
define("USERNAME","x");
define("DBPW","x");
define("DBNAME","x");

define("ERROR_CODE","2");
// 1 = show errors
// 2 = log errors
?>


mysql.class.php
PHP:
<?
class ExcMySql_critical_error extends Exception 
{
     public function __construct($Message) {
         parent::__construct($Message);
     }
}

class ExcMySql_non_critical_error extends Exception 
{
     public function __construct($Message) {
         parent::__construct($Message);
     }
}

class mysql 
{
	public $sql;	
	
	   public function __construct() {
	   	 if (!$this->db = mysql_connect (HOST, USERNAME, DBPW)) 
			throw new ExcMySql_critical_error("DB-Verbindung konnte nicht aufgebaut werden!");
		  
		 if (!mysql_select_db(DBNAME, $this->db))
			throw new ExcMySql_critical_error("DB konnte nicht ausgewählt werden!");
   	   }
		
	   public function select($column,$table,$where=false,$order=false,$limit=false) {
	    // $column wird in string umgewandelt und jedes Element in `` eingeschlossen
	    $column = mysql::converting($column,1);
	   	$sqlab = "
		SELECT $column
		FROM `$table`";
		 if ($where != false) {$sqlab.=" WHERE $where";};
		 if ($order != false) {$sqlab.= " ORDER BY $order";};
		 if ($limit != false) {$sqlab.= " LIMIT $limit";};
		 if (!$sql = mysql_query($sqlab)) {
			throw new ExcMySql_critical_error("MySql-Abfrage konnte nicht verarbeitet werden!");
		 }
		 else {
		 	//Letzte SQL-Abfrage wird gespeichert	
			$this->sql = $sql; 
		 }
		 if (mysql_num_rows($sql) == 0)
		 	throw new ExcMySql_non_critical_error("Die Ergebnissmenge der MySql-Abfrage ist 0!");
		return $sql;  
		}
		
	   public function insert($table,$column,$values) {
	   	$sqlab = "
		INSERT INTO `$table`
		($column)
		VALUES
		($values)";
		 if (!mysql_query($sqlab)) 
		 	throw new ExcMySql_critical_error("Bei der Eintragung der Daten in die Mysql-DB ist ein Fehler aufgetreten!");
		 if (mysql_affected_rows($this->db) == 0) 
		 	throw new ExcMySql_non_critical_error("Es wurde kein Datensatz in die Mysql-DB hinzugefügt!"); 
	    }
	    
	   public function update($table,$values,$where=false) {
	   	$sqlab = "UPDATE `$table` SET $values";
		if ($where != false) {$sqlab.=" WHERE $where";};
		 if (!mysql_query($sqlab)) 
			 throw new ExcMySql_critical_error("Datensatz konnte nicht geändert werden!"); 
		 if (mysql_affected_rows($this->db) == 0) 
			 throw new ExcMySql_non_critical_error("Es wurde kein Datensatz in der Mysql-DB verändert!");
	    }
		
	   public function delete($table, $where) {
	   	$sqlab = "DELETE FROM `$table` WHERE $where";
		 if (!mysql_query($sqlab)) 
    		throw new ExcMySql_critical_error("Datensatz konnte in der Mysql-DB nicht gelöscht werden!"); 
		 if (mysql_affected_rows($this->db) == 0) 
    		throw new ExcMySql_non_critical_error("Es wurde kein Datensatz in der Mysql-DB gelöscht!");
	   }
	   
	   
	   private function converting($column,$type) {
	   	 //Überprüfung ob $column = string
	   	 if (is_string($column)) {
		 	//Aus String wird Array erstellt und trim wird angewand   
   		 	$column = array_map('trim', explode(',', $column)); 
 		 } 
		 
		 if ($type == 1){
		 	 //Arrayelemente werden um `` ergänzt
			 for ($i=0;$i < count($column); $i++) {
				$column[$i]="`".$column[$i]."`"; 
		 	 }
			 //Array wird in String umgewandelt
			 $column=implode(",",$column);
		 } 
		return $column;
	   }
	   
	   public function fetch_object($column,$table,$where=false,$order=false,$limit=false) {
	    //Select-Anweißung durchführen
		$sql = mysql::select($column,$table,$where,$order,$limit);
		//$column wird in Array umgewandelt
		$column = mysql::converting($column,2);
		//Anzahl der Felder
		$numfields = mysql_num_fields($sql);
		//Die Namen der Felder werden im Array gespeichert
		for($i=0;$i < $numfields;$i++){
         	 $fieldname[$i] = mysql_field_name($sql, $i);
	    }
		//Überprüfung ob Datensätze ausgewählt wurden
		if (mysql_num_rows($sql) > 0) { //Wäre es an dieser Stelle möglich mit der evt. geworfenen Exception der select Methode zu arbeiten?
			//Arrayelemente werden mit Inhalt aus der DB belegt
			while ($row = mysql_fetch_object($sql)) {
				for($i=0;$i < $numfields;$i++){
           			$array[$fieldname[$i]]=$row->$fieldname[$i];
				}
			}
		}
		//Arrayelemente werden initialisiert wenn mysql_num_rows($sql) == 0
		else {
			for($i=0;$i < $numfields;$i++){
				$array[$fieldname[$i]]=false;
			}
		}
	   return $array;
	   }
	   
	   
	   public function fetch_array($column,$table,$where=false,$order=false,$limit=false) {
	    //Select-Anweißung durchführen
		$sql = mysql::select ($column,$table,$where,$order,$limit);
		//$column wird in Array umgewandelt
		$column = mysql::converting($column,2);
		//Anzahl der Felder
		$numfields = mysql_num_fields($sql);
		//Die Namen der Felder werden im Array gespeichert
		for($i=0;$i < $numfields;$i++){
         	$fieldname[$i] = mysql_field_name($sql, $i);
	    }
		//Überprüfung ob Datensätze ausgewählt wurden
		if (mysql_num_rows($sql) > 0) { //gleiches wie oben?
			//Arrays werden mit Inhalt aus der DB belegt
			while($row = mysql_fetch_array($sql)) {
				for ($i=0; $i < $numfields;$i++){
					$array[$fieldname[$i]][]=$row[$fieldname[$i]];
				}
			}
		}
		//Arrays werden initialisiert wenn mysql_num_rows($sql) == 0
		else {
			for ($i=0; $i < $numfields;$i++){
				$array[$fieldname[$i]][]=$row[$fieldname[$i]];
			}
		}
		return $array;
	   }
	   
	   public function __destruct() {
	    //Schließen der Mysql-Verbindung
		if (!mysql_close($this->db)) 
    		throw new ExcMySql("MySql-Verbindung konnte nicht geschlossen werden!");
	   }		
}




class security 
{

	public function secure_text($string) {
	$string = trim($string);    
	$string = htmlentities($string, ENT_QUOTES);    
	return($string);
	}
	
	public function mysql_secure($string,$type=1) {
	$string = security::secure_text($string);
	if ($type==1) {
		if(get_magic_quotes_gpc()) {
		  $string = stripslashes($string);    
		}
	}
	if (!$string = mysql_real_escape_string($string))  
		throw new ExcMySql_critical_error("Daten konnten nicht für die MySql-DB validiert werden"); 
    return $string;
  	}
	
	public function output($string) {
		html_entity_decode($string);
	return $string;
	}	
}



//Objekt erzeugen

$security=new security;




function user_meldung()
{
	echo "HI; Leider ist nen Fehler aufgetretetn";
}

function formular()
{
	echo "<br><br>hier da fehler eingeben";
}


function error($typ, $meldung, $datei, $zeile, $kontext)
{
   //Array, um Fehlernummern im Klartext darstellen zu koennen
   $klartext=array(1=>"Error",2=>"Warning",8=>"Notice",
   256=>"User Error",512=>"User Warning",
   1024=>"User Notice");
   ini_set("track_errors",1); // Tracking einschalten
   
   // enthaelt alle Variablen/Arrays, die spaeter
   // nicht ausgegeben werden sollen
   
   $exclude=array("HTTP_POST_VARS","_POST","_GET",
   "HTTP_COOKIE_VARS","_COOKIE","HTTP_SERVER_VARS",
   "_SERVER","HTTP_ENV_VARS","_ENV","HTTP_POST_FILES",
   "HTTP_GET_VARS","_FILES","_REQUEST");
   
   // Alle Variablen abarbeiten
   foreach ($exclude as $key) {
      // Variable loeschen
      unset ($kontext[$key]);
   }
   ob_start();
   print_r($kontext);
   $kontext_inhalte=ob_get_contents();
   ob_end_clean();

   $beschr = "<table style = \"border:2px solid #FF3300\" border=\"1px\" width=\"700px\">
	 <tr>
	  <td width=\"100px\"><b>Datum:</b> </td>
	  <td>". date("d-m-Y H:i:s") ."</td>
	 </tr>
	 <tr>
	  <td><b>Fehlertyp:</b> </td>
	  <td>$klartext[$typ] </td>
	 </tr>
	 <tr>
	  <td valign=\"top\"><b>Meldung:</b> </td>
	  <td>$meldung</td>
	 </tr>
	 <tr>
	  <td><b>Datei:</b> </td>
	  <td>$datei</td>
	 </tr>
	 <tr>
	  <td><b>Zeile:</b> </td>
	  <td>$zeile</td>
	 </tr>
	 <tr>
	  <td valign=\"top\"><b>Variablen:</b> </td>
	  <td><pre>$kontext_inhalte </pre></td>
	 </tr>
	</table>";
	
	if (ERROR_CODE == 1) {
		echo "$beschr<br><br>";
	}
	else {
	
		@$fp=fopen("errorsd.php","r");
		
		if ($fp == true) {
			fputs($fp,$beschr);
		}
		else {
			try {
				if (!$db = mysql_connect (HOST, USERNAME, DBPW))
					throw new ExcMySql_critical_error("DB-Verbindung konnte nicht aufgebaut werden!");
				if (!mysql_select_db(DBNAME, $db))
					throw new ExcMySql_critical_error("DB konnte nicht ausgewählt werden!");
				$sqlab = "INSERT INTO `error_log`
						(error)
						VALUES
						('$beschr')";
				 if (!mysql_query($sqlab)) 
					throw new ExcMySql_critical_error("Bei der Eintragung der Daten in die Mysql-DB ist ein Fehler aufgetreten!");
				 if (mysql_affected_rows($db) == 0) 
					throw new ExcMySql_critical_error("Es wurde kein Datensatz in die Mysql-DB hinzugefügt!"); 
			}
			catch(ExcMySql_critical_error $fehler) {
				echo $fehler->getMessage();
				$empf="mgora@online.de";
	
				$subject="Fehler auf xxx.tld";
				$subject=urlencode($subject);
				$subject=str_replace("%","=",$subject);
				$subject=str_replace("+"," ",$subject);
				$subject="=?ISO-8859?1?Q?$subject?=";
				
				$body="<html>
				<head></head>
				<body>
				Hallo,<br><br>
				
				da ein aufgetredener Fehler weder in der log-Datei noch in der DB gespeichert werden konnte, wird Ihnen dieser nun per Mail zugesant:<br><br>
				
				$beschr
				</body>
				</html>";
				
				$hdrs="From: Fehlermanagement xx.tld <webmaster@prov.tld>\n";
				$hdrs.="MIME-Version: 1.0\n";
				$hdrs.="Content-Type: text/html; charset=\"iso-8859?1\"\n";
				$hdrs.="Content-Transfer-Encoding: 8bit\n";
				$hdrs.="X-Priority: 1\n";
				$hdrs.="Priority: Urgent\n";
				$hdrs.="Importance: High\n";
				$hdrs.="X-MSMail-Priority: High";
				//$hdrs.= "$body\r\n";
				
				if (mail($empf,$subject,$body,$hdrs) == false) {
					$formular=true;
				}
			}
		}  
	   switch ($typ) {
		   case E_WARNING:
		   case E_USER_WARNING:
		   case E_USER_ERROR:
				user_meldung();
				if ($formular === true) {
					formular();
				}
				die;
		}
	 }

}
?>

sicherheitstest.php
PHP:
<?
error_reporting(E_ALL);
include("config.php");
if (ERROR_CODE == 1){
	ini_set('display_errors', 1); 
	ini_set("log_errors",0); 
}
else {
	ini_set('display_errors', 0); 
	ini_set("log_errors",1); 
	ini_set("error_log","(/www/htdocs/w0074849/labor/error.php"); 
}
include("mysql.class.php");
set_error_handler("error");


function exception_handler($fehler) {
	  trigger_error($fehler->getMessage());   
}
set_exception_handler('exception_handler');



try {
	$mysql=new mysql;
	$eingabe2=false;
	$sql=false;
	if (isset($_POST['eingabe1'])): $eingabe1 = $security->mysql_secure($_POST['eingabe1']); else: $eingabe1=false; endif;
	if (isset($_POST['eingabe2'])): $eingabe2 = $security->mysql_secure($_POST['eingabe2']); else: $eingabe2=false; endif;
	if (isset($_POST['senden'])): $senden=true; else: $senden=false; endif;

	if ($senden === true && !empty($eingabe1) && !empty($eingabe2)) {	
	
		try {
			$mysql->insert("test","ein1, ein2","'$eingabe1' ,'$eingabe2'");
		}
		catch(ExcMySql_non_critical_error $fehler) {
			echo $fehler->getMessage();
		}
		
		try {
			$ausgabe = $mysql->fetch_object("ein1, ein2","test",false,"'id' Desc");
		}
		catch (ExcMySql_non_critical_error $fehler) {
			echo $fehler->getMessage();
		}
		
		echo 'Ausgabe der Eingaben aus der DB:<br>1:'.$security->output($ausgabe['ein1']).'<br>2:'.$security->output($ausgabe['ein2']);
		mysql_free_result($mysql->sql);
	}
	?>
	<form action="" enctype="multipart/form-data" method="POST">
	Eingabe1: <input name="eingabe1" size="30" value="<? echo stripslashes($eingabe1); ?>"><br>
	Eingabe2: <input name="eingabe2" size="30"  value="<? echo stripslashes ($eingabe2); ?>"><br><br>
	<input name="senden" type="submit" value="Abschicken">
	</form>
	<br><br>
	Ausgabe aller daten:
	<table style="width:400px;" border="1px" cellspacing="0" bordercolorlight="#000000" bordercolor="#000000" bordercolordark="#000000">
	<?
	try {
		$ausgabe_alle = $mysql->fetch_array("ein1, ein2","test",false,"`id` DESC");
	}
	catch (ExcMySql_non_critical_error $fehler) {
		echo $fehler->getMessage();
	}
	echo count($ausgabe_alle['ein1']);
	for($i=0;$i < count($ausgabe_alle['ein1']); $i++) {	
		echo "
		<tr>
		  <td valign=\"top\">".wordwrap($ausgabe_alle['ein1'][$i], 20, "\n", 1)."</td>
		  <td valign=\"top\">".wordwrap($ausgabe_alle['ein2'][$i], 20, "\n", 1)."</td>
		 </tr>
		 ";
	}
	mysql_free_result($mysql->sql);
}
catch(ExcMySql_critical_error $fehler) {
	trigger_error($fehler->getMessage(), E_USER_WARNING);
}
?>
</table>

Grüße

Matthiasnet
 
Zuletzt bearbeitet:
ein zwei sachen sind mir aufgefallen und da würd ich gern wissen wieso das du das so umgesetzt hast.

1. wieso speicherst du die db-zugangsdaten innerhalb der klasse als variable ab?

es gibt ein triviales szenario indem dann alle daten offen liegen. man kann zb durch unglückliche benutzung diese variablen abfragen. du verwendest "var", nicht wie in php5 "private" oder "public". wobei hier "privat" relevant ist.

selbst wenn du "private" nutzen würdest, könnte man die variablen noch immer auslesen.

darum würde *ich* zumindest das dbpw niemals als klassen-variable speichern.

2. warum greifst du auf globale variablen und damit ausserhalb der klasse auf daten zu? ($GLOBALS[...)

da muss man wohl nicht mehr viel zu sagen, damit brichst du die struktur der klasse.

3. du definierst im methoden-aufbau eine $message variable, nutzt diese aber nur an einer stell, obwohl der selbe text an einer weiteren vorhandne ist.

4. deine klasse nutzt viele echo-aufrufe und ermöglicht dadurch kein transparentes nutzen. die anwendung selbst, hat hier bisher nur wenige möglichkeiten akzeptabel zu reagieren.

5. wenn der inhalt einer variable den ausdruck "$$column[$i].." zur variable "column" generiert, gehen evt daten verloren. das hab ich zwar nicht weiter geprüft, ist aber in einer klasse unschön.

6. du prüft globale einstellungen und arbeitest danach entsprechend weiter. würde man diese methode nutzen, ohne das eben diese daten durch ein formular entgegen genommen wurden, werden daten verfälscht.
"if(get_magic_quotes_gpc()) {.. $string = stripslashes($string); "

7. FALSE ist nicht false:
define("FALSE", true); echo "'".FALSE."'";
typegenau prüft man mit === oder !==
 
Zuletzt bearbeitet:
Erstmal danke für deine Antwort;)

1. wieso speicherst du die db-zugangsdaten innerhalb der klasse als variable ab?

es gibt ein triviales szenario indem dann alle daten offen liegen. man kann zb durch unglückliche benutzung diese variablen abfragen. du verwendest "var", nicht wie in php5 "private" oder "public". wobei hier "privat" relevant ist.

selbst wenn du "private" nutzen würdest, könnte man die variablen noch immer auslesen.

darum würde *ich* zumindest das dbpw niemals als klassen-variable speichern.
ok danke, werde diese dann außerhalb der Klasse definieren.
2. warum greifst du auf globale variablen und damit ausserhalb der klasse auf daten zu? ($GLOBALS[...)

da muss man wohl nicht mehr viel zu sagen, damit brichst du die struktur der klasse.
Ich möchte diese Daten aus der Klasse vielmehr global machen (mit dem Schlüsselwort global hat es nicht geklappt), damit ich diese genau so verwenden kann, wie ich es in meinem Beispiel gemacht habe.... fällt dir zufällig eine alternative dazu ein?
3. du definierst im methoden-aufbau eine $message variable, nutzt diese aber nur an einer stell, obwohl der selbe text an einer weiteren vorhandne ist.
Versteh ich nicht ganz...gebe ich keinen Wert an, erscheint der vorgegebene Text bei erfolgreichem hinzufügen. Gebe ich einen Text ein wie "Anmeldung erfolgreich gespeichert"/"Sie sind nun im Newsletter eingetragen" erscheint dieser bei erfolgreichem ausführen auch...was stimmt den daran nicht?
4. deine klasse nutzt viele echo-aufrufe und ermöglicht dadurch kein transparentes nutzen. die anwendung selbst, hat hier bisher nur wenige möglichkeiten akzeptabel zu reagieren.
sorry versteh damit leider auch nicht ganz was du meinst...was sollte ich den da verändern bzw. wo liegt da der Fehler?
5. wenn der inhalt einer variable den ausdruck "$$column[$i].." zur variable "column" generiert, gehen evt daten verloren. das hab ich zwar nicht weiter geprüft, ist aber in einer klasse unschön.
Sollte die Variable column heißen wird der Wert unter der Variable $column gespeichert...hat ja für den weiteren Verlauf keine Auswirkungen.
Du sagst es wär unschön...wie macht man das ganez den schön?;)
6. du prüft globale einstellungen und arbeitest danach entsprechend weiter. würde man diese methode nutzen, ohne das eben diese daten durch ein formular entgegen genommen wurden, werden daten verfälscht.
"if(get_magic_quotes_gpc()) {.. $string = stripslashes($string); "
Danke, werde diese Methode dementsprechen ausbauen...
7. FALSE ist nicht false:
define("FALSE", true); echo "'".FALSE."'";
typegenau prüft man mit === oder !==
jap nochmals danke, werd ich ändern

Grüße

Matthias
 
Ich möchte diese Daten aus der Klasse vielmehr global machen (mit dem Schlüsselwort global hat es nicht geklappt), damit ich diese genau so verwenden kann, wie ich es in meinem Beispiel gemacht habe.... fällt dir zufällig eine alternative dazu ein?
Das ist aber nicht besonders gut, weil du mit dieser Vorgehensweise beliebige Variablen außerhalb zerstören kannst.
PHP:
$test=1;
$mysql->fetch_object("test","foo");
echo $test; // 4711, weils in der DB steht
Besser du lieferst eine Datenstruktur mit dem DB-Resultat zurück, die die Anwendung dann verarbeiten kann, anstatt in der Anwendung wild rumzufummeln.
siehe hierzu auch den nächsten Punkt:
sorry versteh damit leider auch nicht ganz was du meinst...was sollte ich den da verändern bzw. wo liegt da der Fehler?
Eine Klasse soll unabhängig sein.
Stell dir vor, ich benutze deine Klasse in meinem Projekt und füge mit $mysql->insert(...); was in die DB ein. Find ich klasse, wenn ich irgendwelche Stats in meine Tabellen einfüg, dass der Besucher dann die Meldung "Daten eingefügt" auf dem Bildschirm lesen darf :ugly: :evil:

Du solltest so vorgehen, dass du per Rückgabewert dem Benutzer deiner Funktion mitteilst, ob/welchen Fehler es gab. Wie der Benutzer damit umgeht, ist dir egal. Er kann den Fehler ignorieren oder vielleicht eine Fehlermeldung ausgeben. Mit Sicherheit will er aber keine Ausgabe von dir erhalten.

Immer bedenken: Die Klasse sollte jeder für alles mögliche benutzen können, ohne sie ändern zu müssen.
 
@ passwörter
solche daten sollten nur für die maximale notwendige zeit gespeichert werden, danach sofort löschen. in allen anderen fällen, kann es immer eine möglichkeit geben diese werte auszulesen.

@ $message
fehler von mir, es sind doch zwei verschiedene ausgaben

@ $GLOBAL, $$variable
methoden und funktionen geben daten zurück. anstat irgendetwas ausserhalb der klasse zu überschreiben, solltest du deine ergebnisse einfach mit "return $variable;" zurück geben.

@ echo / errorcode / exception
gib fehlercodes zurück oder wirf exceptions. die klasse ist ein tool, ein programmteil der transparent sein muss. gibt er daten in den sichtbaren bereich, ist das nicht mehr kontrollierbar.
 
also was mir gerade auffällt sind die die()s das sollte auf keinen Fall rein, baue return-codes oder status-codes dafür ein

Edit: ups, scar, hat es ja schon gesagt
 
Also sollte man generell alle Fehler nicht ausgeben und nur zurückgeben?
Also korrigiert mich bitte falls ich falsch liege, aber eine Klasse sollte doch eigentlich Arbeitsschritte sparen....ob ich die Fehlerausgabe nacher im Code schreib (der ja eigentlich immer gleich bleibt) oder direckt von der Methode ausführen (was ja auch nicht so arbeitsaufwendig ist) lasse, ist doch eigentlich egal oder sehe ich das falsch?
Diese Meldungen kann man auch "abschalten", indem ich dem Parameter "" übergebe.
Letztendlich benutze eigentlich nur ich die Klasse...aber sollte jemand mal mit meiner Klasse arbeiten müssen, würde mir jetzt spontan einfallen, dass ich eine abgeleitete Klasse (mit extends) schaffe, die eben nur von mir benutzt wird und um diese "Ausgaben" erweitert wird....oder wie seht ihr das?

@theHacker: Hab nun das Wort exceptions nachgeschlagen und ist anscheinend sowas ähnliches was ich oben angesprochen habe, les mir dann mal morgen passende Lektüre dazu durch ;)


bzg. $GLOBAL, $$variable:
Also bzg. dem Überschreiben von Werten hab ich der Methode extra den Parameter $prefix gegeben, um evt. doppelnennungen zu vermeiden... ich versuch es dann einfach mal mit der Rückgabe eines mehrdimensionalen Arrays.

Mach mich dann morgen mal ans überarbeiten dran;)
 
Also sollte man generell alle Fehler nicht ausgeben und nur zurückgeben?
Also korrigiert mich bitte falls ich falsch liege, aber eine Klasse sollte doch eigentlich Arbeitsschritte sparen....ob ich die Fehlerausgabe nacher im Code schreib (der ja eigentlich immer gleich bleibt) oder direckt von der Methode ausführen (was ja auch nicht so arbeitsaufwendig ist) lasse, ist doch eigentlich egal oder sehe ich das falsch?[...]

Nunja, in einer Produktivumgebung möchtest du die Ausgaben ja schon allein aus Sicherheitsgründen nicht öffentlich machen.
Außerdem ist über eine gemeinsame Fehlerklasse eben gewährleistet, dass bestimmte Fehler nur über diese gehen. Somit lässt sich alles leichter erweitern, es gibt keinen redundanten Code ... kurzum, du bist OOP wieder ein Stück näher.

Bei mir persönlich sieht es z.B. so aus, dass ich in meiner Config nur "display_hard_errors" auf true bzw. false setzen muss, dass mir bestimmte Fehler angezeigt werden oder nicht.
 
Also sollte man generell alle Fehler nicht ausgeben und nur zurückgeben?
Also korrigiert mich bitte falls ich falsch liege, aber eine Klasse sollte doch eigentlich Arbeitsschritte sparen....ob ich die Fehlerausgabe nacher im Code schreib (der ja eigentlich immer gleich bleibt) oder direckt von der Methode ausführen (was ja auch nicht so arbeitsaufwendig ist) lasse, ist doch eigentlich egal oder sehe ich das falsch?
Diese Meldungen kann man auch "abschalten", indem ich dem Parameter "" übergebe.
Letztendlich benutze eigentlich nur ich die Klasse...aber sollte jemand mal mit meiner Klasse arbeiten müssen, würde mir jetzt spontan einfallen, dass ich eine abgeleitete Klasse (mit extends) schaffe, die eben nur von mir benutzt wird und um diese "Ausgaben" erweitert wird....oder wie seht ihr das?

Richtig das sollte sie auch. Ein Objekt ist nicht unbedingt dazu bestimmt dass es was zurückgeben soll. Es ist immer was es ist und was es kann. Hier sind viele unterwegs die ein Objekt in ihrer Form missbrauchen und daraus ehe nur einen Source Code schreiben. Dabei nützt man Objekte gerade um selbstständigkeiten abzugrenzen. Ein Objekt weleches dazu geschrieben wurde nur von Source gefüttert und ständig abgefragt zu werden ist in meinen Augen das Objekt nicht wert. Auf der VHS Schulung sagt man dazu "unrentabel." Im eigentlichen Sinne bedeutet es (beschreiben, erzeugen, füttern und freuen). Es gibt aber auch Objekte die dazu modelliert werden, um ständig abgefragt und gefüttert zu werden. Man sollte es daher mit vorsicht genießen. DB Abfragen sind daher nicht unbedingt sehr sinvoll über eine Art Objekt gesteuert zu werden. Das einzige warum es dann wieder den Sinn wiederwirft ist die Tatsache, dass du auf die Abfragen reagieren kannst. Deshalb würde ich das auch zu diesen Ausnahmen hinzufügen. Ich selbst mache es auch über OOP.

Ich kann micht vor 2 Jahren an meine Arbeit erinnern, als wir für Daimler Chrysler Software entwickelt haben. Unser vorgänger hat ein abartig geiles Objekt geschrieben. Da konntest du oben den Namen des Kunden oder sowas wie das Geburtsdatum eingeben, und schwups hast du alle Daten geliefert bekommen. Alles mit einer Wunderbaren Ansicht, und alle Infos im Überblick. Wenn man sich so 10 Kunden herausgesucht hat, ist alles fein gegangen. Aber wenn man sich 1000 Kunden von Millionen geben lassen hat, sind alle Rechner zusammengebrochen.

Was ich dir damit sagen wollte. Mach dein Objekt auf das nötigste, was wirklich gebraucht wird. Deine Arbeit finde ich garnicht mal so schlecht *Lob*!

Wenn du ein Objekt mit einem Auto vergleichst. Drückt man auf die Hupe, dan hupt es. Drückt man auf den Lichtschalter, dann geht das Licht an oder aus. Dreht man an der Zündung, dann Springt der Motor an.

Dein Ansatz ist also vollkommen richrtig. Lass dir das nicht ausreden.

Du drückst ja auch nicht auf den Lichtschalter um später zu fragen ob das Licht geht. Wenn du dich vergewissern willst, muss es das Objekt können. Dh. wenn was schief geht sollte das Objekt reagieren. Nicht der Sourcecode. Wenn die Reaktion dein die() sein soll, dann ist dem nichts auszusetzen. Dazu ist dann eben dein Objekt bestimmt. (das was es kann)

Ein Objekt ist ja nicht da um ständig zu kontrollieren ob es seine Arbeit verrichtet hat. Es ist da um seine Arbeit zu erledigen, verwalten und seine Eigenschaften auszunutzen .
 
Zuletzt bearbeitet:
Ich kann micht vor 2 Jahren an meine Arbeit erinnern, als wir für Daimler Chrysler Software entwickelt haben. Unser vorgänger hat ein abartig geiles Objekt geschrieben. Da konntest du oben den Namen des Kunden oder sowas wie das Geburtsdatum eingeben, und schwups hast du alle Daten geliefert bekommen. Alles mit einer Wunderbaren Ansicht, und alle Infos im Überblick. Wenn man sich so 10 Kunden herausgesucht hat, ist alles fein gegangen. Aber wenn man sich 1000 Kunden von Millionen geben lassen hat, sind alle Rechner zusammengebrochen.

Diese Technick nennt sich Object-Relational-Mapping (ORM) und höchst wahrscheinlich liegt darin die Zukunft der Datenbank gestützen Abfragen, denn diese sind unabhängig von den darunter liegenden RDBMS-Architekturen, warum das eine ORM da so nen Mist konzipiert hat weiß ich nicht, aber ich kann dir versichern, dass im Normalfall so gut wie null Overhead erzeugt wird, es wird nur ein Objekt erzeugt in dem das Ergebnis gespeichert wird und daraufhin ein Iterator implementiert um durch die Daten zu iterieren, das sind vllt 50 Byte mehr Aufwand, aber Anwendungen werden viel viel einfacher zu entwickeln, Propel/url] im PHP-Umfeld und [url=https://de.wikipedia.org/wiki/Hibernate_%28Framework%29[/url] im Java-Umfeld sind wohl die bekanntesten Frameworks und werden definitiv mittlerweile immer den normalen SQL gestützten Abfragen vorgezogen, im Java-Umfeld ist es sogar so, dass JDBC aus diesem Grund kaum noch verwendet wird.

Edit: zu dem Thema direkte Ausgabe der Fehler:
mit einer Datenbankklasse möchte man sich ja Arbeit ersparen und auch die Klasse immer und überall wiederverwenden können, warum man dann direkt keine Ausgaben in der Klasse macht ist ganz simpel:
Wenn die Datenbank-Verbindung fehlchlägt ist ein die() mit das unschänste, was man tun kann, das beste ist, eine Weiterleitung auf eine statische HTML-Seite zu machen, die sagt, dass es gerade Probleme gibt, da könntest du schön den Error-Code abfangen und fertig.
Und Datenbankfehler, ja die gibt man auch nicht einfach aus, du gibst zurück, dass es Fehler gab und deine Apllikation kann ja verschieden darauf reagieren, vllt möchte sie einen mysql-rollback machen, oder gar dir eine email schreiben, oder was auch immer, es kann ja jeder query eine versch. fehlerbehandlung haben, und genau deshalb gibst du error-codes zurück und nicht einfach die fehler ausgeben.
wenn du genau wiesst, was du anhand irgendwelcher fehlerlevel machen willst, dann kannst du ja noch eine wrapper-klasse draum basteln, die dir fehlercodes auch wieder auswertet und ggf. reagiert, aber einfach eine ausgabe von fehlermeldungen oder ein die() rein, das macht man nicht, das entspricht nicht dem konzept von OOP, dass Programmteile unabhängig voneinander sind, denn wenn ein Programmteil das ganze Script beendet, ist es ja nicht mehr unabhängig ;)
 
Zuletzt bearbeitet:
Nun ja. Das kommt drauf an. Wie du schon sagst. Allerdings halte ich es persönlich nicht sehr sinnvoll, deine Applikation weiterhin auszuführen die auf eine Datenbank angewiesen ist, und einem Fehler unterläuft.

In meinen Augen macht das bist dato einen Sinn, wo das Script einen geringen Umfang annimmt. Bei Projekten die so groß sind, bei denen der Einsatz von Subervsion unverzichtbar ist, weil einfach zu viele Programmierer an den gleichen Scripts arbeiten, macht es weniger Sinn, den Code weiterlaufen zu lassen.

Du kannst dir in solchen Fällen nie erdenken was dein nächster sich bei der Sache gedacht hat. Insofern ist es besser Fehler zu stoppen, anstatt sie durch den Code selbst zu debuggen. Das hält natürlich nicht ab vorher eine E-Mail abzusenden oder der gleichen.

Die Realität der Entwicklung sollte davon ausgehen, dass Projekte den Umfang eines enormen annehmen können. Ein gutes Beispiel ist Google. Es gibt Bücher, wo man nachlesen kann wie diese Giganten gewachsen sind. Damit ist Google, Ebay und der gleichen gemeint. Google zu Beispiel hat auf ein Cluster gesetzt. Dahinter sie setzten simple Scripte ein. Auf jedem Rechner läuft dort das gleiche. Fällt ein Rechner aus, so übernimmt ein anderer Rechner seinen Dienst.

Ich weiß nicht, ob dir das schonmal passiert ist. (Mir aber schon). Tritt bei Google ein Fehler auf, wird das Script restlos abgebrochen, und es erscheint eine Fehlermeldung.

Es geht hier ums rentable. Rentabel ist, wenn der nächste sich nicht um deine Probleme kümmern muss. Deswegen sollte man Fehler, die unerwartet auftreten abbrechen.

Deshalb arbeitet Google nicht mit spezieller Software oder Datenbanken oder Entwickelt gesonderte Codes. Weil der Wartungsaufwand einfach viel zu Kostenintensiv ist. Ein Server kostet um die 30 Euro. Wenn es den verhagelt wird eben eine neuer vom Master bestückt. 30 Euro im Monat im Vergleich der Wartungskosten eines Programmierers, machen Weltden aus. Der Programmierer müsste sich erst an den Code setzen, die Stelle suchen. Dann Debugen, und dann müsste er den Fehler auf all den hundertden Servern im Cluster ausbessern.

Überlege mal die Auswirkung auf Returncodes. Deshalb habe ich mich darauf bezogen. Ich weiß wie die Realität aussieht. Die Kunden wollen einfache Sachen, die ihnen später keine Instandskosten bereiten.

Es ist für ein Unternehmen billiger eine Datenbank zu replizieren, als Fachkräfte zu beschäftigen, die immer auf dem neusten Stand sind.

Man denkt sich immer, dass hinter E-Bay oder Google, Yahoo höchste Spezialisten stecken würden. Dort stecken in Wahrheit die besten Spekulanten. (Es ist wirklich so). Arbeitskraft wird in Supportkräfte verschwendet, wenn man es aus dem Auge des Kunden sieht.

Mal völlig weg vom Kunden. Auch macht man es sich Privat leichter. Wenn Projekte wachsen, und man schnell erkennen kann wo der Fehler ist. Mit Technologie wird (nicht immer) aber meist nur Geld oder Zeit verschwendet.

In jedem Fall sind für ein Programm Returncodes besser!!! Weil ein Programm in sich funtkionieren muss. Da hast du vollkommen recht. Aber du darfst das nicht auf Web beziehen.

Wenn es dich interessiert. Ich habe schon so viel gesehen. Du wirst garnicht glauben mit welchen geschlamperten Trix Giganten arbeiten um einfach Geld einzusparen. Wenn man dort auftritt und alles neu schreiben will, dann wirst du vor die Tür gesetzt. Das würde Millionen kosten. Da ist also kein Vergleich. Immer nur das nötige und das wichtige, dass es funktioniert.

Soviel Leistung wie möglich und so wenig Aufwand und Wartungskosten wie umsetzbar.
 
Zuletzt bearbeitet:
Matthiasnet schrieb:
Also sollte man generell alle Fehler nicht ausgeben und nur zurückgeben?
Also korrigiert mich bitte falls ich falsch liege, aber eine Klasse sollte doch eigentlich Arbeitsschritte sparen....ob ich die Fehlerausgabe nacher im Code schreib (der ja eigentlich immer gleich bleibt) oder direckt von der Methode ausführen (was ja auch nicht so arbeitsaufwendig ist) lasse, ist doch eigentlich egal oder sehe ich das falsch?

Die fehler direkt in der Klasse ausgeben ist schlecht. Damit verbaust du dir ein großen vorteil von OOP, die wiederverwendbarkeit von Code. Klar kann man ihn auch so weiterverwenden... aber das kommt dann Copy&Paste gleich. Z.B. was passiert wenn du mal für ein anderes Projekt andere Fehler ausgeben willst... du wirst an der stelle einfach die Klasse anpassen für das neue Projekt. Jedoch hast du damit praktisch zwei unterschiedliche Klassen. Also wenn du mal was grundlegendes ändern willst müsstest du jetzt zwei Klassen anpassen.
Um solche Probleme zu umgehen kommst du besser wenn du die Fehlerbehandlung auslagerst/umgestalltest. Das heißt nicht das du jetzt für jeden Query eine eigene Fehlerbehandlung machen musst... zb könntest du anstatt das die() auch eine exception auslösen. Exceptions kann man abfangen und drauf reagieren, oder man fängt sie nicht ab und hat ein ähnlichen effekt wie die(). Geht natürlich auch anders... aber das wäre jetzt zuviel.

Ansonsten noch ein kleiner tipp... deiner Klasse fehlt eine Query Funktion. SQL kann auch ein wenig komplexer sein als wie du mit deiner select und insert Funktion abdeckst.

Deshalb arbeitet Google nicht mit spezieller Software oder Datenbanken oder Entwickelt gesonderte Codes. Weil der Wartungsaufwand einfach viel zu Kostenintensiv ist. Ein Server kostet um die 30 Euro. Wenn es den verhagelt wird eben eine neuer vom Master bestückt. 30 Euro im Monat im Vergleich der Wartungskosten eines Programmierers, machen Weltden aus. Der Programmierer müsste sich erst an den Code setzen, die Stelle suchen. Dann Debugen, und dann müsste er den Fehler auf all den hundertden Servern im Cluster ausbessern.

Ja neh... Google arbeitet bestimmt mit Access oder war das nicht doch Datamat für 5€ von Databecker?! Zu was braucht man auch spezielle Software für ein Datenbanksystem was auf über 450.000 Rechnern verteilt läuft und wer weiß wieviele Anfragen in der Sekunde bewältigt :ugly: Und ja Server für 30€? Und hä? Und nochmals hä?
 
Bedanke mich für die vielen, hilfreichen Antworten.
Habe mir nun auch vorgenohmen eine vernünftige exception zu schreiben.
Da ich jedoch in Urlaub fahre, würde ich dieses Thema nach dem Urlaub gerne nochmal aufgreifen....

Ansonsten noch ein kleiner tipp... deiner Klasse fehlt eine Query Funktion. SQL kann auch ein wenig komplexer sein als wie du mit deiner select und insert Funktion abdeckst.
Deshalb steht im Quellcode auch //... , da die anderen so ähnlich aufgebaut sind und ich es nicht "zu voll" machen wollte;)

Grüße

Matthiasnet
 
Ja neh... Google arbeitet bestimmt mit Access oder war das nicht doch Datamat für 5€ von Databecker?! Zu was braucht man auch spezielle Software für ein Datenbanksystem was auf über 450.000 Rechnern verteilt läuft und wer weiß wieviele Anfragen in der Sekunde bewältigt Und ja Server für 30€? Und hä? Und nochmals hä?

Wenn du magst, dann sende mir per PN deine E-Mail Adresse, und ich Scanne dir das aus meinen Buch ein. Dort steht das ganz klipp und klar. Ich habe das Buch Erfolg im Internet Statemants der Giganten erworben und glesen. Es ist wirklich so.

Bie den Serverkosten ist es so. Wenn du als kleiner Mann oder Klein Unternehmen Server anmietest bezahlst du den vollen Preis. Wenn ein Gigant wie Google den vollen Preis bezahlen müsste würde er zum nächsten wechseln. Ganz einfach. Da ist die Machtschraube ganz anders verteilt.

Ich kann dir gerne einen Vereis geben, wo du Teile dieses Buches öffentlich nachlesen kannst, was öffentlich im Web ist. Es ist eine Tatsache.

Hier: https://www.pcwelt.de/index.cfm?pid=1639&pk=15938

geht über mehrere Seiten. Gerade die Giganten haben nur 1 oder 2 Fachkräfte. Sicher haben die Mega Giganten noch ein paar mehr. Der Rest sind Praktikaten, gehilfen und sonstiges.

In jeder Fachlektüre von Dokotren die Bereits Erfolg hatten, oder haben, steht ausdrücklich drin, dass darauf verzichtet werden soll.

Weist du wie Yahoo sein Rechenzentrum hatte? Die haben Mainborads auf Bretter geschraubt um Kosten zu sparen. Das ist blanke Tatsache, wozu sich das Unternehmen äußerte. Nix mit Mega Überwachungszentrale oder der gleichen. Googeln macht schlauer!

Du glaubst nicht, dass ein Unternehmen hunderte Euro por Rechner für spezielle Lösungen ausgibt, wenn es nicht dazu bedarf, und die Kräfte für tausende von Euro schult. In der Programmierung JA. Im IT Nein! Die meisten Vortbildungen die ein IT Angestellter in Anspruch nimmt, sind durch Beihlifen (Im Rahmen des Steuer Absetzbaren) des Unternehmens.

Schau nur auf You Tube. Meinst du die Seite wurde von hunderten von Kräften hochgezogen? Und dennoch ist für einen Giganten Preis an Google verkauft worden. Und wie speziell ist nun das YouTube Script? Da steckt garantiert nicht die Welt drin. Denn darauf ist es im IT nie angekommen.

Second Life hat auch zum Beispiel eine sehr Simple Lösung für ihre Online virtuelles 2tes Leben. Eigentlich im Vergleich mit modern hängt SecondLife weit Welten hinterher. Aber wer ist nun erfolgreich geworden?

Ein Unternehmen wird in Technik investieren, wenn es die Rentabilität stiegert. Vorher nicht. Und eine MYSQL Datenbank kostet nicht. Eine spezielle kann Welten kosten, und das pro Rechner. Es ist billger 20K Rechner dran zu hängen. Erst wenn sich ein Preisvorteil durch Technologie ergibt, wird dort herein investiert.

Siehst doch selbst was sich durchsetzt auch bei Unternehmen:

Apache, Mysql, PHP (gegenüber ASP), OPEN Geschichten, Suberversion, Eclipse bzw. PHP Eclipse. Ausnahmen gibt es aber was kosten diese Sachen? Und das ist der Grund! Sie sind kostenlos. Das würde jeder von euch auch machen.

Übrigens, wenn du meinen Verweis oben (geht über mehrere Seite und unten ist eine Navi) liest, dann weisst du, dass gerade die Unternehmen die hart investiert haben alle Pleite gegangen sind.

Hier nur mal hervorgehoben:

Dr. Dicks These lautet: "Es gibt keine prinzipielle Krise bei den Internet-Firmen. Probleme bekommen nur solche Unternehmen, die ihren Erfolg ausschließlich auf technologische Spielereien gründen und nicht den Kunden mit seinen Bedürfnissen im Fokus ihrer Bemühungen haben". Er betont den Stellenwert der Wirtschaftlichkeit: "Internet-Startups, denen die wirtschaftlichen Beweggründe fehlen, müssen scheitern - da können weder Java, noch XML, noch aufwändig animierte Websites, noch ein perfekt funktionierender Linux-Server etwas retten".

Im IT verdient man mit Simplen Dingen Geld, die jeder Idiot verstehen kann, kaum was kosten, und mit billigstem Aufwand zu warten sind. Dann kannst du reich werden. Mit Lösungen, auf die man neue Kräfte schulen oder gar einstellen muss, die dafür 0,03 Sekunden schneller laufen, und der Wartungsaufwand enorm ist, wirst du nur Pleite gehen. Ich konnte das auch nicht raffen. Aber es ist so. Sicher gibt es ausnahmen wie Banken, die auf ein Sicherheitsaufwand angewiesen sind. In diesem Fall geht auf Grund der Sicherheit und der Kundensicherheit (Zufriedenheit) die Investition vor. Aber auch nur, um die eigene Sicherheit zu gewähren und den Kunden zufrieden zu stellen.

Auch hier im Losesektor ist das so. Eurofriend ist auch mit einem VMS groß geworden. Wenn man mit einem Ista vergleicht, ist das Ista halt besser, dafür bietet das VMS mit den ganzen Addons viel mehr Möglichkeiten. Und mit diesem Script kennt sich fast jeder aus.

Warum nur hat Google seine Seite nicht aufwändig gestylet? Aber selbst Internetanfänger kommen mit dem schlichten aus.

Klamm ist auch auf Grund der bezahlten Startseite bzw. den Losen erfolgreich geworden. Und das gefällt mir an ihm. Da ist auch nicht Mega viel ins Design / Technologie geflossen. Und die Seite ist erfolgreich.

Nur wer sinnlos drauf zu scriptet und meint sich jedes Future einproggen zu müssen macht sich selbst Arbeit das später zu warten. Zeit ist eben auch Geld. Später kann sowas Überlebenswichtig werden. Natürlich dürfen Komplexe Dinge her, die aber den Aufwand künftig senken. Das ist das 1*1 der IT wie es täglich parktiziert wird.

Es sind Dinge wie Cronjobs die sich durchsetzen. Ich kann mich an Klamms Aussage erinnern. Wo er mal schrieb, dass seine Seite fast alles automatisch bewältitg. Daran sieht man, dass er das 1*1 verstanden hat.
 
Zuletzt bearbeitet:
was will man da noch sagen, so viel worte und kein inhalt :roll:

@Matthiasnet.. viel erfolg bei deiner helferklasse und spass im urlaub..
 
Danke, nur nach einem Monat Urlaub kommt so ein Code nacher einem schon fast Fremd vor :biggrin:

Dann wollen wir aml an das Gespräch von vor 1 Monat anknüfen;)

Könnt ihr mir bitte sagen, ob ich mit diesen "neuen" Programmierstil ohne bedenken fortführen kann oder fehlt noch was bzw. kann man da noch was verbessern?

Außerdem würde es mich interessieren wie ihr eure Variablen initialisiert? Macht ihr das immer in der php-Datei in der ihr sie benötigt oder legt ihr dafür z.B. eine global Datei ein und includiert diese üebrall rein bzw. welche Methode wäre besser?
(Ich persönlich tendiere eher zu einer Datei wo alle initialisiert werden um den Überblick zu erhalten, ist ja aber auf den anderen Seite wieder sinnlos da sie nicht überall benötigt werden...)

Wie immer freue ich mich über jedes Staement



config.php
PHP:
<?
define("HOST","localhost");
define("USERNAME","x");
define("DBPW","x");
define("DBNAME","x");

define("ERROR_CODE","2");
// 1 = show errors
// 2 = log errors
?>


mysql.class.php
PHP:
<?
class ExcMySql_critical_error extends Exception 
{
     public function __construct($Message) {
         parent::__construct($Message);
     }
}

class ExcMySql_non_critical_error extends Exception 
{
     public function __construct($Message) {
         parent::__construct($Message);
     }
}

class mysql 
{
	public $sql;	
	
	   public function __construct() {
	   	 if (!$this->db = mysql_connect (HOST, USERNAME, DBPW)) 
			throw new ExcMySql_critical_error("DB-Verbindung konnte nicht aufgebaut werden!");
		  
		 if (!mysql_select_db(DBNAME, $this->db))
			throw new ExcMySql_critical_error("DB konnte nicht ausgewählt werden!");
   	   }
		
	   public function select($column,$table,$where=false,$order=false,$limit=false) {
	    // $column wird in string umgewandelt und jedes Element in `` eingeschlossen
	    $column = mysql::converting($column,1);
	   	$sqlab = "
		SELECT $column
		FROM `$table`";
		 if ($where != false) {$sqlab.=" WHERE $where";};
		 if ($order != false) {$sqlab.= " ORDER BY $order";};
		 if ($limit != false) {$sqlab.= " LIMIT $limit";};
		 if (!$sql = mysql_query($sqlab)) {
			throw new ExcMySql_critical_error("MySql-Abfrage konnte nicht verarbeitet werden!");
		 }
		 else {
		 	//Letzte SQL-Abfrage wird gespeichert	
			$this->sql = $sql; 
		 }
		 if (mysql_num_rows($sql) == 0)
		 	throw new ExcMySql_non_critical_error("Die Ergebnissmenge der MySql-Abfrage ist 0!");
		return $sql;  
		}
		
	   public function insert($table,$column,$values) {
	   	$sqlab = "
		INSERT INTO `$table`
		($column)
		VALUES
		($values)";
		 if (!mysql_query($sqlab)) 
		 	throw new ExcMySql_critical_error("Bei der Eintragung der Daten in die Mysql-DB ist ein Fehler aufgetreten!");
		 if (mysql_affected_rows($this->db) == 0) 
		 	throw new ExcMySql_non_critical_error("Es wurde kein Datensatz in die Mysql-DB hinzugefügt!"); 
	    }
	    
	   public function update($table,$values,$where=false) {
	   	$sqlab = "UPDATE `$table` SET $values";
		if ($where != false) {$sqlab.=" WHERE $where";};
		 if (!mysql_query($sqlab)) 
			 throw new ExcMySql_critical_error("Datensatz konnte nicht geändert werden!"); 
		 if (mysql_affected_rows($this->db) == 0) 
			 throw new ExcMySql_non_critical_error("Es wurde kein Datensatz in der Mysql-DB verändert!");
	    }
		
	   public function delete($table, $where) {
	   	$sqlab = "DELETE FROM `$table` WHERE $where";
		 if (!mysql_query($sqlab)) 
    		throw new ExcMySql_critical_error("Datensatz konnte in der Mysql-DB nicht gelöscht werden!"); 
		 if (mysql_affected_rows($this->db) == 0) 
    		throw new ExcMySql_non_critical_error("Es wurde kein Datensatz in der Mysql-DB gelöscht!");
	   }
	   
	   
	   private function converting($column,$type) {
	   	 //Überprüfung ob $column = string
	   	 if (is_string($column)) {
		 	//Aus String wird Array erstellt und trim wird angewand   
   		 	$column = array_map('trim', explode(',', $column)); 
 		 } 
		 
		 if ($type == 1){
		 	 //Arrayelemente werden um `` ergänzt
			 for ($i=0;$i < count($column); $i++) {
				$column[$i]="`".$column[$i]."`"; 
		 	 }
			 //Array wird in String umgewandelt
			 $column=implode(",",$column);
		 } 
		return $column;
	   }
	   
	   public function fetch_object($column,$table,$where=false,$order=false,$limit=false) {
	    //Select-Anweißung durchführen
		$sql = mysql::select($column,$table,$where,$order,$limit);
		//$column wird in Array umgewandelt
		$column = mysql::converting($column,2);
		//Anzahl der Felder
		$numfields = mysql_num_fields($sql);
		//Die Namen der Felder werden im Array gespeichert
		for($i=0;$i < $numfields;$i++){
         	 $fieldname[$i] = mysql_field_name($sql, $i);
	    }
		//Überprüfung ob Datensätze ausgewählt wurden
		if (mysql_num_rows($sql) > 0) { //Wäre es an dieser Stelle möglich mit der evt. geworfenen Exception der select Methode zu arbeiten?
			//Arrayelemente werden mit Inhalt aus der DB belegt
			while ($row = mysql_fetch_object($sql)) {
				for($i=0;$i < $numfields;$i++){
           			$array[$fieldname[$i]]=$row->$fieldname[$i];
				}
			}
		}
		//Arrayelemente werden initialisiert wenn mysql_num_rows($sql) == 0
		else {
			for($i=0;$i < $numfields;$i++){
				$array[$fieldname[$i]]=false;
			}
		}
	   return $array;
	   }
	   
	   
	   public function fetch_array($column,$table,$where=false,$order=false,$limit=false) {
	    //Select-Anweißung durchführen
		$sql = mysql::select ($column,$table,$where,$order,$limit);
		//$column wird in Array umgewandelt
		$column = mysql::converting($column,2);
		//Anzahl der Felder
		$numfields = mysql_num_fields($sql);
		//Die Namen der Felder werden im Array gespeichert
		for($i=0;$i < $numfields;$i++){
         	$fieldname[$i] = mysql_field_name($sql, $i);
	    }
		//Überprüfung ob Datensätze ausgewählt wurden
		if (mysql_num_rows($sql) > 0) { //gleiches wie oben?
			//Arrays werden mit Inhalt aus der DB belegt
			while($row = mysql_fetch_array($sql)) {
				for ($i=0; $i < $numfields;$i++){
					$array[$fieldname[$i]][]=$row[$fieldname[$i]];
				}
			}
		}
		//Arrays werden initialisiert wenn mysql_num_rows($sql) == 0
		else {
			for ($i=0; $i < $numfields;$i++){
				$array[$fieldname[$i]][]=$row[$fieldname[$i]];
			}
		}
		return $array;
	   }
	   
	   public function __destruct() {
	    //Schließen der Mysql-Verbindung
		if (!mysql_close($this->db)) 
    		throw new ExcMySql("MySql-Verbindung konnte nicht geschlossen werden!");
	   }		
}




class security 
{

	public function secure_text($string) {
	$string = trim($string);    
	$string = htmlentities($string, ENT_QUOTES);    
	return($string);
	}
	
	public function mysql_secure($string,$type=1) {
	$string = security::secure_text($string);
	if ($type==1) {
		if(get_magic_quotes_gpc()) {
		  $string = stripslashes($string);    
		}
	}
	if (!$string = mysql_real_escape_string($string))  
		throw new ExcMySql_critical_error("Daten konnten nicht für die MySql-DB validiert werden"); 
    return $string;
  	}
	
	public function output($string) {
		html_entity_decode($string);
	return $string;
	}	
}



//Objekt erzeugen

$security=new security;




function user_meldung()
{
	echo "HI; Leider ist nen Fehler aufgetretetn";
}

function formular()
{
	echo "<br><br>hier da fehler eingeben";
}


function error($typ, $meldung, $datei, $zeile, $kontext)
{
   //Array, um Fehlernummern im Klartext darstellen zu koennen
   $klartext=array(1=>"Error",2=>"Warning",8=>"Notice",
   256=>"User Error",512=>"User Warning",
   1024=>"User Notice");
   ini_set("track_errors",1); // Tracking einschalten
   
   // enthaelt alle Variablen/Arrays, die spaeter
   // nicht ausgegeben werden sollen
   
   $exclude=array("HTTP_POST_VARS","_POST","_GET",
   "HTTP_COOKIE_VARS","_COOKIE","HTTP_SERVER_VARS",
   "_SERVER","HTTP_ENV_VARS","_ENV","HTTP_POST_FILES",
   "HTTP_GET_VARS","_FILES","_REQUEST");
   
   // Alle Variablen abarbeiten
   foreach ($exclude as $key) {
      // Variable loeschen
      unset ($kontext[$key]);
   }
   ob_start();
   print_r($kontext);
   $kontext_inhalte=ob_get_contents();
   ob_end_clean();

   $beschr = "<table style = \"border:2px solid #FF3300\" border=\"1px\" width=\"700px\">
	 <tr>
	  <td width=\"100px\"><b>Datum:</b> </td>
	  <td>". date("d-m-Y H:i:s") ."</td>
	 </tr>
	 <tr>
	  <td><b>Fehlertyp:</b> </td>
	  <td>$klartext[$typ] </td>
	 </tr>
	 <tr>
	  <td valign=\"top\"><b>Meldung:</b> </td>
	  <td>$meldung</td>
	 </tr>
	 <tr>
	  <td><b>Datei:</b> </td>
	  <td>$datei</td>
	 </tr>
	 <tr>
	  <td><b>Zeile:</b> </td>
	  <td>$zeile</td>
	 </tr>
	 <tr>
	  <td valign=\"top\"><b>Variablen:</b> </td>
	  <td><pre>$kontext_inhalte </pre></td>
	 </tr>
	</table>";
	
	if (ERROR_CODE == 1) {
		echo "$beschr<br><br>";
	}
	else {
	
		@$fp=fopen("errorsd.php","r");
		
		if ($fp == true) {
			fputs($fp,$beschr);
		}
		else {
			try {
				if (!$db = mysql_connect (HOST, USERNAME, DBPW))
					throw new ExcMySql_critical_error("DB-Verbindung konnte nicht aufgebaut werden!");
				if (!mysql_select_db(DBNAME, $db))
					throw new ExcMySql_critical_error("DB konnte nicht ausgewählt werden!");
				$sqlab = "INSERT INTO `error_log`
						(error)
						VALUES
						('$beschr')";
				 if (!mysql_query($sqlab)) 
					throw new ExcMySql_critical_error("Bei der Eintragung der Daten in die Mysql-DB ist ein Fehler aufgetreten!");
				 if (mysql_affected_rows($db) == 0) 
					throw new ExcMySql_critical_error("Es wurde kein Datensatz in die Mysql-DB hinzugefügt!"); 
			}
			catch(ExcMySql_critical_error $fehler) {
				echo $fehler->getMessage();
				$empf="mgora@online.de";
	
				$subject="Fehler auf xxx.tld";
				$subject=urlencode($subject);
				$subject=str_replace("%","=",$subject);
				$subject=str_replace("+"," ",$subject);
				$subject="=?ISO-8859?1?Q?$subject?=";
				
				$body="<html>
				<head></head>
				<body>
				Hallo,<br><br>
				
				da ein aufgetredener Fehler weder in der log-Datei noch in der DB gespeichert werden konnte, wird Ihnen dieser nun per Mail zugesant:<br><br>
				
				$beschr
				</body>
				</html>";
				
				$hdrs="From: Fehlermanagement xx.tld <webmaster@prov.tld>\n";
				$hdrs.="MIME-Version: 1.0\n";
				$hdrs.="Content-Type: text/html; charset=\"iso-8859?1\"\n";
				$hdrs.="Content-Transfer-Encoding: 8bit\n";
				$hdrs.="X-Priority: 1\n";
				$hdrs.="Priority: Urgent\n";
				$hdrs.="Importance: High\n";
				$hdrs.="X-MSMail-Priority: High";
				//$hdrs.= "$body\r\n";
				
				if (mail($empf,$subject,$body,$hdrs) == false) {
					$formular=true;
				}
			}
		}  
	   switch ($typ) {
		   case E_WARNING:
		   case E_USER_WARNING:
		   case E_USER_ERROR:
				user_meldung();
				if ($formular === true) {
					formular();
				}
				die;
		}
	 }

}
?>

sicherheitstest.php
PHP:
<?
error_reporting(E_ALL);
include("config.php");
if (ERROR_CODE == 1){
	ini_set('display_errors', 1); 
	ini_set("log_errors",0); 
}
else {
	ini_set('display_errors', 0); 
	ini_set("log_errors",1); 
	ini_set("error_log","(/www/htdocs/w0074849/labor/error.php"); 
}
include("mysql.class.php");
set_error_handler("error");


function exception_handler($fehler) {
	  trigger_error($fehler->getMessage());   
}
set_exception_handler('exception_handler');



try {
	$mysql=new mysql;
	$eingabe2=false;
	$sql=false;
	if (isset($_POST['eingabe1'])): $eingabe1 = $security->mysql_secure($_POST['eingabe1']); else: $eingabe1=false; endif;
	if (isset($_POST['eingabe2'])): $eingabe2 = $security->mysql_secure($_POST['eingabe2']); else: $eingabe2=false; endif;
	if (isset($_POST['senden'])): $senden=true; else: $senden=false; endif;

	if ($senden === true && !empty($eingabe1) && !empty($eingabe2)) {	
	
		try {
			$mysql->insert("test","ein1, ein2","'$eingabe1' ,'$eingabe2'");
		}
		catch(ExcMySql_non_critical_error $fehler) {
			echo $fehler->getMessage();
		}
		
		try {
			$ausgabe = $mysql->fetch_object("ein1, ein2","test",false,"'id' Desc");
		}
		catch (ExcMySql_non_critical_error $fehler) {
			echo $fehler->getMessage();
		}
		
		echo 'Ausgabe der Eingaben aus der DB:<br>1:'.$security->output($ausgabe['ein1']).'<br>2:'.$security->output($ausgabe['ein2']);
		mysql_free_result($mysql->sql);
	}
	?>
	<form action="" enctype="multipart/form-data" method="POST">
	Eingabe1: <input name="eingabe1" size="30" value="<? echo stripslashes($eingabe1); ?>"><br>
	Eingabe2: <input name="eingabe2" size="30"  value="<? echo stripslashes ($eingabe2); ?>"><br><br>
	<input name="senden" type="submit" value="Abschicken">
	</form>
	<br><br>
	Ausgabe aller daten:
	<table style="width:400px;" border="1px" cellspacing="0" bordercolorlight="#000000" bordercolor="#000000" bordercolordark="#000000">
	<?
	try {
		$ausgabe_alle = $mysql->fetch_array("ein1, ein2","test",false,"`id` DESC");
	}
	catch (ExcMySql_non_critical_error $fehler) {
		echo $fehler->getMessage();
	}
	echo count($ausgabe_alle['ein1']);
	for($i=0;$i < count($ausgabe_alle['ein1']); $i++) {	
		echo "
		<tr>
		  <td valign=\"top\">".wordwrap($ausgabe_alle['ein1'][$i], 20, "\n", 1)."</td>
		  <td valign=\"top\">".wordwrap($ausgabe_alle['ein2'][$i], 20, "\n", 1)."</td>
		 </tr>
		 ";
	}
	mysql_free_result($mysql->sql);
}
catch(ExcMySql_critical_error $fehler) {
	trigger_error($fehler->getMessage(), E_USER_WARNING);
}
?>
</table>