A good documentation of source code is necessary as it helps others to
evaluate your application, to make it error free. But with so much code being
written it becomes difficult to document each and every program. PHP 5 has an
in-built feature called 'Reflection,' which allows you to reverse engineer
different classes, functions or extensions. It also gives information on
objects, starting and ending line numbers of a class or function, parameters and
creates documents. It is an object oriented extension to the existing PHP core
engine. Using this feature, you no longer need to go through hundreds of pages
of documentation to find out about any class or function. A common scenario
where you can use 'Reflection' is, when you have an encoded script to work on
and you don't want to go through its manual. It also helps in understanding how
a particular code is working. Now let's define a class 'first' with a function
called 'display' and second function called 'second' which inherits the parent
class.
Direct Hit! |
Applies To: PHP developers USP: Know about any class or function without reading manuals Primary Link: http://in.php.net/ oop5.reflection Keywords: reverse engg with PHP |
class first {
public function display($text) {
// Display the argument passed
echo $text;
} }
class second extends first {
private function bar(first &$baz) {
// do something
} }
$child = new second('hello world');
$child->display('test');
?>
Save this code with '.php' extension and run the script by issuing the
command “php
Now, let's do reverse engineering of our code. Add the following lines at the
end of the program:
$sec_refl = new ReflectionClass('second'); echo "\n",
"Reflection of Second Class: ", "\n"; echo "This class is abstract: ", (int)$sec_refl->isAbstract(),
"\n";
echo "This class is final: ", (int)$sec_refl->isFinal(), "\n";
echo "This class is actually an interface: ", (int)$sec_refl->isInterface(),
"\n"; echo "\$second is an object of this class: ", (int)$sec_refl->isInstance($sec),
"\n"; $first_refl = new ReflectionClass('first');
echo "\n", "Reflection of First Class: ", "\n" ; echo "This class inherits from
First : ", (int)$sec_refl-> isSubclassOf ($first_refl), "\n";
$reflect = new ReflectionClass('second'); foreach($reflect->getMethods() as $reflectmethod)
{
echo " {$reflectmethod->getName()}()\n"; echo " ", str_repeat("-",
strlen($reflectmethod->getName()) + 2), "\n"; foreach($reflectmethod->getParameters()
as $num => $param) {
echo "Param $num: \$", $param->getName(), "\n"; echo "Passed by
reference: ", (int)$param->isPassedByReference(), "\n"; echo "Can be null: ", (int)$param->allowsNull(),
"\n";
echo "Class type: ";
if ($param->getClass()) {
echo $param->getClass()->getName();
} else { echo "N/A"; } echo "\n\n"; }}
In these lines we have created two new instances of Reflection class for each
class and passed both the classes as a parameter. Then we formatted the output
using some inbuilt function along with the Reflection Class. There is another
way of doing this, ie by simply giving a single line “echo $sec_refl” (for
second class), however, the output will be a bit confusing. The output after
adding the above code is:
Output of the first display function:
Sample Text Argument
Reflection of Second Class:
This class is abstract: 0
This class is final: 0
This class is actually an interface: 0
$second is an object of this class: 1
...
In the output you can clearly see whether a class is an abstract class or
not, or whether there's any object, etc. Further you can also see the
description of each method for the 'second' class: like the number of arguments,
class type, name of the arguments passed, etc.