Hi everyone, sorry for writing such a long email, but this design decision is very important for the completion of the Reflection component.
Sebastian Bergmann wrote: > Stefan Marr schrieb: >> And there has been a discussion to include another Interface definition in >> between the reflection classes and the underlying infrastructure, to be able >> to use a parser and handle Reflection without loading the classes. Butdon't >> know how that much about this idea. Falko? > > Yes, Static Reflection (ie. being able to use the Reflection API without > the class being loaded) is something I would really like to see in the > component. Recently I studied several approaches for the integration of the Static Reflection concept we developed at the FrOSCon. The idea we discussed at the conference was not to include the parser for static analysis directly in the ezcReflection component (at least for the first release). Instead we wanted to introduce a layer of interface which should then be implemented by ezcReflection and Static Reflection classes. This would allow for tools like ezcCodeAnalyzer, ezcWsdl or PHPCallGraph to leverage both reflection implementations. Jakob and me developed some tools to generate PHP code out of reflection objects. You may have a look at them in our Subversion repositories at: svn://svn.pureenergy.cc/staticReflection https://instantsvc.svn.sourceforge.net/svnroot/instantsvc/branches/reflection2php Interestingly we discovered that this kind of code generation can be leveraged for refactoring and quality assurance. On the one hand the tools enable the generation of interfaces out of classes or class skeletons out of interfaces. On the other hand it allows for comparing properties and method signatures among various classes, e.g. between ezcReflection classes and the PHP Reflection API. (Try a Diff-Viewer on the output in the svn.) However the design with interfaces does not seem to be very elegant because it would require a complete reimplementation of nearly all features of the ezcReflection component in the Static Reflection classes. Thus I propose a dependency injection approach: We could allow the injection of instances of external Reflection implementations through the constructors of the ezcReflection classes. Such an external Reflection implementation would have to extend the PHP reflection classes as well as the ezcReflection does. If such an instance is given the ezcReflection would leverage it as its data source. Otherwise PHP Reflection would be utilized as usual. Additional features of the external instance could also be leveraged by forwarding calls via overloading. class ezcReflectionClass extends ReflectionClass { protected $class; /** * @param string|object|ReflectionClass $argument * name, instance or ReflectionClass object of * the class to be reflected */ public function __construct( $argument ) { if ( !$argument instanceof ReflectionClass ) { parent::__construct($argument); } $this->class = $argument; ... } public function getName() { if ( $this->class instanceof ReflectionClass ) { // query external reflection object $name = $this->class->getName(); } else { $name = parent::getName(); } return $name; } public function __call( $method, $arguments ) { if ( !$this->class instanceof ReflectionClass ) { return call_user_method( $this->class, $method, $arguments ); } else { throw new Exception( 'Call to undefined method ' . __CLASS__ . '::' . $method ); } } ... } This aproach would enable users of the ezcReflection to leverage various reflection extensions (e.g. StaticReflection or a version extended with intercession features of Runkit as Stefan proposed it) together with the annotation mechanism and the type system. Furthermore the reimplementation of all methods would allow us to provide a complete documentation since the section of the PHP manual is more or less incomplete. Do you have any other ideas on how to solve this integration problem or improve the proposed design? Kind regards, Falko -- Components mailing list [email protected] http://lists.ez.no/mailman/listinfo/components
