eZ component: Reflection, Requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Introduction ============ Since Web Services have been invented to enable interoperable communication between various platforms they have to be typed statically. Hence type information will be required when developing tools for automated generation of Web Services. In modern programming languages a typical way to obtain structural information is to leverage the runtime environment of the language and access language elements through a high level reflection API. As of PHP5 a Reflection API has been included in the standard PHP distribution. It provides an API to obtain information about classes and all their methods and properties, without the need to parse any source code. Simple functions, runtime objects and PHP extensions can be inspected, as well. But the gathering of information is not the only feature of the Reflection API. It is also possible to modify properties of objects, invoke arbitrary methods or functions and instantiate objects. The Reflection API conforms to a meta model of an object-oriented programming language. That way it is possible to reflect nearly all aspects of a given class or object. However PHP's Reflection API does not provide any type information due to PHP being a dynamically typed language. That means only at runtime types of concrete variables or objects can be determined. But it is not possible to obtain this information statically from a class or function declaration without having an instance of it. This is indeed not a problem for implementing SOAP since it only deals with concrete instances at runtime. But e.g. when describing service interfaces the knowledge of structural details is essentially required. When looking at professional PHP applications it stands out that they only use the dynamic typing features where it is really useful e.g. to deal with various inputs or produce different outputs. However large parts of the code will work with strict types and even enforce them e.g. by throwing an exception when receiving input of a wrong data type. This behavior is also documented in the source code documentation stored in comments of those language elements. Thus it appears that in many cases type information already exists statically in the source code. With version 5.1 of PHP the capabilities of the Reflection API have been enhanced and now it is possible to extract all comments associated with a language construct with API methods. So it is a logical next step to leverage the information given in the source code documentation directly at runtime. phpDocumentor (http://phpdoc.org), the standard documentation tool for PHP, provides a common way to document source code by using a formal syntax which can be processed by a computer. Unfortunately just the syntax for data type descriptions is somewhat underspecified since it was only meant to be understandable by human beings. In order to parse these data type descriptions the syntax has to be specified more precisely as defined in section Format. Given a technology to access documentation tags at runtime it would be a perfect foundation to build an annotation mechanism for PHP since it would be also feasible to introduce and work with new tags. Interestingly there have been comparable developments in other programming languages e.g. in Java with XDoclet (http://xdoclet.sourceforge.net/). Description ----------- The main objective of the Reflection component is to enhance PHP by type information and annotations. It uses source code documentation to determine data types and other pieces of information provided via annotations. Those annotations can be used to realize systems which depend on strong type information or additional details about the source code itself. Current implementation ---------------------- The current implementation is highly evolved and well tested. The component is already used by several tools and can be considered stable. Requirements ============ The Reflection component should have the same features, power and performance as the original Reflection API but enhanced by the ability to obtain annotations for classes, methods, properties or functions. This new feature should also be used to implement a type system which enables PHP applications to retrieve data types of parameters, return values and properties. The type system should distinguish three main categories of types. Primitive types are the built-in types boolean, integer, float, string and resource. Array types are all kinds of arrays and class types are used to represent user defined or internal classes. This differentiation is made in consideration of the language behavior and the capabilities of WSDL for defining types in a language independent way. Since arrays are treated in a special way they are additionally classified as simple arrays or maps (dictionaries). An array is represented as a map if it is an associative array i.e. is used like key value pairs. Usage scenarios of the Reflection component are for example WSDL generation for Web Services or Aspect-Oriented Programming (AOP). Processable additions to the source code in general enable a wide range of new applications. Design goals ============ The Reflection API of PHP should be extended as much as possible through class inheritance. Special considerations ====================== In order to maintain the dynamic nature of the language it is explicitly not required to enforce any constraints at runtime. The PHP language runtime should not be modified at all. As a consequence the component expects a correct source code documentation and it is possible that runtime behavior does not correspond to the behavior expected due to improper documentation. Format ====== The Reflection component should reuse the syntax of phpDocumentor (http://phpdoc.org) and also some of its annotation tags. To retrieve the data types of properties, parameters and return values the annotations @var, @param and @return should be analyzed. They have the following syntax: /** * @var datatype description */ /** * @param datatype $paramname description * @return datatype description */ datatype can be the name of a class or any of the built-in PHP data types: - boolean - integer - double - string - resource Additionally it is possible to specify arrays of those data types. For this purpose two extended notations should be supported. Simple arrays which use keys of the type integer and where all values are instances of the same data type can be described by naming the value type followed by square brackets, e.g. integer[] or also string[][] in case of multidimensional arrays. Associative arrays can be notated as array(datatype1=>datatype2). But this should only be used if the key type differs from integer or if it is of major importance and should therefore be emphasized for human readers of the documentation. If a multiple types are possible for a language element they should be listed separated by a |. An open issue which needs further discussion is the handling of aggregate types mixed and number. Diagrams ======== php_reflection_api.png - Class diagram of PHP's Reflection API