Giessen R Users Group - 1. Workshop SEM mit lavaan
Web Entwicklung mit PHP - Teil 2
1. PHP
Personal Homepage Tools - Hypertext Preprocessor
Programmieren für das Web
Teil 2 - Objektorientierung
Version: 2012-04-22
License: CC BY NC SA
Erstellt von Hans-Joachim Piepereit (hajo_p@live.de)
Konstruktives Feedback hierzu ist gern gesehen
3. 1 Strukturierung
1.1 Namensräume
- Verhindern Namenskollisionen zwischen Klassen, Interfaces, usw.
- Verwenden als Start und Trennzeichen einen Backslash
- Schwächere Form von Java Packages, keine Existenzprüfungen
- Sprachelemente (z.b. "default") nicht erlaubt und PHP reserviert
- Hilfreich beim Abbilden einer Pfadstruktur (siehe Autoloading)
1 <?php
2 // S e t z e den Namensraum e i n e r Datei
3 namespace d i e s i s t e i n t e s t ;
4 // A l t e r n a t i v e Syntax d i e mehrere j e Datei e r l a u b t
5 namespace d i e s i s t e i n t e s t {
6 f u n c t i o n abc ( ) { r e t u r n 1 ; }
7 }
3
4. Möglichkeiten der Verwendung von Namensräumen
1 <?php // Nutze e i n e n Namensraum beim Aufruf
2 echo d i e s i s t e i n t e s t abc ( ) ;
3
4 // S e l b i g e s mit vorherigem Import
5 use d i e s i s t e i n t e s t abc ;
6 echo abc ( ) ;
7
8 // Es g i b t auch e i n e n A l i a s Import
9 use d i e s i s t e i n t e s t as t e s t 2 ;
10 echo t e s t 2 abc ( ) ;
11
12 // Der g l o b a l e Namespace der PHP F e a t u r e s i s t
13 echo time ( ) ;
14 // Der a k t u e l l e Namespace kann z .B. so a b g e r u f e n werden
15 echo __NAMESPACE__;
4
5. 1.2 Klassen
Beispiel
1 <?php
2 // E r s t e l l e e i n e neue K l a s s e
3 class test {
4
5 // D e f i n i e r e e i n i n t e r n e s A t t r i b u t
6 p r i v a t e $_attr = ' abc ' ;
7
8 // Funktionen s i n d d i e Methoden von Klassen
9 p u b l i c f u n c t i o n fun ( )
10 {
11 // Rufe das A t t r i b u t a u f
12 return $this− >_attr ;
13 }
14 }
5
6. Konstruktor
- Ist per __construct() definierbar (seit PHP 5.3.3 einziger Weg)
- Keine Pflicht und keine Automatisierung für geerbe Konstruktoren
- Das aus Java bekannte super() geht in PHP per parent::__construct()
- Es ist je Klasse nur ein eigener bzw. aktiver Konstruktor erlaubt
1 <?php
2 // E r s t e l l e e i n e neue K l a s s e
3 class test {
4
5 // D i e s e s Mal mit einem Konstruktor
6 f u n c t i o n __construct ( ) {
7
8 echo ' Return Werte machen h i e r wenig Sinn ' ;
9 }
10 }
6
7. Vererbung
- PHP besitzt keine Lösung für das Diamond Problem
- Klassen können daher nur von einer anderen Klasse erben
1 <?php
2 // Erbe von der K l a s s e t e s t
3 c l a s s extendedtest extends t e s t {
4
5 // E r s e t z e den Konstruktor mit einem e i g e n e n
6 f u n c t i o n __construct ( ) {
7 echo ' t e s t ' ;
8
9 // Rufe den Konstruktor der Basis−K l a s s e a u f
10 p a r e n t : : __construct ( ) ;
11 }
12 }
7
8. Autoloading
- Spart include und require Befehle im Quelltext ein
- Die Funktion __autoload besser nicht mehr dafür verwenden
- spl_autoload_register() nimmt beliebig viele Autoloader auf
- Eingeschränkte Funktionalität in den CLI Modi beachten
1 <?php // D e f i n i e r e e i n e n minimalen Autoloader
2 function autoload_test ( $ c l a s s )
3 {
4 i n c l u d e ' b a s i s / pfad / ' . $ c l a s s . ' . php ' ;
5 }
6
7 // S e t z e den Autoloader zu e v e n t u e l l schon anderen hinzu
8 spl_autoload_register ( ' autoload_test ' ) ;
9 // E r s t e l l e e i n Objekt e i n e r b i s h e r unverwendeten K l a s s e
10 $ t e s t = new d i e s i s t e i n Test ( ) ;
8
9. 1.3 Interfaces
- Erlauben das Definieren der angebotenen Schnittstelle von Klassen
- Interfaces können wie auch Klassen voneinander Erben
- Klassen können mehrere Interfaces zugleich implementieren
- Namenskonflikte werden nicht aufgelöst, führen also zu Fehlern
1 <?php
2 // E r s t e l l e e i n I n t e r f a c e
3 i n t e r f a c e test1 { };
4
5 // Noch e i n I n t e r f a c e
6 i n t e r f a c e t e s t 2 extends t e s t 1
7 {
8 // Verlange e i n e Methode
9 p u b l i c f u n c t i o n r e q ( $abc ) ;
10 }
9
10. 2 Einsatz und Erweiterungen
2.1 Nutzung von Klassen
- Paamayim Nekudotayim (::) erlaubt statischen Methodenaufruf
- Echte Objekte werden dagegen per new Klassenname() erzeugt
- Die Objektmethoden ruft man per $object->methode() auf
1 <?php // Hole e i n e v a l i d e Z e i t z o n e ab
2 $dtz = new DateTimeZone ( ' Europe / B e r l i n ' ) ;
3
4 // Hole d i e a k t u e l l e Unix Z e i t d i e s e r Z e i t z o n e ab
5 $ c f f = DateTime : : createFromFormat ( 'U ' , time ( ) , $dtz ) ;
6
7 // Gebe das Datum i n l e s b a r e r Form aus
8 echo $ c f f −>format ( 'Y −d H: i : s ' ) ;
−m
9 /∗ Jahr−Monat−Tag Stunden : Minuten : Sekunden ∗/
10
11. 2.2 Formale Parameter
Pflichtangaben
- Durch setzen eines Startwertes werden diese Optional
- Übergabepflicht bis inklusive dem letzten nicht Optionalen
1 <?php
2 // Eine neue K l a s s e
3 class test5
4 {
5 // Methode d i e zwischen 3 und 4 Parameter v e r l a n g t
6 p u b l i c f u n c t i o n e f g ( $one , $two = 1 , $ t h r e e , $ f o u r = 0)
7 {
8 r e t u r n $one . $two . $ t h r e e . ' − ' . $ f o u r ;
9 }
10 }
11
12. Typisierung
- Alle Klassen können als Objekttyp erzwungen werden
- Dabei sind, falls vorhanden, die Namensräume passend anzugeben
- Bei den Basistypen werden nur Arrays unterstützt
1 <?php // Eine neue K l a s s e
2 class test7
3 {
4 // Verlange f o r m a l e Parameter von einem Typ
5 p u b l i c f u n c t i o n e f g ( DateTime $dte , a r r a y $ a r r a y )
6 {
7 // L i e f e r e Array mit Unix Z e i t an d e s s e n Ende
8 $ a r r a y [ ] = $dte− >getTimestamp ( ) ;
9 return $array ;
10 }
11 }
12
13. 2.3 Schlüsselwörter
Sichtbarkeit
public Standard, greift wenn ausgelassen
protected Jeweilige Klasse und bei Vererbung
private Nur in der jeweiligen Klasse
Zielbereich
parent::$var "parent" verwendet die Elternklasse
self::$var "self" verwendet die aktuelle Klasse
$this->var "this" verwendet das aktuelle Exemplar
- Bei "parent" wird passend aus der Elternklasse aufgerufen
- Die Aufrufe an "self" sind statisch, siehe :: Operator
- Dagegen kann "this" nur dynamisch in Objekten verwendet werden
13
14. Abstract
- Abstract verhindert das Erzeugen von Exemplaren einer Klasse
- Erzwingt bei Methoden deren Signatur für davon erbende Klassen
- Achtung: Dies trifft auf den Konstruktor erst seit PHP 5.4 zu
1 <?php
2 // Keine Objekte von der K l a s s e e r z e u g b a r
3 abstract class test9
4 {
5 // Muss b e i Vererbung i m p l e m e n t i e r t werden
6 a b s t r a c t p u b l i c f u n c t i o n uvw ( $x , $y , $z ) ;
7
8 // Methoden mit I n h a l t s i n d w e i t e r h i n e r l a u b t
9 p r o t e c t e d f u n c t i o n abc ( ) { echo ' t e s t ' ; }
10 }
14
15. Final
- Das Erben von als Final markierten Klassen ist nicht möglich
- Das Überschreiben von als Final markierten Methoden ist verboten
Static
- Static Variablen behalten zwischen Aufrufen ihren je letzten Wert
- Bei Attributen in Klassen verhält sich dies exakt genauso
- Mit Static markierte Methoden sind per :: Operator nutzbar
1 <?php // Kein Erben von d i e s e r K l a s s e e r l a u b t
2 f i n a l c l a s s area51
3 {
4 // D i e s e Funktion kann s t a t i s c h verwendet werden
5 p u b l i c s t a t i c f u n c t i o n i n c ( $ i n t ) { r e t u r n ++$ i n t ; }
6 }
15
16. 2.4 Fehlerbehandlung
Errors
- Der gesamte prozedural aufgebaute PHP Kern verwendet Errors
- Ausgabe per display_errors an- und abschaltbar
- Detaillevel per error_reporting() einstellbar
1 <?php // Z e i g e a l l e F e h l e r an
2 ini_set ( ' display_errors ' , true ) ;
3 e r r o r _ r e p o r t i n g (E_ALL) ;
4
5 // Z e i g e k e i n e F e h l e r an
6 ini_set ( ' display_errors ' , f a l s e ) ;
7 error_reporting (0) ;
8
9 // V e r s t e c k e a u f t r e t e n d e F e h l e r ( b i t t e vermeiden )
10 @file_get_contents ( ' t e s t . txt ' ) ;
16
17. Exceptions
- Werden mit der Throw Anweisung geworfen
- Sollten mit Try / Catch Blöcken gefangen werden
1 <?php // Teste das Werfen und Fangen von Ausnahmen
2 class test42
3 {
4 public s t a t i c function ghi ()
5 {
6 throw new Exception ( ' h i e r geht etwas n i c h t ' ) ;
7 }
8 }
9
10 try { test42 : : ghi () ; }
11 c a t c h ( Exception $e )
12 { echo $e− >getMessage ( ) ; }
17
18. Exception Details
- Ungefangene Ausnahmen brechen die weitere Ausführung ab
- Try/Catch besitzt kein Finally (wird in PHP auch nicht benötigt)
- Man kann eigene Exception Klassen erstellen bzw. davon erben
Errors als Exceptions behandeln
1 <?php // E r s t e l l e e i n e e i g e n e Fehlerbehandlung
2 f u n c t i o n fehler_als_ausnahme ( $nr , $ s t r , $ f i l e , $ l i n e )
3 {
4 // Weniger schwere E r r o r s a l s E r r o r E x c e p t i o n verwenden
5 $e = new E r r o r E x c e p t i o n ( $ s t r , $nr ,0 , $ f i l e , $ l i n e ) ;
6 // J e t z t kann d i e Ausnahmebehandlung damit a r b e i t e n
7 meine_ausnahmebehandlung ( $e ) ;
8 }
9 s e t _ e r r o r _ h a n d l e r ( ' fehler_als_ausnahme ' ) ;
18
19. 3 Beispielscript: PDO mit SQLite
1 <?php // V e r b i n d u n g s d e t a i l s b e i F e h l e r v e r s t e c k e n
2 try {
3 $con = new PDO( ' s q l i t e : t e s t . s q l i t e ' ) ;
4 }
5 c a t c h ( PDOException $e ) {
6 $ e r r o r = $e− >getMessage ( ) ;
7 }
8 // E r s t e l l e e i n e neue T a b e l l e
9 $query = 'CREATE TABLE IF NOT EXISTS t e s t ( t_id i n t e g e r , '
10 . ' t_name v a r c h a r ( 4 0 ) , PRIMARY KEY ( t_id ) ) ' ;
11 $prepared = $con− r e p a r e ( $query ) ;
>p
12 $check = $prepared− x e c u t e ( ) ;
>e
13 i f ( empty ( $check ) ) { $ e r r o r = $prepared− r r o r I n f o ( ) [ 2 ] ; }
>e
14
15 // Gebe e i n e E r f o l g s m e l d u n g oder den F e h l e r aus
16 echo empty ( $ e r r o r ) ? ' t a b e l l e a n g e l e g t ' : $ e r r o r ;
19
20. 17
18
19 // Trage e i n e n Datensatz e i n
20 $ c o n t e n t = a r r a y ( ' : v1 ' => ' f i r s t ' ) ;
21 $query = "INSERT INTO t e s t ( t_name ) VALUES ( : v1 ) " ;
22 $prepared = $con− r e p a r e ( $query ) ;
>p
23 $check = $prepared− x e c u t e ( $ c o n t e n t ) ;
>e
24 i f ( empty ( $check ) ) { $ e r r o r = $prepared− r r o r I n f o ( ) [ 2 ] ; }
>e
25
26 // Gebe e i n e E r f o l g s m e l d u n g oder den F e h l e r aus
27 echo empty ( $ e r r o r ) ? ' e i n t r a g 1 a n g e l e g t ' : $ e r r o r ;
28
29 // Trage noch e i n e n Datensatz e i n
30 $ c o n t e n t = a r r a y ( ' : v1 ' => ' second ' ) ;
31 $check = $prepared− x e c u t e ( $ c o n t e n t ) ;
>e
32 i f ( empty ( $check ) ) { $ e r r o r = $prepared− r r o r I n f o ( ) [ 2 ] ; }
>e
33
34 // Gebe e i n e E r f o l g s m e l d u n g oder den F e h l e r aus
35 echo empty ( $ e r r o r ) ? ' e i n t r a g 2 a n g e l e g t ' : $ e r r o r ;
20
21. 36
37
38 // Lese den E i n t r a g mit dem I n h a l t f i r s t aus
39 $ c o n t e n t = a r r a y ( ' : v1 ' => ' f i r s t ' ) ;
40 $query = "SELECT ∗ FROM t e s t WHERE t_name = : v1 LIMIT 1 " ;
41 $prepared = $con− r e p a r e ( $query ) ;
>p
42 $check = $prepared− x e c u t e ( $ c o n t e n t ) ;
>e
43 i f ( empty ( $check ) ) { $ e r r o r = $prepared− r r o r I n f o ( ) [ 2 ] ; }
>e
44
45 // Gebe den F e h l e r oder d i e ID aus
46 i f ( empty ( $ e r r o r ) ) {
47 // Hole d i e a n g e f r a t e n Daten ab
48 $ r e s u l t = $prepared− e t c h (PDO : : FETCH_ASSOC) ;
>f
49 echo ' ID von " f i r s t " : ' . $ r e s u l t [ ' t_id ' ] ;
50 }
51 else {
52 echo $ e r r o r ;
53 }
21
22. 4 Anhang
4.1 Verweise und Empfehlungen
Websites zu den Themen
http://www.php.net/oop PHP Manual (OOP Bereich)
http://www.php.net/pdo PHP Manual (PDO Bereich)
Bücher zu den Themen
Objektorientierte Programmierung in PHP 5 Franzis Blau
Webanwendungen mit PHP und MySQL O’Reilly
Interessante Community Websites
http://www.it-republik.de/php http://www.phpmaster.com
http://www.phpdeveloper.org http://www.planet-php.net
http://www.phphatesme.com http://www.stackoverflow.com/tags/php
22