Fakultät IWI DB & IS II - SS 2017 PHP Teil 2 • Zugriff auf Datenbanken • Objektorientierung in PHP5 Andreas Schmidt PHP - Teil 2 1/24 Fakultät IWI DB & IS II - SS 2017 Datenbankzugriff mit PHP • verschiedene Varianten • native Schnittstelle (mysql_<x>, ora_<x>, ...) • ODBC Funktionen (z.B. odbc_fetchRow(...) • PHP Data Objects (PDO) • PEAR MDB2 Paket (PHP Extension and Application Repository) • Eigenschaften der PDO und PEAR MDB2 Klassen • einheitliche API für verschiedene Datenbanken • durchgängiges objektorientiertes Design (ala JDBC) • einheitlicher Zugriff auf Metainformationen der unterschiedlichen Datenbanken • weitere Eigenschaften von MDB2: • Reihe von Zusatzfunktionalitäten (z.B. Sequenzen, Range von Ergebnissen, ...) • einheitliche Fehlermeldungen/Bezeichner Andreas Schmidt PHP - Teil 2 2/24 Fakultät IWI DB & IS II - SS 2017 PDO: Methoden für Datenbankzugriff (1) $db = new PDO($dsn, $user, $password) $db = null; // Connects to a database // Disconnects from a database $stmt = $db->query($sql) // Sends a query to the database $stmt = $db->prepare($sql) $stmt->execute($parameter) // Prepares a SQL statement for later execution // Executes a prepared SQL statment $row = $stmt->fetch($fetchmode) // Fetches next row from a result set $stmt->columnCount() $stmt->rowCount() // Gets number of columns in a result set // Gets number of rows in a result set $db->exec($sql) // executes an Modification DML-Statement // (insert, update, delete). // returns the number of affected rows Andreas Schmidt PHP - Teil 2 3/24 Fakultät IWI DB & IS II - SS 2017 Auswahl: Methoden für Datenbankzugriff (2) $db->beginTransaction(); $db->commit() $db->rollback() // Starts a transaction // Commits the current transacition // Rolls back the current transaciton $value = $db->quote($value, $datatype) // quote data $stmt->getColumnMeta($col_number); Andreas Schmidt // returns a dictionary with informations // about column PHP - Teil 2 4/24 Fakultät IWI DB & IS II - SS 2017 PDO: Verbindungsaufbau • Durch Datasourcename (dsn) werden spezifische Treiber für DB geladen • Aufbau DSN $dbType:host=$host:$port;dbname=$dbname $dbType:dbname=$dbspec • Beispiele: • $dsn = "mysql:host=localhost;dbname=mondial"; • $dsn = "oci:dbname=oracledbwi"; # mit tnsnames.ora • $dsn = 'oci:dbname=xe'; # mit tnsnames.ora • $dsn = 'oci:dbname=//iwi-w-vm-dbo:1521/oracledbwi.hskarlsruhe.de' • $dsn = "oci:dbname=//localhost:1521/xe • Standardmäßig werden MySQL Treiber geladen, die anderen müssen in der php.ini explizit angegeben werden (php_pdo_oci.dll, php_pdo_...) Andreas Schmidt PHP - Teil 2 5/24 Fakultät IWI DB & IS II - SS 2017 PDO: Beispiele für den Zugriff auf Datenbanken $ds = 'mysql:host=localhost;dbname=mondial'; try { $db = new PDO($ds, ’root’, ’’); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->beginTransaction(); $sql = "SELECT name, height FROM mountain WHERE height > ? ORDER BY height desc"; $stmt = $db->prepare( $sql ); $stmt->execute(array(5000)); while ($row = $stmt->fetch()) { print("{$row[0]} ({$row[1]})\n"); } print "\n{$stmt->rowCount()} datasets returned\n"; $db = null; } catch (PDOException $e) { echo "Fehler: ".$e->getMessage()."\n"; } Andreas Schmidt • Ausgabe: $ php.exe pdo_select.php Mount Everest (8848) Mount Godwin Austen (8611) Pik Kommunizma (7494) Pik Pobeda (7439) Pik Lenina (7134) Pik Chan-Tengri (6995) ... 21 datasets returned PHP - Teil 2 6/24 Fakultät IWI DB & IS II - SS 2017 PDO: Beispiele für den Zugriff auf Datenbanken $ds = 'mysql:host=localhost;dbname=mondial'; try { $db = new PDO($ds, 'root', ''); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->beginTransaction(); $sql = "INSERT INTO mountain (name, height, longitude, latitude) VALUES (?, ?, ?, ?)"; $stmt = $db->prepare( $sql ); $stmt->execute(array('Mahlberg', 613, 8.22, 48.50)); print "Datensatz eingefügt\n"; $db->commit(); $db = null; } catch (Exception $e) { echo "Fehler: ".$e->getMessage()."\n"; } Andreas Schmidt PHP - Teil 2 7/24 Fakultät IWI DB & IS II - SS 2017 MySQL: Insert & automatisch generierte Schlüsselwerte -- DDL: create table pdo_test ( id integer primary key auto_increment, value varchar(20) not null ) engine=innodb; // Code: ... $sql = "insert into pdo_test (value) values(?)"; $stmt = $db->prepare( $sql ); $stmt->execute(array('test')); $id = $db->lastInsertId(); print "Datensatz mit ID $id eingefügt\n"; Andreas Schmidt PHP - Teil 2 8/24 Fakultät IWI DB & IS II - SS 2017 Oracle: Insert & automatisch generierte Schlüsselwerte -- DDL: create sequence seq_pdo_test; create table pdo_test ( id number primary key, value varchar2(20) not null ); // Code: ... $sql = "insert into pdo_test (id, value) values(seq_pdo_test.nextval, ?)"; $stmt = $db->prepare( $sql ); $stmt->execute(array('test')); $sql = "SELECT seq_pdo_test.currval FROM dual"; $x = $db->query($sql)->fetch(); print "Datensatz mit ID {$x[0]} eingefügt\n"; Andreas Schmidt PHP - Teil 2 9/24 Fakultät IWI DB & IS II - SS 2017 PDO: Beispiele für den Zugriff auf Datenbanken $ds = 'mysql:host=localhost;dbname=mondial'; try { $db = new PDO($ds, 'root',''); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->beginTransaction(); $sql = "UPDATE SET WHERE AND city population = round(population * 1.05) country = ? province = ?"; $stmt = $db->prepare( $sql ); $stmt->execute(array('F', 'Bretagne')); print "{$stmt->rowCount()} datasets changed\n"; $db->commit(); $db = null; } catch (PDOException $e) { echo "Fehler: ".$e->getMessage()."\n"; } Andreas Schmidt PHP - Teil 2 10/24 Fakultät IWI DB & IS II - SS 2017 Vollständiges Beispiel <?php $ds = 'mysql:host=localhost;dbname=mondial'; try { $db = new PDO($ds, 'root', ''); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION $sql = "select name, height from mountain where height > ? order by height desc"; $stmt = $db->prepare( $sql ); $stmt->execute(array(5000)); ?> <html> <head> <title>Mondial DB: Mountains</title> </head> <body> <h1 align="center"> High Mountains </h1> <table align="center" border="1"> <tr> <th>name</th> <th>Altitude</th> </tr> <?php while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { ?> <tr> <td><?php echo $row['name'] ?></td> <td><?php echo $row['height'] ?></td> </tr> <?php } ?> </table> </body> </html> <?php $db = null; } catch (Exception $e) { echo "Fehler: ".$e->getMessage()."\n"; } Schmidt Andreas PHP - Teil 2 11/24 Fakultät IWI DB & IS II - SS 2017 Ausgabe Andreas Schmidt PHP - Teil 2 12/24 Fakultät IWI DB & IS II - SS 2017 Onlinequellen zu PDO und MDB2 • Manual: Package PDO: http://php.net/manual/de/book.pdo.php • PDO-Tutorial: http://code.tutsplus.com/tutorials/why-you-should-be-using-phps-pdo-for-databaseaccess--net-12059 • Package Information: MDB2 http://pear.php.net/package/MDB2 • http://www.installationwiki.org/MDB2 Andreas Schmidt PHP - Teil 2 13/24 Fakultät IWI DB & IS II - SS 2017 Objektorientierung in PHP • Konzepte: • Klassen • Instanzen- /Klassenvariablen • Instanzen- /Klassenmethoden • Konstruktoren • Vererbung • Interfaces • Sichtbarkeit: private, protected, public • Exceptions • „magic methods“ Andreas Schmidt • Beispiel $b1 = new Bruch(1); $b2 = new Bruch(-1, 2); $b3 = $b1->sub($b2); $b4 = $b3->mult(new Bruch (-2, 3)); echo $b4; PHP - Teil 2 14/24 Fakultät IWI DB & IS II - SS 2017 Quellcode Bruch.php function neg() { return new Bruch(-$this->zaehler, $this->nenner); } class Bruch { private $zaehler; private $nenner; function __tostring() { if ($this->nenner!=1) return "$this->zaehler/$this->nenner"; else return "$this->zaehler"; } function __construct($z=0, $n=1) { $this->zaehler = $z; if ($n==0) die("Nenner darf nicht 0 sein"); $this->nenner = $n; $this->kuerze(); } private static function ggt($m, $n) { $m = abs($m); $n = abs($n); if ($n>$m) return Bruch::ggt($n,$m); while ($n>0) { $z = $n; $n = $m % $n; $m = $z; } return $m; } private function kuerze() { $ggt = Bruch::ggt($this->zaehler, $this->nenner); $this->zaehler = $this->zaehler / $ggt; $this->nenner = $this->nenner / $ggt; } function add($b) { $zn = $this->zaehler * $b->nenner + $this->nenner * $b->zaehler; $nn = $b->nenner * $this->nenner; return new Bruch($zn, $nn); } Andreas Schmidt // weitere Methoden ... } PHP - Teil 2 15/24 Fakultät IWI DB & IS II - SS 2017 Objektorientierung in PHP5 • Konstruktoren werden wie normale Methoden definiert, allerdings tragen sie den Namen _ _construct(...) (bis PHP4: den selben Namen wie die Klasse) • Instanzenvariablen und Methoden besitzen die Sichtbarkeit private, protected, public (default: public) • Zugriff auf Instanzenvariablen (falls erlaubt) erfolgt mittels Pfeil-Notation: $bruch->zaehler • Aufruf der Instanzenmethoden (falls erlaubt) erfolgt mittels Pfeil-Notation: $bruch->ausgabe() • Innerhalb der Klasse kann auf die Instanz mittels des Bezeichners $this zugegriffen werden $this->nenner $this->kuerze() Andreas Schmidt PHP - Teil 2 16/24 Fakultät IWI DB & IS II - SS 2017 Objektorientierung in PHP5 • Klassenmethoden werden durch voranstellen des Schlüsselwortes static gekennzeichnet • Aufruf von Klassenmethoden erfolgt durch das Voranstellen des Klassennamens und :: Bruch::ggt($z1, $z2) • Klassenvariablen werden durch das Schlüsselwort static deklariert (z.B. static public $database_connection) • Zugriff auf Klassenvariablen: • innerhalb der Klasse: self::$database_connection • von außerhalb1: Klassenname::$database_connection • Einfachvererbung ist mittels des Schlüsselwortes extends möglich: class Student extends Person { // Klassendefinition v. Student 1. sofern erlaubt Andreas Schmidt PHP - Teil 2 17/24 Fakultät IWI DB & IS II - SS 2017 Objektorientierung in PHP5 • Magic Methods • _ _toString(): wird aufgerufen wenn ein Objekt mittels echo ausgegeben wird • _ _call($methodname, $parameter): wird aufgerufen, wenn keine passende Methode gefunden wurde • _ _get($property_name): wird aufgerufen, wenn kein passendes Property gefunden wurde • _ _set($propertyname, $value): wird aufgerufen, wenn ein nichtexistierendes Property einen Wert zugewiesen bekommt Andreas Schmidt PHP - Teil 2 18/24 Fakultät IWI DB & IS II - SS 2017 nützliche PHP-Funktionen • explode($separator, $string) -- Zerteilt einen String anhand eines Trennzeichens • implode($separator, $array) -- Verbindet Array-Elemente zu einem String (anderer Name: join) • strlen($str) -- Ermitteln der String-Länge • die($message) -- Gibt eine Nachricht aus und beendet das aktuelle Skript • eval($code_str) -- Wertet einen String aus, als wäre er PHP-Code (Bsp: $eval_string = "\$obj = new $class(\$row);"; eval($eval_string); • print_r($var): Gibt komplette Datenstruktur aus (zu Debugzwecken) Andreas Schmidt PHP - Teil 2 19/24 Fakultät IWI DB & IS II - SS 2017 nützliche PHP-Funktionen • • • • empty($var) -- Testet ob eine Variable einen Wert ungleich "" hat. isset($var) -- Prüft die Existenz einer Variablen exec($str) -- Führt ein externes Programm aus is_array($var) -- liefert TRUE, wenn es sich bei der übergebenen Variable um einen Array (oder assoziativen Array) handelt • is_object($var) -- liefert TRUE,. wenn es sich bei der übergebenen Variable um ein Objekt (Instanz einer Klasse) handelt • print $str -- wie echo $str Andreas Schmidt PHP - Teil 2 20/24 Fakultät IWI DB & IS II - SS 2017 Tipps • Verschiedene Arten von möglichen Fehlern: • PHP-Syntax Fehler: z.B. falsche Klammerung, falsche Schreibweise bei Funktionen/Methoden, ... • Beispiele: Parse error: syntax error, unexpected '}' in .\DB-IS-2WS06\code\OO.php on line 28 Fatal error: Call to undefined method Test::set_idx() in .\DB-IS-2-WS06\code\OO.php on line 27 Andreas Schmidt PHP - Teil 2 21/24 Fakultät IWI DB & IS II - SS 2017 Tipps • PHP Programmierfehler (falsch geschriebene Variablennamen) print "hier erfolgt keine Warnung: \$a: $a\n"; error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); print "Hier schon: \$a: $a\n"; •Ausgabe $ php.exe warnungen.php hier erfolgt keine Warnung: $a: Notice: Undefined variable: a in C:\test\warnungen.php on line 5 Hier schon: $a: Andreas Schmidt PHP - Teil 2 22/24 Fakultät IWI DB & IS II - SS 2017 Tipps • SQL-Fehler: • Beispiel: [nativecode=1064 ** You have an error in your SQL syntax; check the manual thatcorresponds to your MySQL server version for the right syntax to use near '< 1000' at line 1] Andreas Schmidt PHP - Teil 2 23/24 Fakultät IWI DB & IS II - SS 2017 Tipps • HTML-Fehler: • keine Ausgabe wegen fehlerhaftem HTML Andreas Schmidt PHP - Teil 2 24/24