29
Andreas Schmidt PHP - Teil 2 1/29 Fakultät IWI DB & IS II - WS 2018 PHP Teil 2 Zugriff auf Datenbanken Objektorientierung in PHP5

Fakultät IWI DB & IS II - WS 2018 - smiffy.de · • PHP Data Objects (PDO) • PEAR MDB2 Paket (PHP Extension and Application Repository) • Eigenschaften der PDO und PEAR MDB2

  • Upload
    lamnga

  • View
    215

  • Download
    0

Embed Size (px)

Citation preview

Andreas Schmidt PHP - Teil 2 1/29

Fakultät IWIDB & IS II - WS 2018

PHP Teil 2

• Zugriff auf Datenbanken

• Objektorientierung in PHP5

Andreas Schmidt PHP - Teil 2 2/29

Fakultät IWIDB & IS II - WS 2018

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 3/29

Fakultät IWIDB & IS II - WS 2018

PDO: Methoden für Datenbankzugriff (1)

$db = new PDO($dsn, $user, $password) // Connects to a database $db = null; // Disconnects from a database

$stmt = $db->query($sql) // Sends a query to the database

$stmt = $db->prepare($sql) // Prepares a SQL statement for later execution$stmt->execute($parameter) // Executes a prepared SQL statment

$row = $stmt->fetch($fetchmode) // Fetches next row from a result set

$stmt->columnCount() // Gets number of columns in a result set$stmt->rowCount() // Gets number of rows in a result set

$stmt->bindParam($pos, $value, $dataType, $length)// binds a php variable to an questionmark // placeholder in a SQL-Statement

Andreas Schmidt PHP - Teil 2 4/29

Fakultät IWIDB & IS II - WS 2018

Auswahl: Methoden für Datenbankzugriff (2)

$db->beginTransaction(); // Starts a transaction$db->commit() // Commits the current transacition$db->rollback() // Rolls back the current transaciton

$value = $db->quote($value, $datatype) // quote data

$stmt->getColumnMeta($col_number); // returns a dictionary with informations // about column

Andreas Schmidt PHP - Teil 2 5/29

Fakultät IWIDB & IS II - WS 2018

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.hs-

karlsruhe.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 6/29

Fakultät IWIDB & IS II - WS 2018

PDO: Beispiele für den Zugriff auf Datenbanken

$dsn = 'mysql:host=localhost;dbname=mondial';try {$db = new PDO($dsn, "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";}

• Ausgabe:

$ php.exe pdo_select.phpMount Everest (8848)Mount Godwin Austen (8611)Pik Kommunizma (7494)Pik Pobeda (7439)Pik Lenina (7134)Pik Chan-Tengri (6995)...

21 datasets returned

Andreas Schmidt PHP - Teil 2 7/29

Fakultät IWIDB & IS II - WS 2018

PDO: Beispiele für den Zugriff auf Datenbanken

$dsn = 'mysql:host=localhost;dbname=mondial';try {

$db = new PDO($dsn, '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 (PDOException $e) { echo "Fehler: ".$e->getMessage()."\n";}

Andreas Schmidt PHP - Teil 2 8/29

Fakultät IWIDB & IS II - WS 2018

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 9/29

Fakultät IWIDB & IS II - WS 2018

-- 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";

Oracle: Insert & automatisch generierte Schlüsselwerte

Andreas Schmidt PHP - Teil 2 10/29

Fakultät IWIDB & IS II - WS 2018

PDO: Beispiele für den Zugriff auf Datenbanken

$dsn = 'mysql:host=localhost;dbname=mondial';try { $db = new PDO($dsn, 'root',''); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$db->beginTransaction();

$sql = "UPDATE city SET population = round(population * 1.05) WHERE country = ? AND 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 11/29

Fakultät IWIDB & IS II - WS 2018

PDO: Ausführen einer Stored Function

$dsn = 'oci:host=localhost;dbname=xe';try { $db = new PDO($dsn, $user, $pw); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->beginTransaction(); $sql = "BEGIN ? := neue_bestellung(?); END;"; $stmt = $db->prepare( $sql ); $kunde_id = 1; $bestell_id = null; $stmt->bindParam(2, $kunde_id, PDO::PARAM_INT); $stmt->bindParam(1, $bestell_id, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 32); if ($stmt->execute()) {

print "stored function ausgeführt\n"; } print "Bestell ID: $bestell_id\n";

$db->commit(); $db = null;} catch (Exception $e) { echo "Fehler: ".$e->getMessage()."\n";}

Andreas Schmidt PHP - Teil 2 12/29

Fakultät IWIDB & IS II - WS 2018

PDO: Ausführen einer Stored Procedure

$dsn = 'oci:host=localhost;dbname=xe';try { $db = new PDO($dsn, $user, $pw); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->beginTransaction();

$sql = "BEGIN neuer_bestellposten(?,?,?); END;"; $stmt = $db->prepare( $sql ); $bestellung_id = 3;

$artikel_id = 1; $anzahl = 3; $stmt->bindParam(1, $bestell_id, PDO::PARAM_INT); $stmt->bindParam(2, $artikel_id, PDO::PARAM_INT); $stmt->bindParam(3, $anzahl, PDO::PARAM_INT);

if ($stmt->execute()) echo "$anzahl Artikel mit ID $artikel_id eingefügt\n";

$db->commit(); $db = null;} catch (Exception $e) { echo "Fehler: ".$e->getMessage()."\n";}

Andreas Schmidt PHP - Teil 2 13/29

Fakultät IWIDB & IS II - WS 2018

<?php $dsn = 'mysql:host=localhost;dbname=mondial'; try { $db = new PDO($dsn, '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"; }

Vollständiges Beispiel

Andreas Schmidt PHP - Teil 2 14/29

Fakultät IWIDB & IS II - WS 2018

Ausgabe

Andreas Schmidt PHP - Teil 2 15/29

Fakultät IWIDB & IS II - WS 2018

Onlinequellen zu PDO

• 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-database-access--net-12059

Andreas Schmidt PHP - Teil 2 16/29

Fakultät IWIDB & IS II - WS 2018

Objektorientierung in PHP

• Konzepte:

• Klassen

• Instanzen- /Klassenvariablen

• Instanzen- /Klassenmethoden

• Konstruktoren

• Vererbung

• Interfaces

• Sichtbarkeit:private, protected, public

• „magic methods“

• Beispiel

$b1 = new Bruch(1);$b2 = new Bruch(-1, 2);$b3 = $b1->sub($b2);$b4 = $b3->mult(new Bruch (-2, 3));echo $b4;

Andreas Schmidt PHP - Teil 2 17/29

Fakultät IWIDB & IS II - WS 2018

Quellcode Bruch.php

class Bruch { private $zaehler; private $nenner;

function __construct($z=0, $n=1) { $this->zaehler = $z; if ($n==0) die("Nenner darf nicht 0 sein"); $this->nenner = $n; $this->kuerze(); }

private function kuerze() { $ggt = self::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); }

function neg() { return new Bruch(-$this->zaehler, $this->nenner); }

function __toString() { if ($this->nenner!=1) return "$this->zaehler/$this->nenner"; else return "$this->zaehler"; }

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; }

// weitere Methoden ...}

Andreas Schmidt PHP - Teil 2 18/29

Fakultät IWIDB & IS II - WS 2018

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 zugegrif-fen werden $this->nenner $this->kuerze()

Andreas Schmidt PHP - Teil 2 19/29

Fakultät IWIDB & IS II - WS 2018

Objektorientierung in PHP5

• Klassenmethoden werden durch voranstellen des Schlüsselwortes static gekennzeichnet

static function losMachWas($x) { ... }

• Aufruf von Klassenmethoden:

• außerhalb der Klasse1: Klassenname::losMachWas($z1)

• innerhalb der Klasse: self::losMachWas($z2)

1. sofern erlaubt

Andreas Schmidt PHP - Teil 2 20/29

Fakultät IWIDB & IS II - WS 2018

• 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 21/29

Fakultät IWIDB & IS II - WS 2018

Objektorientierung in PHP5

• Magic Methods

• _ _construct(...): wird aufgerufen wenn ein Objekt mittels new <classname>(...) erzeugt werden soll

• _ _toString(): wird aufgerufen wenn ein Objekt mittels echo oder print ausgegeben wird

• _ _call($methodname, $parameter): wird aufgerufen, wenn keine pas-sende Methode gefunden wurde

• _ _get($property_name): wird aufgerufen, wenn kein passendes Pro-perty gefunden wurde

• _ _set($propertyname, $value): wird aufgerufen, wenn ein nichtexistie-rendes Property einen Wert zugewiesen bekommt

Andreas Schmidt PHP - Teil 2 22/29

Fakultät IWIDB & IS II - WS 2018

Magic Method Example

class MyClass { private $values = array(); function __get($prop) {

if (array_key_exists($prop, $this->values)) return $this->values[$prop]; else throw new Exception("undefined property '$prop'"); } function __set($prop, $value) { $this->values[$prop] = $value; } function __toString() { $str = "MyClass: ("; foreach ($this->values as $k=>$v) $str .= " $k : $v;"; return $str.")"; } function __call($method, $params) { $errmsg = "unknown Method ".__CLASS__."::$method(...) called"; if (substr($method, 0,3)=="get") { $property = strToLower(substr($method, 3, strlen($method)-3)); if (array_key_exists($property, $this->values))

return $this->values[$property]; else

throw new Exception($errmsg); } else throw new Exception($errmsg); }}

Methode muss mit "get" beginnen

Property muss existieren

Andreas Schmidt PHP - Teil 2 23/29

Fakultät IWIDB & IS II - WS 2018

Magic Method Examples

$v = new MyClass(); // calls __construct(...)$v->m1 = 12; // calls __set(...)$v->name = "Hanna"; $v->age = 25; print "m1: $v->m1\n"; // calls __get(...)print $v->getAge()."\n"; // calls __call(...)try { $v->setM1(56); // calls __call(...) ->error die("illegal method-call not detected\n");} catch (Exception $e) { print "illegal method-call detected\n";}print $v; // calls __string(...)print $v->xyz; // calls __get(...) ->error

Andreas Schmidt PHP - Teil 2 24/29

Fakultät IWIDB & IS II - WS 2018

nützliche PHP-Funktionen

• explode($separator, $string) -- Zerteilt einen String anhand eines Trennzei-chens

• 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 25/29

Fakultät IWIDB & IS II - WS 2018

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 26/29

Fakultät IWIDB & IS II - WS 2018

Tipps

• Verschiedene Arten von möglichen Fehlern:

• PHP-Syntax Fehler: z.B. falsche Klammerung, falsche Schreibweise bei Funk-tionen/Methoden, ...

• Beispiele:

Parse error: syntax error, unexpected '}' in .\DB-IS-2-

WS06\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 27/29

Fakultät IWIDB & IS II - WS 2018

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.phphier erfolgt keine Warnung: $a:

Notice: Undefined variable: a in C:\test\warnungen.php on line 5Hier schon: $a:

Andreas Schmidt PHP - Teil 2 28/29

Fakultät IWIDB & IS II - WS 2018

Tipps

• SQL-Fehler:

• Beispiel:[nativecode=1064 ** You have an error in your SQL syntax;

check the manual thatcorresponds to your MySQL server ver-

sion for the right syntax to use near '< 1000' at line 1]

Andreas Schmidt PHP - Teil 2 29/29

Fakultät IWIDB & IS II - WS 2018

Tipps

• HTML-Fehler:

• keine Ausgabe wegen fehlerhaftem HTML