Top Banner
Wer nutzt die PHP-Reflection API? Und für was?
42

Metaprogrammierung und Reflection

Jul 02, 2015

Download

Business

Stefan Marr
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Metaprogrammierung und Reflection

Wer nutzt die PHP-Reflection API?Und für was?

Page 2: Metaprogrammierung und Reflection

Fragen können jederzeit gestellt werden

Page 3: Metaprogrammierung und Reflection

Metaprogrammierung und Reflection

Tool-Entwicklung für und mit PHP

Stefan Marr PHP Unconference

26./27. April 2008

Page 4: Metaprogrammierung und Reflection

1. Begriffsklärung

2. Open Implementations– Metaprogrammierung und Frameworkdesign

3. Relevante Sprachfeatures von PHP

4. Reflection und Runkit für die Tool-Entwicklung

5. Zusammenfassung

Agenda

Page 5: Metaprogrammierung und Reflection

METAPROGRAMMIERUNG UND REFLECTION

Kurze Begriffsklärung zur Einleitung

Page 6: Metaprogrammierung und Reflection

Verarbeitendes SystemComputational

System

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world)

reasons aboutand acts upon

representation of/returning information about

• Daten repräsentieren Domäne• Programm beschreibt

Veränderungen• Interpreter führt Programm aus

• Domäne• Buchhaltung, Kundendaten,

Logistik, Webinhalte, …

nach [1]

Page 7: Metaprogrammierung und Reflection

Kausal verbundenes System

• Ursache-Wirkungsbeziehung zwischen System und Domäne

• Direkte wechselseitige Auswirkungen

• Regellungstechnik• Klimaanlagen• Autopiloten• …

ComputationalSystem

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world)

reasons aboutand acts upon

causally connectedrepresentation

nach [1]

Page 8: Metaprogrammierung und Reflection

Meta-System

• Spezielle Domäne: Programme• Meta-Programme und -system

arbeiten auf Basis-Programmen und -systemen

• Compiler• Code-Transformation,

Generierung• …

Base System

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world )

reasons aboutand acts upon

representation of/returning information about

Meta System

Interpreter

State(Data)

Behavior(Program )

reasons aboutand acts upon

representation of/returning information about

nach [1]

Page 9: Metaprogrammierung und Reflection

Reflektives System

• Spezielle Meta-Systeme• Selbstrepräsentation bestimmter

Strukturen• Kausal verbunden

• Reflektives Verhalten• Introspection (beobachten)• Intercession

(Selbstveränderung)

ComputationalSystem

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world )

reasons aboutand acts upon

causally connectedrepresentation

reasons aboutand acts upon

representation of/returning information about

nach [1]

Page 10: Metaprogrammierung und Reflection

Meta- und Reflektive SystemeComputational

System

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world)

reasons aboutand acts upon

representation of/returning information about

ComputationalSystem

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world)

reasons aboutand acts upon

causally connectedrepresentation

Base System

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world )

reasons aboutand acts upon

representation of/returning information about

Meta System

Interpreter

State(Data)

Behavior(Program )

reasons aboutand acts upon

representation of/returning information about

ComputationalSystem

Interpreter

State(Data)

Behavior(Program )

Domain(some part of the world )

reasons aboutand acts upon

causally connectedrepresentation

reasons aboutand acts upon

representation of/returning information about

Kausal verbunden

Meta-System

Reflektiv

nach [1]

Page 11: Metaprogrammierung und Reflection

OPEN IMPLEMENTATIONSMetaprogrammierung und Moduldesign

Page 12: Metaprogrammierung und Reflection

• Verstecken von Implementierungsdetails– Vereinfachung des Client-

Codes• Verringerung von

Abhängigkeiten zwischen Modulen und Clients– Erhöhung der

Wiederverwendbarkeit– Client-Code lesbarer und

verständlich ohne Wissen über unterliegende Implementierung

Abstraktion in einer Black Box

Page 13: Metaprogrammierung und Reflection

• Geeignete Implementierungsstrategie abhängig von der Art der Nutzung des Moduls

• Implementierungs-entscheidungen – selten dokumentiert– für bestimmte Fälle

ungeeignet– nicht anpassbar– zu starke Abstraktion

• Client weiß meist am besten welche Strategie geeignet wäre

Probleme der Black Box

Page 14: Metaprogrammierung und Reflection

• Implementierungs-entscheidungen nicht im Interface sichtbar, aber:– Performanceauswirkungen

• Abbildung von High-Level auf Low-Level Funktionen vielfältig möglich– Beeinflussen Performance– Entscheidung daher

feststehend, aber nicht verborgen

Keine 100%ige Black Box möglich

Page 15: Metaprogrammierung und Reflection

• Neuimplementierung von Interfacefunktionen– Um gewünschte Eigenschaften zu

erreichen– Code wird größer und komplexer

• „Code zwischen den Zeilen“– Behandelt Probleme die eigentlich

vom Interface verborgen werden sollten

– Basiert auf undokumentierten Interna, verborgen vom Interface, aber dem Programmierer bekannt

Probleme und Workarounds

Page 16: Metaprogrammierung und Reflection

Lösung: Reflektive Module

Basis Interface

• Bietet Funktionalität an

• Das WASMeta Interface• Ermöglicht Steuerung

des Basis Interfaces• Das WIE

Page 17: Metaprogrammierung und Reflection

Reflektive Module/Programme

• Vorteile– Schnittstellennutzung

jetzt wieder als Black Box– Konfiguration bzw.

Implementierungsstrategie der Black Box vom Client wählbar

• Programmierer können sich auf Modulnutzung konzentrieren

• Optimierung/Konfiguration separat möglich

Page 18: Metaprogrammierung und Reflection

• Frameworks– Aufteilung in Client API und Framework API

– Konfigurationsdateien, Konstanten, Parameter, Flags, …

• Dependency Injection als Pattern verbreitet

• Funktionen mit Callbacks altbekannt

Umsetzungsmöglichkeiten

Page 19: Metaprogrammierung und Reflection

• Frameworks sollten Erweiterungs- bzw. Spezialisierungspunkte anbieten– Problematische Teile vom Client anpassbar

• Anpassung, Konfiguration über Meta-APIs

• Design trotzdem nicht mit den zu kapselnden Details überfrachten– Auf geeignete Trennung zwischen WAS und WIE

achten

ZusammenfassungOpen Implementations

Page 20: Metaprogrammierung und Reflection

RELEVANTE SPRACHFEATURES VON PHP

Magic Methods und die Reflection API

Page 21: Metaprogrammierung und Reflection

• Dynamische Object-Properties– __g e t ( ) , __s e t ( )

• Werden verwendet wenn die angefragten Properties nicht vorhanden sind

• z. B. für Validierung und Vermeidung von unspezifizierten Properties

• __i s s e t ( ) , __u n s e t ( )

• __c l o n e ( ) : ändert Semantik von c l o n e• __t o S t r i n g ( ) , __s l e e p ( ) ,

__wa k e u p ( ) , __s e t _s t a t e ( )

Magic Methods

Page 22: Metaprogrammierung und Reflection

• __a u t o l o a d ( $ c l a s s Na me )– Ermöglicht echtes Lazy-loading von Klassen

– Implementiert eigene Laderoutine

• __c a l l ( $ me t h o d Na me , $ a r g s )– Ermöglicht echtes Late-Binding

– Instanzverhalten zur Laufzeit entscheidbar

• __c a l l S t a t i c ( $ me t h o d Na me , $ a r g s )– La t e - Bi n d i n g f ü r Kl a s s e n me t h o d e n

Magic Methods

Page 23: Metaprogrammierung und Reflection

Reflection APIKlassendiagramm der Reflection API von PHP 5.2

+getName() : string+isPublic () : bool+isPrivate() : bool+isProtected() : bool+isStatic () : bool+isDefault() : bool+getModifiers() : int+getValue(in object : object) : mixed+setValue(in object : object, in value : mixed)+getDeclaringClass() : ReflectionClass+getDocComment() : string

ReflectionProperty

+getName() : string+isInternal() : bool+isUserDefined() : bool+isInstantiable () : bool+hasConstant(in name : string) : bool+hasMethod(in name : string) : bool+hasProperty(in name : string) : bool+getFileName() : string+getStartLine() : int+getEndLine() : int+getDocComment() : string+getConstructor() : ReflectionMethod+getMethod(in name : string) : ReflectionMethod+getMethods() : ReflectionMethod[]+getProperty(in name : string) : ReflectionProperty+getProperties() : ReflectionProperty[]+getConstants() : array+getConstant(in name : string) : mixed+getInterfaces() : ReflectionClass[]+isInterface() : bool+isAbstract() : bool+isFinal() : bool+getModifiers() : int+isInstance(in object : object) : bool+newInstance(in args : mixed) : object+newInstanceArgs(in args : array) : object+getParentClass() : ReflectionClass+isSubclassOf (in class : ReflectionClass) : bool+getStaticProperties() : array+getStaticPropertyValue(in name : string, in default : mixed = null) : mixed+setStaticPropertyValue(in name : string, in value : mixed)+getDefaultProperties() : array+isIterateable() : bool+implementsInterfaces(in name : string) : bool+getExtension() : ReflectionExtension+getExtensionName() : string

ReflectionClass

ReflectionObject

+invoke(in object : object, in ... : mixed) : mixed+invokeArgs(in object : object, in args : mixed) : mixed+isFinal() : bool+isAbstract() : bool+isPublic () : bool+isPrivate() : bool+isProtected() : bool+isStatic () : bool+isConstructor() : bool+isDestructor() : bool+getModifiers() : int+getDeclaringClass() : ReflectionClass

ReflectionMethod

+getName() : string+isPassedByReference() : bool+getDeclaringClass() : ReflectionClass+getClass() : ReflectionClass+isArray() : bool+allowsNull() : bool+isPassedByReference() : bool+isOptional () : bool+isDefaultValueAvailable () : bool+getDefaultValue() : mixed

ReflectionParameter

+getName() : string+getVersion() : string+getFunctions() : ReflectionFunction[]+getConstants() : array+getINIEntries() : array+getClasses() : ReflectionClass[]+getClassNames() : array+info() : string

ReflectionExtension

+getName() : string+isInternal() : bool+isDisabled() : bool+isUserDefined() : bool+getFileName() : string+getStartLine() : int+getEndLine() : int+getDocComment() : string+getStaticVariables() : array+invoke(in args : mixed, in ... : mixed) : mixed+invokeArgs() : mixed+returnsReference() : bool+getParameters() : ReflectionParameter[]+getNumberOfParameters() : int+getNumberOfRequiredParameters() : int

ReflectionFunction

func_get_arg()func_get_args()func_num_args()is_subclass_of()get_parent_class()get_class()get_class_methods()get_object_vars()get_class_vars()class_exists()interface_exists()function_exists()method_exists()property_exists ()get_declared_classes()get_declared_interfaces()get_included_files()get_required_files()ini_set()ini_get()get_defined_constants()get_defined_functions()get_defined_vars()call_user_func()call_user_func_array()create_function()eval()

<<functions>>

Page 24: Metaprogrammierung und Reflection

ReflectionPropertyReflectionClass

ReflectionObject

ReflectionMethod

ReflectionParameter

ReflectionExtension

func_get_arg()func_get_args()func_num_args()is_subclass_of()get_parent_class ()get_class()get_class_methods()get_object_vars()get_class_vars()class_exists()interface_exists()function_exists()method_exists()property_exists ()get_declared_classes()get_declared_interfaces()get_included_files()get_required_files()ini_set()ini_get()get_defined_constants()get_defined_functions()get_defined_vars()call_user_func()call_user_func_array()create_function()eval()

<<functions>>

ReflectionFunction

Page 25: Metaprogrammierung und Reflection

ReflectionPropertyReflectionClass

ReflectionObject

ReflectionMethod

ReflectionParameter

ReflectionExtension

func_get_arg()func_get_args()func_num_args()is_subclass_of()get_parent_class()get_class()get_class_methods()get_object_vars()get_class_vars()class_exists()interface_exists()method_exists ()property_exists()get_declared_classes ()get_declared_interfaces()get_included_files()get_required_files()ini_set()ini_get()get_defined_constants()get_defined_functions()get_defined_vars()

<<functions>>

ReflectionFunction

PHP System Runtime Data

ReflectionPHP Core

Classes Objects ...

PH

P V

irtu

al M

achi

ne

with

Sys

tem

Lev

el E

xte

nsio

ns

Page 26: Metaprogrammierung und Reflection

REFLECTION UND RUNKIT FÜR DIE TOOL-ENTWICKLUNG MIT PHP

phpCrow, ezcReflection und isvcRunkit

Page 27: Metaprogrammierung und Reflection

splash

Page 28: Metaprogrammierung und Reflection

• Generierten Code ausführen: e v a l ( )

• Funktionen erstellen: c r e a t e _f u n c t i o n ( )

• Dynamische Aufrufe:– c a l l _u s e r _f u n c t i o n ( )– c a l l _u s e r _f u n c t i o n _a r r a y ( )– c a l l _u s e r _me t h o d ( )– c a l l _u s e r _me t h o d _a r r a y ( )– $ f u n c t i o n Na me ( $ a , $ b ) ;

Intercession mit Standard-PHP

Page 29: Metaprogrammierung und Reflection

$ f u n c = c r e a t e _f u n c t i o n ( ' $ f o o , $ b a r ' ,' e c h o " Cr e a t e d F u n c t i o n : $ f o o

$ b a r \n " ; ' ) ;$ f u n c ( ' He l l o ' , ' Wo r l d ! ' ) ;v a r _d u mp ( a d d s l a s h e s ( $ f u n c ) ) ;c a l l _u s e r _f u n c ( $ f u n c , ' F OO' , ' b a z ' ) ;

/ / c o mmo n us ag e e xampl e , wi t h pe r f o r manc e i s s ue s !$ a v = a r r a y ( ' t h e ' , ' a ' , ' t h a t ' , ' t h i s ' ) ;a r r a y _wa l k ( $ a v ,

c r e a t e _f u n c t i o n ( ' &$ v , $ k ' , ' $ v = $ v . " ma n g o " ; ' ) ) ;

p r i n t _r ( $ a v ) ;

create_function

Page 30: Metaprogrammierung und Reflection

c l a s s I n v o k e Te s t {p u b l i c f u n c t i o n c a l l Me ( ) {

e c h o " Ye a h , y o u c a l l e d me ! \n " ;}

}

$ o = n e w I n v o k e Te s t ( ) ;$ c l a s s = n e w Re f l e c t i o n Cl a s s ( $ o ) ;$ me t h o d = $ c l a s s - >g e t Me t h o d ( ' c a l l Me ' ) ;$ me t h o d - >i n v o k e ( $ o ) ;

f u n c t i o n f o o F u n c ( $ b a r ) {e c h o " $ b a r \n " ;

}$ f u n c = ' f o o F u n c ' ;$ f u n c ( ' He l l o Wo r l d ' ) ;

Funktionen/Methoden Aufrufe

Page 31: Metaprogrammierung und Reflection

+getAnnotations()+hasAnnotation()+getType()

ezcReflectionProperty

+getAnnotations()+hasAnnotation()

ezcReflectionClass

+getAnnotations()+hasAnnotation()+getReturnType()+isMagic()+isInherited()+isOveridden()+isIntroduced()

ezcReflectionMethod

+getType()

ezcReflectionParameter

ezcReflectionClassType

«interface»ezcReflectionType

ezcReflectionAbstractType

ezcReflectionPrimitiveType ezcReflectionArrayType

ReflectionProperty ReflectionClass ReflectionMethod ReflectionParameter

ezcReflection

Page 32: Metaprogrammierung und Reflection

+getAnnotations()+hasAnnotation()+getType()

ezcReflectionProperty

+getAnnotations()+hasAnnotation()

ezcReflectionClass

+getAnnotations()+hasAnnotation()+getReturnType()+isMagic()+isInherited()+isOveridden()+isIntroduced()

ezcReflectionMethod

+getType()

ezcReflectionParameter

ezcReflectionClassType

«interface»ezcReflectionType

ezcReflectionAbstractType

ezcReflectionPrimitiveType ezcReflectionArrayType

ReflectionProperty ReflectionClass ReflectionMethod ReflectionParameter

ezcReflection

Page 33: Metaprogrammierung und Reflection

+getAnnotations()+hasAnnotation()+getType()

ezcReflectionProperty

+getAnnotations()+hasAnnotation()

ezcReflectionClass

+getAnnotations()+hasAnnotation()+getReturnType()+isMagic()+isInherited()+isOveridden()+isIntroduced()

ezcReflectionMethod

+getType()

ezcReflectionParameter

ezcReflectionClassType

«interface»ezcReflectionType

ezcReflectionAbstractType

ezcReflectionPrimitiveType ezcReflectionArrayType

ReflectionProperty ReflectionClass ReflectionMethod ReflectionParameter

ezcReflection

Page 34: Metaprogrammierung und Reflection

ezcReflection

PHP Core Functions Reflection API

PHP System Runtime DataClasses Objects ...

PH

P V

M

ezcReflection

+getAnnotations()+hasAnnotation()+getType()

ezcReflectionProperty

+getAnnotations()+hasAnnotation()

ezcReflectionClass

+getAnnotations()+hasAnnotation()+getReturnType()+isMagic()+isInherited()+isOveridden()+isIntroduced()

ezcReflectionMethod

+getType()

ezcReflectionParameter

ezcReflectionClassType

«interface»ezcReflectionType

ezcReflectionAbstractType

ezcReflectionPrimitiveType ezcReflectionArrayType

ReflectionProperty ReflectionClass ReflectionMethod ReflectionParameter

PH

P L

angu

age

Leve

l Im

ple

men

tatio

ns

Page 35: Metaprogrammierung und Reflection

ezcReflection Überblick

• Ermöglicht Reflection auf PHPDoc-Annotationen

• Erweiterte Typ-Informationen zur Laufzeit

• Aber keine direkten Laufzeit-Einflüsse der Typ-Annotationen

• Design ermöglicht beliebige Erweiterungen der Reflection API als Datenquelle mit zu nutzen– z. B. eine StaticReflection

• Genutzt für z. B. WSDL Generierung

Page 36: Metaprogrammierung und Reflection

/ * ** @we bs e r v i c e* /c l a s s He l l o Wo r l d {

/ * ** @var s t r i ng* /p r i v a t e $ h e l l o = ' He l l o ' ;/ * ** @par am s t r i ng $ name* @r e t ur n s t r i ng* @we bme t ho d* /p u b l i c f u n c t i o n g e t Gr e e t i n g ( $ n a me ) {

r e t u r n " $ t h i s - >h e l l o $ n a me ! " ;}

}

Annotationen

Page 37: Metaprogrammierung und Reflection

Intercession mit Runkit

func_get_arg()func_get_args()func_num_args()is_subclass_of()get_parent_class()get_class()get_class_methods()get_object_vars()get_class_vars()class_exists()interface_exists()method_exists ()property_exists()get_declared_classes()get_declared_interfaces()get_included_files()get_required_files()ini_set()ini_get()get_defined_constants()get_defined_functions()get_defined_vars()

<<functions>>

PHP System Runtime Data

ReflectionPHP Core

Classes Objects ...

PH

P V

irtu

al M

achi

ne

with

Sys

tem

Lev

el E

xte

nsio

ns

runkit_class_adopt()runkit_class_emancipate()runkit_constant_add()runkit_constant_redefine()runkit_constant_remove()runkit_function_add()runkit_function_copy()runkit_function_redefine()runkit_function_remove()runkit_function_rename()runkit_import()runkit_lint_file()runkit_lint()runkit_method_add()runkit_method_copy()runkit_method_redefine()runkit_method_remove()runkit_method_rename()runkit_return_value_used()runkit_sandbox_output_handler()runkit_superglobals()

<<functions>>

Runkit

Page 38: Metaprogrammierung und Reflection

ezcReflection und isvcRunkit

PHP Core Functions

PHP System Runtime DataClasses Objects ...

PH

P V

M

isvcRunkit

+emancipate()+setParentClass()+addNewMethod()+addExistingMethod()+removeMethod()

isvcRunkitClass

+getCode()+setCode()+delete()+setName()

isvcRunkitMethod

ReflectionClass ReflectionMethod

Lang

uage

Le

vel I

mp

lem

ent

atio

ns

Reflection API Runkit Extension

ezcReflection

Page 39: Metaprogrammierung und Reflection

ZUSAMMENFASSUNGMetaprogramming und Reflection

Page 40: Metaprogrammierung und Reflection

• PHP hat viele Features um Reflection einzusetzen

• Intercession über Runkit-Extension– Vorallem für Tool-Entwicklung

• Reflection hat Einflüsse auf Performance– PHP Ausführungsmodell beachten

– Besonders in Web-Anwendungen nicht erste Wahl

• Nützlich für länger lebende Prozesse/Programme– z. B. GTK+, QT, MFC oder Kommandozeilen-

Anwendungen

Zusammenfassung

Page 41: Metaprogrammierung und Reflection

Literatur

Paper zu diesem VortragG. GABRYSIAK, S. MARR, AND F. MENGE, Meta Programming and Reflection in PHP, Hasso-Plattner Institute, Universiy of Potsdam, Germany, February 2008. https://instantsvc.svn.sourceforge.net/svnroot/instantsvc/branches/metaprogramming/doc/

Der CodephpCrow – A PHP-PHP-IDE, February 2008.

https://instantsvc.svn.sourceforge.net/svnroot/instantsvc/branches/metaprogramming/src/MetaPHP

ezcReflection, SVN Repository, eZ Components, January 2008. http://svn.ez.no/svn/ezcomponents/experimental/Reflection

Page 42: Metaprogrammierung und Reflection

Weitere Literatur und Software

[1] R. HIRSCHFELD, Course on "Metaprogrammierung und Reflection", 2007. Lecture Material, Non-public.

[2] G. BRACHA AND D. UNGAR, Mirrors: design principles for meta-level facilities of object-oriented programming languages, in OOPSLA '04: Proceedings of the 19th annual ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications, New York, NY, USA, 2004, ACM, pp. 331–344.

[3] S. GOLEMON, Runkit, PHP Extension, The PHP Group, January 2008. http://pecl.php.net/package/runkit

[4] A. P. GREGOR KICZALES, Open Implementations and Metaobject Protocols, MIT Press, Cambridge, MA, USA, 1996. http://www2.parc.com/csl/groups/sda/publications/papers/Kiczales-TUT95/for-web.pdf

[5] PHP DOCUMENTATION GROUP, PHP Manual, documentation, November 2007. http://www.php.net/manual/en/language.oop5.reflection.php

[6] THE PHP GROUP, PHP Extension Community Library, Project Site, January 2008. http://pecl.php.net/