RFC __autodefine / spl_autodefine

This proposal proposes to introduce one function for automagically
defining missing definitions at run time.
The reader should have a reasonable level of PHP knowledge and
computer languages when reading this proposal.
Note: Whenever __autodefine is used, also spl_autodefine is meant.

Current situation

PHP currently supports defining missing classes by the __autoload function.
This solution mimics the class loader concept from Java.
Once defined, undefined class functions (methods) can be emulated by
using __call and __callStatic.
It can be argued that __autoload is enough for the future if the
future is object-oriented.


Proposition

While very useful in its own right __autoload is limited: only classes
can be loaded dynamically.
However, there is still a lot of code that is either mixed functional
and object-oriented or only functional.
Excluding that code from such a solution makes life very hard on
everyone maintaining mixed code bases.
It is understandable that by denying this function to non-object
oriented code an incentive exists for maintainers and developers to
switch to object-oriented programming.
Although understandable it is not acceptable, for the following reasons:
1) There are enough people maintaining and writing code in a perfect
manner that do not grasp object orientation
2) Any large code base should have the possibility to slowly migrate
and not be coerced into an object oriented way of working
3) Even if this coercion would work, it would not guarantee the
solution is object-oriented, only that it is coded in classes

So, it can be stated that a number of language constructs are missing
the option to autoload.

>From a conceptual point, tokens in a sequence of statements refer to
definitions. The implementation of almost all run time environments
demands that a definition exists before first referenced. __autoload
changed this rule by allowing classes to be defined when the execution
of a statement hits on an undefined class. This behaviour should be
generalized.

Generally, it can be said that PHP needs a mechanism for automagically
defining undefined elements. The proposed name for that function is
__autodefine. The parameters to this function would be $name and
$type. The type parameter would refer to all the existing elements
that are defined. Probably the maximal set of language constructs that
could be supported are: T_ARRAY, T_CLASS, T_CLASS_C, T_CONST,
T_FUNCTION T_FUNC_C, T_INCLUDE, T_INCLUDE_ONCE, T_INTERFACE,
T_METHOD_C, T_NAMESPACE, T_NS_C, T_REQUIRE, T_REQUIRE_ONCE, T_USE,
T_VAR, T_VARIABLE. The author believes the minimal solution should
support at least T_FUNCTION, T_CLASS, T_INTERFACE and include
(T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE). Namespaces
will be part of the name as is the case in call_user_func.

The relation with the current implementation is that __autoload equals
__autodefine( $name, T_CLASS ) with the exception of the optional
file_extensions parameter. __autoload need not be changed and
__autodefine can live alongside __autoload. Author believes __autoload
should be marked 'deprecated'.


Minimal solution proposal

  __autodefine( $name, $type )

  $name is the string of the missing definition

  $type is the integer identification of the type and defined by constants.


  $type constant            $name format
                        name examples

  T_FUNCTION             [namespace][class name][::|->]function name
a\b\foo, System::boot, SomeClass->getWidth
  T_CLASS                   [namespace]class name
   Image, ns\Image
  T_INTERFACE           [namespace]class name           Image, ns\Image
  T_INCLUDE                file name
  somefile, ../somefile, \includes\Somefile
  T_INCLUDE_ONCE  file name
somefile, ../somefile, \includes\Somefile
  T_REQUIRE                file name
  somefile, ../somefile, \includes\Somefile
  T_REQUIRE_ONCE  file name
somefile, ../somefile, \includes\Somefile


Code examples

  foo(b);            // __autodefine( 'foo', T_FUNCTION )

  p = new PHP();     // __autodefine( 'PHP', T_CLASS )

  include 'piece'    // __autodefine( 'piece', T_INCLUDE )

  ons\foo();         // __autodefine( 'ons\foo', T_FUNCTION )

  p->im();           // __autodefine( 'PHP->im', T_FUNCTION )

  p->cm();           // __autodefine( 'PHP::cm', T_FUNCTION )


Advantages

A whole new array of possibilities opens up for managing code, both at
run time and both at design time (development). Code is no longer
bound to file containers. Small pieces of code can exist on their own.
At run time only the code pieces that are needed for execution are
defined. No longer parsing of complete files when only 5 code lines
will be executed. A parse error in a file not relevant to the piece of
code that will be executed will not prevent execution anymore. By
splitting code up, developers can work side by side on the same code
base, every developer on  a set of code pieces, much smaller than the
files now and thus reducing (locking) conflicts. Code pieces can be
tested standalone and accepted. Progress is measurable on function
level. Requirements can be tied to their functions. Basically, a lot
of metafunctions are suddenly possible because splitting up code in
smaller pieces has become a workable solution. Code could be for
example managed like in a wiki, with page (= code piece) revisions
etc. If needed the code pieces can be assembled into any number of
files for delivery. An extreme solution is assembling all the code
pieces into a zip file and having a run time implementation of
__autodefine that picks definitions from a zip file. While the same
code is available during development in a wiki. Large codebases can be
split up over time into more manageable pieces giving the developers
renewed control over their application. The __autodefine function will
enable all sorts of new ways of managing code and work processes.
Security can be enhanced enormously as it is not common anymore where
definitions will come from and how they are decrypted. Even if someone
gets access to the source code (outside the web root), it might be
scrambled. Also insight into the system can be obtained by observing
definition patterns that can be gathered during the autodefine
processing.


Disadvantages

Initially execution may be slower. However, this can be countered with
different implementations for __autodefine at production time and
development time. The author also believes that others will find ways
to counter this disadvantage by using caching or keeping definitions
in memory inbetween executions.


Conclusion

The minimal solution to support all definitions would be the function
__autodefine( $name, $type ). From there on, every developer can
determine his/her own strategy for automagically defining
implementations. The __autodefine function enables developers to split
code up into smaller pieces as before while at the same time make it
manageable by removing the need to include all these functions. By
splitting code up in smaller pieces more developers can work together
on one (1) code base. A parse error in a function that is not called
will not damage the run time as is the case in the current
implementation where many functions are grouped into files for reasons
of manageability. __autodefine also enables developers to utilize all
sorts of autodefinition mechanisms like retrieving definitions from
the file system, the network, a zip file or even a database. Even
multiple sources can be used, runtime versioning mechanisms can be
utilized, code decryption on the fly is possible. It would be even
interesting if the autodefinition could be in the form of byte codes.

The __autodefine function is generic enough that the same concept can
be applied in most other languages.

The request is to supply at least the minimal __autodefine in a very
near future version of PHP. To be complete and consistent spl_
autodefine_ call, spl_ autodefine_ extensions, spl_ autodefine_
functions, spl_ autodefine_ register, spl_ autodefine_ unregister and
spl_ autodefine should be defined (although considered not necessary
according to the author).

Reinier van Loon

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to