Archive for May 5th, 2008

Analysing PHP Objects and Classes

Monday, May 5th, 2008

Due to the dynamic nature of PHP as a programming language it can be quite difficult to determine what is happening. This is then even harder if you don’t have access to debugging tools such as those in Zend Studio.

How can you view an object?

  1. header("Content-Type: text/plain");
  2.  
  3. class Foo {
  4.  
  5. private $name = "Fred";
  6. private $age = 30;
  7.  
  8. public function __construct(){}
  9.  
  10. public function bar(){
  11. echo "Hello World";
  12. }
  13.  
  14. }
  15.  
  16. $myFoo = new Foo();
  17.  
  18. print_r($myFoo);
  19. $content = print_r($myFoo, true);
  20.  
  21. var_dump($myFoo);

These all are all ways of outputting objects and can prove to be invaluable. I find using print_r particularly useful for logging data errors to a file or database that you can analyse later.

  1. Foo Object
  2. (
  3. [name:private] => Fred
  4. [age:private] => 30
  5. )
  6. object(Foo)#1 (2) {
  7. ["name:private"]=>
  8. string(4) "Fred"
  9. ["age:private"]=>
  10. int(30)
  11. }

Reflection

“In computer science, reflection is the process by which a computer program can observe and modify its own structure and behaviour. The programming paradigm driven by reflection is called reflective programming.” Wikipedia (http://en.wikipedia.org/wiki/Reflection_%28computer_science%29) .

Ok, so what does that mean? Basically, Reflection is a way of programmatically dealing with classes. So you can find out information about them. Including the properties and values.

What’s inside a class?

As of PHP 5 there is now a very powerful reflection library available. This includes a number of very useful objects. The two we will be focusing on are ReflectionClass and Reflection. Here is the one liner that can do it all….

  1. Reflection::export(new ReflectionClass(‘SimpleXMLElement’));

To set up a simple test case for this I used;

  1. header("Content-Type: text/plain");
  2.  
  3. Reflection::export(new ReflectionClass(‘SimpleXMLElement’));

This creates quite a bit of output;

  1. Class [   class SimpleXMLElement implements Traversable ] {
  2.  
  3. - Constants [0] {
  4. }
  5.  
  6. - Static properties [0] {
  7. }
  8.  
  9. - Static methods [0] {
  10. }
  11.  
  12. - Properties [0] {
  13. }
  14.  
  15. - Methods [12] {
  16. Method [  final public method __construct ] {
  17. }
  18.  
  19. Method [  public method asXML ] {
  20. }
  21.  
  22. Method [  public method saveXML ] {
  23. }
  24.  
  25. Method [  public method xpath ] {
  26. }
  27.  
  28. Method [  public method registerXPathNamespace ] {
  29. }
  30.  
  31. Method [  public method attributes ] {
  32. }
  33.  
  34. Method [  public method children ] {
  35. }
  36.  
  37. Method [  public method getNamespaces ] {
  38. }
  39.  
  40. Method [  public method getDocNamespaces ] {
  41. }
  42.  
  43. Method [  public method getName ] {
  44. }
  45.  
  46. Method [  public method addChild ] {
  47. }
  48.  
  49. Method [  public method addAttribute ] {
  50. }
  51. }
  52. }

So what does it all mean? It’s quite a bit to read through. So starting from the top;

Line one shows us the definition of the class but it’s got a few things more than we are used to seeing. The first being <internal:SimpleXML>. This means that it exists internally, as in its implemented in C code rather than native PHP. SimpleXML is the name of the package that the class is in. Then on this line we can see the name of the class, any classes it extends and any interfaces it implements.
The next step as we go in we can see its divided into various different sections. These are fairly self explanatory so I won’t go into too much detail. Again, for each method you can see its implemented internally and is in the SimpleXML package.

  1. header("Content-Type: text/plain");
  2.  
  3. class Test{
  4.  
  5. private function hello(){
  6.  
  7. }
  8.  
  9. }
  10.  
  11. Reflection::export(new ReflectionClass(‘Test’));

The above example is the same as before but with a simple class made up for it. The output follows

  1. Class [  class Test ] {
  2. @@ C:\Important\www\BlogExamples\5. Analysing PHP Objects and Classes\reflection.php 6-12
  3.  
  4. - Constants [0] {
  5. }
  6.  
  7. - Static properties [0] {
  8. }
  9.  
  10. - Static methods [0] {
  11. }
  12.  
  13. - Properties [0] {
  14. }
  15.  
  16. - Methods [1] {
  17. Method [  private method hello ] {
  18. @@ C:\Important\www\BlogExamples\5. Analysing PHP Objects and Classes\reflection.php 8 - 10
  19. }
  20. }
  21. }

This has a very similar result to the output on the SimpleXMLElement in terms of the content. The key differences are, internal is now replaced by ‘user’ and rather than have a package name there is a special value represented by ‘@@’ that shows where the code resides. It’s nice to see it even shows the line numbers for the class and the methods.

So…

What is this all useful for? Generally on the whole PHP’s documentation is very good. However, it doesn’t always show the differences between versions of PHP clearly, some of the newer features remain less well documented or perhaps the documentation doesn’t have good coverage in your native language.

Either way, will this ever replace reading the source code and documentation? Well, probably not. However for internal code thats written in C unless you want to read that it makes for quite a handy reference.