Reflection in PHP #3 - Using Reflection on Classes
Description:
Reflection in PHP #3 - Using Reflection on Classes
About this Kata Series
This Kata Series explores a core API in PHP called Reflection which allows a developer to reverse-engineer classes, interfaces, functions, methods and extensions. It is assumed that the user undertaking this Kata Series is already familiar with both functional and object-oriented programming in PHP. A good indicator that you are ready for this Kata Series is if you are able to complete at least 6 out of 8 topics/Kata in my PHP Functions series without hesitation and are at least moderately familiar with all the topics covered in the first 7 Kata in my Object-Oriented PHP series. Certain Kata in this Series may also require slightly more advanced OOP knowledge such as the awareness of what an interface is, but if such extra knowledge is required, it will be mentioned under a "Prerequisites" subtitle.
Most Kata in this Series will consist of two main parts - a "Lesson" and a "Task". However, unlike either of "Object-Oriented PHP" and "PHP Functions", the "Lesson" will only teach the fundamental concepts required to understand the "Task" presented in each Kata. In most cases, you will be expected to look up on the official Reflection documentation in order to figure out the details of how to actually complete the Kata "Task" (e.g. which methods to call or even what class to use!). If you are still in doubt after referring to the official documentation, you are strongly encouraged to conduct your own research and use whatever resources are available to you on the Internet or otherwise.
Lesson
As was briefly mentioned in the first Kata of this Series, the Reflection API in PHP is not limited to reverse-engineering functions and their parameters; they can also be used to reverse-engineer classes of all types as well as class-like structures (interfaces, traits, etc.). All such classes and class-like structures (including interfaces and traits) can be reverse-engineered using a single class called ReflectionClass
. In case you were wondering, there does not exist ReflectionInterface
and/or ReflectionTrait
as such structures are also considered "classes" (albeit special ones).
The class constructor of ReflectionClass
is somewhat similar to that of ReflectionFunction
in that it also accepts exactly one argument which could either be the name of the class as a string or an object (which must naturally be an instance of a PHP class). Once the instance of ReflectionClass
is instantiated, a lot of information can then be extracted about that class, e.g. whether it is an interface, trait, abstract class or an ordinary class; what its parent class is (if it has one); the traits that a class uses and the interfaces that it implements etc.
Furthermore, as you may have guessed, you can also learn a great deal about each and every component of a class itself simply by calling the correct methods. For example, you could call on the getProperties()
method of the ReflectionClass
class to obtain an array of ReflectionProperty
s, each one corresponding to a particular property present in that class, whether public
, private
or protected
. Similarly, the getMethods()
method of the ReflectionClass
class can be invoked in order to obtain an array of ReflectionMethod
s corresponding to each method present in the class. It is interesting to note that ReflectionMethod
is very similar to ReflectionFunction
as a class method is essentially a "function" that belongs to a particular class so for example, you could then call the getParameters()
method of each ReflectionMethod
in order to obtain an array of ReflectionParameter
s per class method to study each class method and its parameters in great depth. Intriguing, huh?
Before we move on to the Task, you may find the official documentation on ReflectionClass useful. In some parts of the Task, you may also find the official documentation on ReflectionProperty and ReflectionMethod useful.
Final Remarks
This is the last "Lesson" of this Series. As you may have noticed by reading the official docs on the Reflection API in PHP, we have not yet covered all of the classes present in the API, e.g. ReflectionExtension
and ReflectionGenerator
. This is due to two main reasons: (1) Such features in PHP as extensions and generators are not as commonly used as function and classes so it is highly unlikely that you will need to use Reflection on them often and (2) by now, you should already be very familiar with the official documentation on Reflection and how to understand and apply it in real-world code. The key to understanding and applying Reflection under the correct circumstances is not by memorizing all of the methods present in each and every class (although you could do if you have a good memory!); rather, it is being able to refer to the official Documentation when necessary and understanding how to properly read it so you can call the correct method in the correct manner when required in order to obtain the information that you desire. As long as you know how to refer to the official Documentation and understand it quickly, you should be able to use any Reflection class with ease whenever you need it.
Task
Write a function get_class_overview()
which accepts exactly one argument $c
, the name of the class as a string or an instance of that class and return an associative array with the following key-value pairs:
"properties"
- This should be set to an associative array with 3 key-value pairs:"public"
,"protected"
and"private"
, each detailing the number of properties with the given visibility"methods"
- This should also be set to an associative array with 3 key-value pairs:"public"
,"protected"
and"private"
, each detailing the number of methods with the given visibility
For example, given the following class:
class Example {
public $a = 1;
public $b;
private $c = "Hello World";
public function d() {}
protected function e() {}
protected function f() {}
}
... your function should return the following associative array:
[
"properties" => [
"public" => 2,
"protected" => 0,
"private" => 1
],
"methods" => [
"public" => 1,
"protected" => 2,
"private" => 0
]
]
This test case has been included for you.
Kata in this Series
- Reflection in PHP #1 - Introduction
- Reflection in PHP #2 - Dissecting a function via ReflectionParameter
- Reflection in PHP #3 - Using Reflection on Classes
- Reflection in PHP #4 - Puzzle Challenge [Assessment]
You May Also Like
Similar Kata:
Stats:
Created | Mar 16, 2017 |
Published | Mar 17, 2017 |
Warriors Trained | 534 |
Total Skips | 172 |
Total Code Submissions | 769 |
Total Times Completed | 227 |
PHP Completions | 227 |
Total Stars | 10 |
% of votes with a positive feedback rating | 97% of 55 |
Total "Very Satisfied" Votes | 52 |
Total "Somewhat Satisfied" Votes | 3 |
Total "Not Satisfied" Votes | 0 |
Total Rank Assessments | 4 |
Average Assessed Rank | 5 kyu |
Highest Assessed Rank | 5 kyu |
Lowest Assessed Rank | 6 kyu |