PHP Classes and Objects Introspecting Objects - Supercoders | Web Development and Design | Tutorial for Java, PHP, HTML, Javascript PHP Classes and Objects Introspecting Objects - Supercoders | Web Development and Design | Tutorial for Java, PHP, HTML, Javascript

Breaking

Post Top Ad

Post Top Ad

Monday, May 27, 2019

PHP Classes and Objects Introspecting Objects

PHP Classes and Objects



Introspecting Objects

Problem

You want to inspect an object to see what methods and properties it has, which lets you write code that works on any generic object, regardless of type.

Solution

Use the Reflection classes to probe an object for information.

For a quick overview of the class, call Reflection::export():

         // learn about cars
         Reflection::export(new ReflectionClass('car'));

Or probe for specific data:

         $car = new ReflectionClass('car');
         if ($car->hasMethod('retractTop')) {
               // car is a convertible
         }

Discussion

It’s rare to have an object and be unable to examine the actual code to see how it’s described. Still, with the Reflection classes, you can programmatically extract information about both object-oriented features, such as classes, methods, and properties, and non-OO features, such as functions and extensions.

This is useful for projects you want to apply to a whole range of different classes, such as creating automated class documentation, generic object debuggers, and state savers, like serialize().

Example  Person class

          class Person {
                public $name;
                protected $spouse;
                private $password;

                public function __construct($name) {
                       $this->name = $name
                }

                public function getName() {
                       return $name;
                }

                protected function setSpouse(Person $spouse) {
                       if (!isset($this->spouse)) {
                              $this->spouse = $spouse;
                       }
                }

                private function setPassword($password) {
                       $this->password = $password;
                }
          }

For a quick overview of the class, call Reflection::export():

          Reflection::export(new ReflectionClass('Person'));

          Class [ <user> class Person ] {
             @@ /www/reflection.php 3-25

              - Constants [0] {
              }

              - Static properties [0] {
              }

              - Static methods [0] {
              }

              - Properties [3] {
                Property [ <default> public $name ]
                Property [ <default> protected $spouse ]
                Property [ <default> private $password ] 
              }

              - Methods [4] {
                 Method [ <user> <ctor> public method _ _construct ] {
                     @@ /www/reflection.php 8 - 10

                      - Parameters [1] {
                         Parameter #0 [ $name ]
                      }
                 }

                 Method [ <user> public method getName ] {
                      @@ /www/reflection.php 12 - 14
                 }

                 Method [ <user> protected method setSpouse ] {
                      @@ /www/reflection.php 16 - 20

                      - Parameters [1] {
                         Parameter #0 [ Person or NULL $spouse ]
                      }
                 }

                 Method [ <user> private method setPassword ] {
                      @@ /www/reflection.php 22 - 24

                      - Parameters [1] {
                         Parameter #0 [ $password ]
                      }
                  }
              }
          }

The Reflection::export() static method takes an instance of the ReflectionClass class and returns a copious amount of information. As you can see, it details the number of constants, static properties, static methods, properties, and methods in the class. Each item is broken down into component parts. For instance, all the entries contain visibility identifiers (private, protected, or public), and methods have a list of their parameters underneath their definition.

Reflection::export() not only reports the file where everything is defined, but even gives the line numbers! This lets you extract code from a file and place it in your documentation.

Example  shows a short command-line script that searches for the filename and starting line number of a method or function.

Example  Using reflection to locate function and method definitions

         if ($argc < 2) {
              print "$argv[0]: function/method, classes1.php [, ... classesN.php]\n";
              exit;
         }

         // Grab the function name
         $function = $argv[1];

         // Include the files
         foreach (array_slice($argv, 2) as $filename) {
                  include_once $filename;
         }

         try {
               if (strpos($function, '::')) {
                    // It's a method
                    list ($class, $method) = explode('::', $function);
                    $reflect = new ReflectionMethod($class, $method);
               } else {
                    // It's a function
                    $reflect = new ReflectionFunction($function);
               }

               $file = $reflect->getFileName();
               $line = $reflect->getStartLine();

               printf ("%s | %s | %d\n", "$function()", $file, $line);
         } catch (ReflectionException $e) {
               printf ("%s not found.\n", "$function()");
         }

Pass the function or method name as the first argument, and the include files as the remaining arguments. These files are then included, so make sure they don’t print out anything.

The next step is to determine whether the first argument is a method or a function. Because methods are in the form class::method, you can use strpos() to tell them apart.

If it’s a method, use explode() to separate the class from the method, passing both to ReflectionMethod. If it’s a function, you can directly instantiate a ReflectionFunction without any difficulty.

Because ReflectionMethod extends ReflectionFunction, you can then call both get FileName() and getStartLine() of either class. This gathers the information that you need to print out, which is done via printf().

When you try to instantiate a ReflectionMethod or ReflectionFunction with the name of an undefined method, these classes throw a ReflectionException. Here, it’s caught and an error message is displayed.

A more complex script that prints out the same type of information for all user-defined methods and functions appears.

If you just need a quick view at an object instance, and don’t want to fiddle with the Reflection classes, use either var_dump(), var_export(), or print_r() to print the object’s values. Each of these three functions prints out information in a slightly different way; var_export() can optionally return the information, instead of displaying it.



No comments:

Post a Comment

Post Top Ad