5.8 Feature showcase: Accessing class interna

at 2010-08-30 in Examples5.8-SERIES by friebe (0 comments)

NeoThe XP Framework's 5.8-SERIES contains a feature that will allow the reflection API to access private and protected members. Of course, just because you can, doesn't mean you should, as this does allow you to break the encapsulation principle.

On the other side, this feature comes in handy for serialization mechanisms, as well as for reflection-based factory or delegation patterns.


Example

  class URLHandler extends Object {

protected
function handleHttp(URL $url) {
Console::writeLine
('Handling HTTP-URL ', $url);
}

protected
function handleFtp(URL $url) {
Console::writeLine
('Handling FTP-URL ', $url);
}

public
function handle(URL $url) {
$this->getClass()->getMethod('handle'.$url->getScheme())
->invoke
($this, array($url))
;
}
}
Here, it seems kind of natural to allow reflection to access the protected methods, because we're not doing it from an outside scope, but inside the class. And this is actually what the reflection API will check for: There are no modifications to the reflective invocation call needed, it will just work as-is.

Now if we want to refactor the handle() method out into the calling scope, this will no longer work:
  class Main extends Object {
public
static function main(array $args) {
$url= new URL($args[0]);
XPClass::forName
('com.example.URLHandler')->getMethod('handle'.$url->getScheme())
->invoke
($class->newInstance(), array($url))
;
}
}
Because we aren't be allowed to access URLHandler's protected (or private) members in regular code, we aren't allowed to do that using reflection either: It will yield an IllegalAccessException.

Introducing setAccessible()
There might be situations where this behaviour is desired, though, so there is a way around it: Using the setAccessible() method:
  // ...
XPClass::forName('com.example.URLHandler')->getMethod('handle'.$url->getScheme())
->setAccessible
(TRUE)
->invoke
($class->newInstance(), array($url))
;
// ...
By adding this call to your chain you can get around the accessibility checks, and do anything with a method you could do with a public one.

Summary
The XP Framework supports private and protected reflective access for methods as well as fields, and independently of PHP's reflection API supporting it. It will respect scopes and only require a setAccessible() call if you're really "breaking into" a class:-)



Subscribe

You can subscribe to the XP framework's news by using RSS syndication.


Categories

News
General
PHP5
Announcements
RFCs
Further reading
Examples
Editorial
EASC
Experiments
Unittests
Databases
5.8-SERIES
Unicode
Language
5.9-SERIES

Related

Find related articles by a search for «5.8».