Torsten: Anfängerfrage, über connect zur Datenbank

Bitte schaut nur einmal über meinen Code, ob das so richtig ist, oder ob man es anderes machen sollte. Ichh abe hier mein PHP Buch gewälzt, und bin mir trotzdem nicht ganz sicher.

Torsten

define('DB_NAME', 'datenbank');
define('DB_USER', 'root');
define('DB_PASSWORD', 'passwort');
define('DB_HOST', 'localhost');

$Verbindung = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die ("Verbindung fehlgeschlagen");
mysql_select_db(DB_NAME) or die ("Datenbank existiert nicht");
mysql_close($Verbindung);

  1. Und was tut es?

  2. Sieht auf den ersten Blick gut aus.

    2 Ratschläge:

    Speichere das in einer einzelnen PHP-Datei, deren Name mit '.ht_' beginnt und auf '.php' endet. Das schafft geringfügig mehr Sicherheit für das Datenbank-Passwort, denn ein Apache-Webserver wird eine Datei mit einem solchen Name in der Grundkonfiguaration nicht ausliefern.

    Includiere die Datei mit require_once.

    Benutze mysql_pconnect

    Das könnte so manchen aufwendigen Verbindungsaufbau ersparen und die Performance verbessern.

    Jörg Reinholz, Schlosser

    1. Tach!

      Benutze mysql_pconnect

      Diese Empfehlung ist mit Vorsicht zu genießen, besonders wenn man Anfänger ist und nicht weiß, was bei der P-Variante alles zu beachten ist.

      Das könnte so manchen aufwendigen Verbindungsaufbau ersparen und die Performance verbessern.

      Der MySQL-Verbindungsaufbau ist für die meisten Anwendungsfälle schnell genug - für Anfängerscripts sowieso. Es sind eine ganze Menge Fallstricke zu beachten: Persistent Database Connections oder Advantages / Disadvantages of pconnect.

      dedlfix.

  3. Tach!

    Bitte schaut nur einmal über meinen Code, ob das so richtig ist, oder ob man es anderes machen sollte. Ichh abe hier mein PHP Buch gewälzt, und bin mir trotzdem nicht ganz sicher.

    Nimm das PHP-Buch nur mit Vorsicht, denn es ist veraltet. Die mysql-Extension wird nicht mehr lange unterstützt werden, wie man im PHP-Handbuch (englische Originalausgabe) bei den Beschreibungen all ihrer Funktionen lesen kann. Stattdessen ist die mysqli-Extension oder PDO der Ersatz. (PDO ist etwas anwenderfreundlicher.) Beispiele sind zu allen Funktionen und auch zum generellen Einsatz in den entsprechenden Kapiteln zu finden.

    $Verbindung = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die ("Verbindung fehlgeschlagen");
    mysql_select_db(DB_NAME) or die ("Datenbank existiert nicht");

    'or die()' ist keine Fehlerbehandlung. Schnupfen kuriert man auch nicht durch Erschießen. Besser ist, sich für den Fehlerfall Gedanken zu machen, wie der Admin benachrichtigt wird und was der normale Besucher stattdessen zu sehen bekommt, damit er vielleicht doch noch ein brauchbares Ergebnis und die Konkurrenz keinen neuen Kunden bekommt.

    dedlfix.

  4. Hi Torsten,

    Bitte schaut nur einmal über meinen Code, ob das so richtig ist, oder ob man es anderes machen sollte. Ichh abe hier mein PHP Buch gewälzt, und bin mir trotzdem nicht ganz sicher.

    Ich greife mal dedlfix Vorschlag auf: PDO
    Untenstehend eine Basisklasse, aus welcher für sprezielle Aufgaben weitere Klassen abgeleitet werden können. Keine Angst vor OOP, Du kommst sowieso nicht dran vorbei ;)

    Das Beispiel zeigt auch das Exception-Chaining. Deswegen ja auch eine eigene Klasse, weil es eine PDOException geben könnte (DB-Server wech) und in der eigenen Anwendungs-Klasse mit Exception gearbeitet wird; eine etwaige PDPException wird an die Klasse Exception 'durchgereicht'.

    Beim Entwickeln ebenfalls hilfreich, Du siehst auch ewaige Syntaxfehler.

    Viel Spaß, Hotti

      
    <?php  
    // die neue PDO Basisklasse für MySQL  
    ///////////////////////////////////////////////////////////////////////////  
      
    class MySQL{  
    	protected $DBH;  
    	public function __construct($cfg = array()){  
    		try{  
    			$this->dbh($cfg);  
    		}  
    		catch(PDOException $e){  
    			throw new Exception($e->getMessage());  
    		}  
    	}  
      
    	private function dbh($cfg){  
    		$default = array(  
    			'user' => '',  
    			'pass' => '',  
    			'host' => 'localhost',  
    			'port' => 3306,  
    			'base' => 'myweb',  
    		);  
    		$cred = array_merge($default, $cfg);  
    		$this->DBH = new PDO(sprintf("mysql:dbname=%s;host=%s", $cred['base'], $cred['host']),  
    			$cred['user'], $cred['pass'],  
    			array(  
    				PDO::ATTR_TIMEOUT => 2,  
    				PDO::ATTR_PERSISTENT => true,  
    			));  
    		$this->DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
    	}  
    }  
      
    ///////////////////////////////////////////////////////////////////////////  
    /* Testbereich */  
      
    // Der Connect könnte eine Exception werfen, also auffangen  
    try{  
    	$pdo = new MySQL (array('host' => 'roro'));  
    	echo "DB-Verbindung OK\n", print_r($pdo,1);  
    }  
    catch(Exception $e){  
    	echo "Fehler/Exception: ", $e->getMessage();  
    }  
    /* Testbereich Ende */  
      
    return;  
    ?>  
    
    
    1. Tach!

      Untenstehend eine Basisklasse, aus welcher für sprezielle Aufgaben weitere Klassen abgeleitet werden können.
      class MySQL{

      Nicht nur, dass du einfach von PDO erben und somit dessen Funktionsumfang direkt nutzen könntest, statt für alles Wrapperfunktionen bereitstellen zu müssen, machst du aus der von PDO betriebenen Abstraktion über viele DBMSe wieder eine Konkretisierung auf nur ein einzelnes DBMS. Warum nimmst du dann nicht gleich mysqli als Basis, wenn du nur den MySQL-Teil haben willst?

      Das Beispiel zeigt auch das Exception-Chaining. Deswegen ja auch eine eigene Klasse, weil es eine PDOException geben könnte (DB-Server wech) und in der eigenen Anwendungs-Klasse mit Exception gearbeitet wird; eine etwaige PDPException wird an die Klasse Exception 'durchgereicht'.

      Damit erreichst du, dass man im übergeordneten Programmteil nicht mehr speziell auf PDOExceptions reagieren kann, stattdessen nur noch die ganz allgemeine Exception zur Verfügung hat, die noch bei einer Menge anderer Probleme geworfen werden könnte (nicht in diesem Fall hier, aber wenn man mal das System weiter ausbauen will, kommt das irgendwann zum Tragen). Es ist manchmal sinnvoll, spezielle Exceptions in andere Exceptions einzupacken, dann aber sicher nicht in die ganz allgemeine Exception-Klasse.

        catch(PDOException $e){  
        	throw new Exception($e->getMessage());  
      

      Seit PHP 5.3 kann man auch richtiges Exception Chaining verwenden. "Richtiges" unterscheidet sich von deiner Varianten, dass nicht nur die Message durchgereicht wird sondern dass die gesamte ursprüngliche Exception als Eigenschaft der neuen Exception gespeichert wird.

      Das Einpacken und Neu-Werfen gibt zudem an den Aufrufer in den Eigenschaften für Line und File die neue throw-Zeile an. Das Reduzieren auf den Meldungstext macht somit auch das Indentifizieren der ursprünglichen Stelle schwerer, weil diese Information aus der alten Exception verloren geht - und das hier auch noch völlig ohne Not. Das heißt also, so wie du das zeigst, baust du dir nur Nachteile in den Code.

      dedlfix.

      1. hi,

        Nicht nur, dass du einfach von PDO erben und somit dessen Funktionsumfang direkt nutzen könntest, statt für alles Wrapperfunktionen bereitstellen zu müssen, machst du aus der von PDO betriebenen Abstraktion über viele DBMSe wieder eine Konkretisierung auf nur ein einzelnes DBMS.

        Was ich gezeigt habe ist, nur die Basisklasse, welche den DBHandler bereitstellt, das ist in diesem Fall das PDO (PDO ≅ DBH).

        Warum nimmst du dann nicht gleich mysqli als Basis, wenn du nur den MySQL-Teil haben willst?

        Es geht eben nicht nur um MySQL. Von daher ist meine Basisklasse austauschbar ;)

        Seit PHP 5.3 kann man auch richtiges Exception Chaining verwenden. "Richtiges" unterscheidet sich von deiner Varianten, dass nicht nur die Message durchgereicht wird sondern dass die gesamte ursprüngliche Exception als Eigenschaft der neuen Exception gespeichert wird.

        Guck ich mir an, danke!

        Viele Grüße,
        Horst