jump to navigation

Exploring Various Parts of PHP By “reverse engineering” February 4, 2012

Posted by Tournas Dimitrios in PHP.
trackback

According to Wikipedia —- Reverse engineering is the process of discovering the technological principles of a device , object , or system through analysis of its structure —- There are  scenarios where we have to explore the internal structure of a Class in PHP , for example :

  • The script is encoded
  • The PHP manual is difficult to understand or not  well documented
  • Don’t want to  read someone else’s PHP source code .
  • Exploring if the Class embeds specific type of functionality (isDestructor , isProtected , toString , getClosure ) .

PHP’s reflection API  adds the ability to reverse-engineer Classes , interfaces , functions , methods and extensions . Additionally, the reflection API offers ways to retrieve doc comments for functions , classes and methods . A couple practical examples will shed some light into PHP’s reflection API .  Lets’s define a couple Classes , they just implement PHP’s OOP inheritance functionality  and don’t have any practical implementation .

class MyParent {
public function foo($info) {
	// do stuff
	}
    }

class Child extends MyParent {
	public $someval;

private function test(myparent $members) {
	// do stuff
	}

public function __construct($val) {
	$this->someval = $val;
	}
	}

$child = new Child('hello world');
$child->foo('test');

What we have there are two classes (MyParent , Child) , of which the second inherits from the first . Myparent’s  function , foo() , accepts one parameter. Child has a local variable ($someval) , one normal function (test()) that takes one parameter, and also a constructor that takes one parameter too . At the end of the script we instantiate an object of type  Child , passing in a value for the constructor, then calling its foo() function .  Let’s reverse engineer the code : what exactly does the Child class offer us ?

Add this line to the end of the code:

$reflect = new ReflectionClass('Child');
echo "<pre>";
echo $reflect;
echo "</pre>";

Running the script now should output a lot of information :

Class [  class Child extends MyParent ] {
  @@ C:\Program Files\wamp\www\phpunit\test.php 9-19

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [1] {
    Property [  public $someval ]
  }

  - Methods [3] {
    Method [  private method test ] {
      @@ C:\Program Files\wamp\www\phpunit\test.php 12 - 14

      - Parameters [1] {
        Parameter #0 [  myparent $members ]
      }
    }

    Method [  public method __construct ] {
      @@ C:\Program Files\wamp\www\phpunit\test.php 16 - 18

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

    Method [  public method foo ] {
      @@ C:\Program Files\wamp\www\phpunit\test.php 4 - 6

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

The output is actually quite understandable . For example , it says there are three methods , then lists each of them . Note that it tells us that all three are public functions and take one parameter . The @@ lines tell us where individual items were actually defined in the source code , which is great for jumping straight to something that interests you .

The Reflection Class has lot of public functions that could be used to mirror the internal structure of an object . Running the following code will show us that the Class contains 40  functions   :


// Just ignore PHP's "Warning" Error message
foreach(get_class_methods(new ReflectionClass()) as $key=>$method)
{
echo $key.' -> '.$method.'<br />';
}

/*
 Example : Let's find if "Child" is an subClass of "MyParent"
( "is_subclass_of()" has the same functionality )
*/
$reflect = new ReflectionClass('Child');
echo ($reflect->isSubclassOf('MyParent')) ?  "Yess" : "No" ;

Now lets Reverse engineer the ReflectionClass itself :

// Just ignore PHP's "Warning" Error message
$reflect = new ReflectionClass(new ReflectionClass());
echo "<pre>";
echo $reflect;
echo "</pre>";

/*
A better structured result
The output is detailed information on all our functions , nice formatted.
*/
$reflect = new ReflectionClass(new ReflectionClass());
echo "<b>Exploring the class :</b>";
echo "<br>============================================<br>";
foreach($reflect->getMethods() as $reflectmethod) {
echo "  {$reflectmethod->getName()}()
";
echo  str_repeat("-", strlen($reflectmethod->getName()) + 5), "
";
foreach($reflectmethod->getParameters() as $num => $param) {
	echo " Param $num: \$", $param->getName(), "
";
	echo "Passed by reference: ", (int)$param->isPassedByReference(), "
";
	echo "Can be null: ", (int)$param->allowsNull(), "
";
	echo " Class type: ";
	if ($param->getClass()) {
		echo $param->getClass()->getName();
	} else {
		echo "N/A";
	}
	echo "<p>";
}
}

Other interesting tools for reverse engineering PHP’s building blocks (classes , interfaces , functions , methods and extensions) are the Reflection Classes (ReflectionFunction , ReflectionExtension , ReflectionObject , ReflextionExeption )  . For example the ReflectionExtension Class can be used to mirror a specific Extension .

$reflect = new ReflectionExtension('simplexml');
echo "<pre>";
echo $reflect ;
echo "<pre>";

Links :

Comments»

No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s