blob: be49897ca4d3ed9e888fb1f12ab7ba85923f243e [file] [log] [blame]
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