{"id":247,"date":"2010-11-20T18:24:09","date_gmt":"2010-11-20T17:24:09","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=247"},"modified":"2010-11-26T23:27:56","modified_gmt":"2010-11-26T22:27:56","slug":"reflection-teil-1-reflectionclass","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/reflection-teil-1-reflectionclass\/","title":{"rendered":"Reflection &#8211; Teil 1: ReflectionClass"},"content":{"rendered":"<h3>Was ist Reflection<\/h3>\n<p>Eines der coolsten Features in PHP, was leider so gut wie ohne Dokumentation dasteht. Reflection ist eine M\u00f6glichkeit, Meta Informationen \u00fcber so ziemlich alles in PHP herauszubekommen. Welche Interfaces implementiert eine Klasse? Welche Methoden hat sie? Wieviele Parameter hat eine Funktion \/ Methode, davon wieviele optionale? Was ist der Default-Wert eines Parameters? Dies und einiges mehr ist wohl nur mit der Reflection herauszubekommen.<\/p>\n<h3>Arten der Reflection<\/h3>\n<p>Oben habe ich mit meinen Fragen bereits die Grundbereiche der Reflection erschlagen. Was ist nun wie reflektierbar?<\/p>\n<ul>\n<li><i>ReflectionClass<\/i> &#8211; Liefert Infos \u00fcber Klassen<\/li>\n<li><i>ReflectionObject<\/i> &#8211; Im Prinzip wie die ReflectionClass, nur das der Angriffspunkt nicht die ganze Klasse, sondern eine Instanz dieser ist.<\/li>\n<li><i>ReflectionFunction<\/i> &#8211; Liefert Infos \u00fcber Funktionen<\/li>\n<li><i>ReflectionMethod<\/i> &#8211; Wie ReflectionFunction, nur mit zus\u00e4tzlichen &#8211; methodenspezifischen &#8211; Infos wie den Zugriffstyp (private? abstract? final? &#8230;)<\/li>\n<li><i>ReflectionParameter<\/i> &#8211; Liefert Infos \u00fcber Funktions- und Methodenparameter<\/li>\n<li><i>ReflectionProperty<\/i> &#8211; Liefert Infos \u00fcber Klassen-Attribute (private? static? Default-Wert? &#8230;)<\/li>\n<\/ul>\n<p>Diesen Klassen widme ich mich nun also in der mehrteiligen Reihe. Los gehts direkt in diesem <b>Teil 1<\/b> mit der ReflectionClass (ReflectionObject schenke ich mir), sodass dann in <b>Teil 2<\/b> ReflectionFunction und ReflectionMethod gemeinsam behandelt werden. <b>Teil 3<\/b> wird sich um die ReflectionParameter handeln. Schlie\u00dfen wird die Serie mit <b>Teil 4<\/b> und dem ReflectionProperty. Zu erwarten sind jede Menge Code-Beispiele.\n<\/p>\n<h3>ReflectionClass<\/h3>\n<p>Starten werde ich mit einer &#8222;Grundinfrastruktur&#8220;, die ihr euch bitte genau anschaut. Darauf wird dann ein gro\u00dfer Teil der Codebeispiele dieses Teils basieren. Es sieht erstmal viel aus, ist vom Aufbau her aber total simpel. Es ist einfach nur m\u00f6glichst viel an Sprachkonstrukten verwendet worden.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\ninterface ITest{}\r\n\r\nclass A implements ITest\r\n{\r\n\t\/\/constants\r\n\tconst A_Const1 = &quot;A_Const1&quot;;\r\n\tconst A_Const2 = &quot;A_Const2&quot;;\r\n\t\r\n\t\/\/properties\r\n\tprivate $A_Private = &quot;A_Private&quot;;\r\n    protected $A_Protected = &quot;A_Protected&quot;;\r\n    public $A_Public = &quot;A_Public&quot;;\r\n\t\r\n\t\/\/static properties\r\n\tprivate static $A_PrivateStatic = &quot;A_PrivateStatic&quot;;\r\n    protected static $A_ProtectedStatic = &quot;A_ProtectedStatic&quot;;\r\n    public static $A_PublicStatic = &quot;A_PublicStatic&quot;;\r\n\t\r\n\t\/\/methods\r\n\tpublic function A_PublicMethod(){}\r\n\tprivate function A_PrivateMethod(){}\r\n\tprotected function A_ProtectedMethod(){}\r\n\t\r\n\t\/\/static methodes\r\n\tpublic static function A_PublicStaticMethod(){}\r\n\tprivate static function A_PrivateStaticMethod(){}\r\n\tprotected static function A_ProtectedStaticMethod(){}\r\n}\r\n\r\n\/**\r\n * Thats a cool class\r\n * For sure!\r\n *\/\r\nclass B extends A\r\n{\r\n\t\/\/constants\r\n\tconst B_Const1 = &quot;B_Const1&quot;;\r\n\tconst B_Const2 = &quot;B_Const2&quot;;\r\n\t\r\n\t\/\/properties\r\n\tprivate $B_Private = &quot;B_Private&quot;;\r\n    protected $B_Protected = &quot;B_Protected&quot;;\r\n    public $B_Public = &quot;B_Public&quot;;\r\n\t\r\n\t\/\/static properties\r\n\tprivate static $B_PrivateStatic = &quot;B_PrivateStatic&quot;;\r\n    protected static $B_ProtectedStatic = &quot;B_ProtectedStatic&quot;;\r\n    public static $B_PublicStatic = &quot;B_PublicStatic&quot;;\r\n\t\r\n\t\/\/methods\r\n\tpublic function B_PublicMethod(){}\r\n\tprivate function B_PrivateMethod(){}\r\n\tprotected function B_ProtectedMethod(){}\r\n\t\r\n\t\/\/static methodes\r\n\tpublic static function B_PublicStaticMethod(){}\r\n\tprivate static function B_PrivateStaticMethod(){}\r\n\tprotected static function B_ProtectedStaticMethod(){}\r\n}\r\n<\/pre>\n<\/p>\n<h4>Generelle Klasseninformationen<\/h4>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint &quot;Class &quot;.$refclass-&gt;getName().&quot; is defined from line &quot;.$refclass-&gt;getStartLine().&quot; to &quot;.$refclass-&gt;getEndLine().&quot; in file &quot;.$refclass-&gt;getFileName();\r\n\/\/Class B is defined from line 37 to 62 in file D:\\xampp\\htdocs\\ref1.php\r\n<\/pre>\n<h4>Konstanten<\/h4>\n<p>Alle Konstanten inklusive deren Wert der Klasse und aller \u00dcberklassen.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint_r($refclass-&gt;getConstants());\r\n\/*\r\nArray\r\n(\r\n    [B_Const1] =&gt; B_Const1\r\n    [B_Const2] =&gt; B_Const2\r\n    [A_Const1] =&gt; A_Const1\r\n    [A_Const2] =&gt; A_Const2\r\n)\r\n*\/\r\n<\/pre>\n<h4>Attribute<\/h4>\n<p>Alle Attribute (statisch und nicht statisch) der Klasse und aller \u00dcberklassen. Sch\u00f6n zu sehen, dass die privaten Attribute der Oberklasse hier fehlen.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint_r($refclass-&gt;getDefaultProperties()); \r\n\/*\r\nArray\r\n(\r\n    [B_PrivateStatic] =&gt; B_PrivateStatic\r\n    [B_ProtectedStatic] =&gt; B_ProtectedStatic\r\n    [B_PublicStatic] =&gt; B_PublicStatic\r\n    [A_ProtectedStatic] =&gt; A_ProtectedStatic\r\n    [A_PublicStatic] =&gt; A_PublicStatic\r\n    [B_Private] =&gt; B_Private\r\n    [B_Protected] =&gt; B_Protected\r\n    [B_Public] =&gt; B_Public\r\n    [A_Protected] =&gt; A_Protected\r\n    [A_Public] =&gt; A_Public\r\n)\r\n*\/\r\n<\/pre>\n<h4>DocBlock<\/h4>\n<p>Der Doc-Block Kommentar der Klasse.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint $refclass-&gt;getDocComment();\r\n\/**\r\n * Thats a cool class\r\n * For sure!\r\n *\/\r\n<\/pre>\n<h4>Interfaces<\/h4>\n<p>Alle Interfaces, die die Klasse (und Oberklassen dieser) implementieren. Als Value wird wieder ein ReflectionClass Objekt \u00fcbergeben, welches man dann nach gleichem Schema reflecten kann.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint_r($refclass-&gt;getInterfaces()); \r\n\/*\r\nArray\r\n(\r\n    [ITest] =&gt; ReflectionClass Object\r\n        (\r\n            [name] =&gt; ITest\r\n        )\r\n)\r\n*\/\r\n<\/pre>\n<h4>Methoden<\/h4>\n<p>Alle Methoden der Klasse und aller Oberklassen. Hierbei sind merkw\u00fcrdigerweise (vergleiche den Punkt <i>Attribute<\/i>) auch die privaten Methoden der Oberklasse dabei. Gilt sowohl f\u00fcr statische wie auch f\u00fcr nicht statische Methoden.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint_r($refclass-&gt;getMethods());\r\n\/*\r\nArray\r\n(\r\n    [0] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; B_PublicMethod\r\n            [class] =&gt; B\r\n        )\r\n    [1] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; B_PrivateMethod\r\n            [class] =&gt; B\r\n        )\r\n    [2] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; B_ProtectedMethod\r\n            [class] =&gt; B\r\n        )\r\n    [3] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; B_PublicStaticMethod\r\n            [class] =&gt; B\r\n        )\r\n    [4] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; B_PrivateStaticMethod\r\n            [class] =&gt; B\r\n        )\r\n    [5] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; B_ProtectedStaticMethod\r\n            [class] =&gt; B\r\n        )\r\n    [6] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; A_PublicMethod\r\n            [class] =&gt; A\r\n        )\r\n    [7] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; A_PrivateMethod\r\n            [class] =&gt; A\r\n        )\r\n    [8] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; A_ProtectedMethod\r\n            [class] =&gt; A\r\n        )\r\n    [9] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; A_PublicStaticMethod\r\n            [class] =&gt; A\r\n        )\r\n    [10] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; A_PrivateStaticMethod\r\n            [class] =&gt; A\r\n        )\r\n    [11] =&gt; ReflectionMethod Object\r\n        (\r\n            [name] =&gt; A_ProtectedStaticMethod\r\n            [class] =&gt; A\r\n        )\r\n)\r\n*\/\r\n<\/pre>\n<p>Als optionalen Parameter kann man in <i>getMethods()<\/i> noch spezifizieren, was man genau f\u00fcr Methoden zur\u00fcck m\u00f6chte. Zur Auswahl stehen: <i>ReflectionMethod::IS_STATIC, ReflectionMethod::IS_PUBLIC, ReflectionMethod::IS_PROTECTED, ReflectionMethod::IS_PRIVATE, ReflectionMethod::IS_ABSTRACT, ReflectionMethod::IS_FINAL<\/i> und auch Kombinationen davon. Beispiel:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint_r($refclass-&gt;getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PRIVATE));\r\n<\/pre>\n<p>W\u00fcrde zum Beispiel alle statischen und alle privaten Methoden zur\u00fcckgeben.<\/p>\n<h4>Static Properties<\/h4>\n<p>Alle statischen Attribute der Klasse selbst und ihrer Oberklassen. Hierbei ist wieder zu bemerken, dass die privaten statischen Attribute der Oberklasse fehlen.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nprint_r($refclass-&gt;getStaticProperties());\r\n\/*\r\nArray\r\n(\r\n    [B_PrivateStatic] =&gt; B_PrivateStatic\r\n    [B_ProtectedStatic] =&gt; B_ProtectedStatic\r\n    [B_PublicStatic] =&gt; B_PublicStatic\r\n    [A_ProtectedStatic] =&gt; A_ProtectedStatic\r\n    [A_PublicStatic] =&gt; A_PublicStatic\r\n)\r\n*\/\r\n<\/pre>\n<h4>Pr\u00fcfung auf Abstraktheit einer Klasse<\/h4>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;B&quot;);\r\nvar_dump($refclass-&gt;isAbstract());\r\n\/\/bool(false)\r\n<\/pre>\n<h4>Pr\u00fcfung auf Klassentyp<\/h4>\n<p>Okay, keine wirklich tolle \u00dcberschrift. Prinzip ist aber einfach. Es geht darum zu pr\u00fcfen, ob die reflektierte Klasse selbst geschrieben wurde oder &#8222;PHP-intern&#8220; ist. Das Beispiel machts klar:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$refclass = new ReflectionClass(&quot;StdClass&quot;);\r\nvar_dump($refclass-&gt;isUserDefined());\r\n\/\/bool(false)\r\n\r\n$refclass = new ReflectionClass(&quot;A&quot;);\r\nvar_dump($refclass-&gt;isUserDefined());\r\n\/\/bool(true)\r\n<\/pre>\n<h4>To be continued<\/h4>\n<p>Das wars also mit der ReflectionClass. Ein paar Methoden habe ich unterschlagen, um es nicht unn\u00f6tig aufzubl\u00e4hen. F\u00fcr alles weitere steht das <a href=\"http:\/\/php.net\/manual\/en\/class.reflectionclass.php\">PHP Handbuch zur ReflectionClass<\/a> gern zur Verf\u00fcgung. Im n\u00e4chsten Teil gehts weiter mit ReflectionFunction und ReflectionMethod.<\/p>\n<p>\n<b>Folgende Teile:<\/b><\/p>\n<ul>\n<li><a href=\"https:\/\/d-mueller.de\/blog\/reflection-teil-2-reflectionmethod-und-reflectionfunction\/\">Teil 2: ReflectionMethod und ReflectionFunction<\/a><\/li>\n<li><a href=\"https:\/\/d-mueller.de\/blog\/reflection-teil-3-reflectionparameter\/\">Teil 3: ReflectionParameter<\/a><\/li>\n<li><a href=\"https:\/\/d-mueller.de\/blog\/reflection-teil-4-reflectionproperty\/\">Teil 4: ReflectionProperty<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Was ist Reflection Eines der coolsten Features in PHP, was leider so gut wie ohne Dokumentation dasteht. Reflection ist eine M\u00f6glichkeit, Meta Informationen \u00fcber so ziemlich alles in PHP herauszubekommen. Welche Interfaces implementiert eine Klasse? Welche Methoden hat sie? Wieviele &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/reflection-teil-1-reflectionclass\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,3],"tags":[],"class_list":["post-247","post","type-post","status-publish","format-standard","hentry","category-php","category-webdev"],"_links":{"self":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/comments?post=247"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/247\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}