Automatic Class Loading Proposal

Jump to: navigation, search


Automatic class loading is a feature that eliminates manual including of PHP files. It can be implemented only if you can derive the location of class from its name. Usually one class needs to be stored in one file.

This is a proposal for standardisation of class naming and class file storage in Moodle using existing Frankenstyle rules.

Pros

  • improved coding style
  • lower memory footprint
  • enforcing of standardised class names and location of source files
  • possibility to replace standard classes in local customisations via custom classloader without core modification

Cons

  • potentially lower performance because current Moodle class names are ambiguous and plugin locations are dynamic, workaround is to start using namespaces and rework plugin listing API

Namespaces

PHP 5.3.0 introduced a new concept called namespaces, this feature would significantly simplify the directory structure of classes directory.

Examples:

  • new \core\xxx_yyy() ---> in lib/classes/xxx_yyy.php
  • new \core\xxx\yyy.php() ---> lib/classes/xxx/yyy.php
  • new \core\event\base.php() ---> lib/classes/event/base.php
  • new \core\event\something_happened() ---> lib/classes/event/something_happened.php
  • new \mod_forum\event\post_rated() ---> mod/forum/classes/event/post_rated.php

Pros:

  • very fast
  • easy to understand
  • fewer backwards compatibility problems

Cons:

  • few core developers know it

Legacy plugin class naming

The general plugin class name should be: plugintype_pluginname_typeofclass_someclass

Unfortunately the pluginname part might contain multiple underscores which may lead to various problems.

The algorithm for finding of the class file location from given class name is:

  1. we have a class aaa_bbb_ccc_ddd_eee_fff
  2. aaa is always the plugin type, it can not be word core or moodle, ex.: mod, tool, block
  3. bbb is a candidate for plugin name, if this plugin exists look for file bbbdir/classes/ccc_ddd_eee_fff.php
  4. if plugin or class does not exist bbb_ccc is another candidate for plugin name, look for bbb_cccdir/classes/ddd_eee_fff.php
  5. repeat until reaching the limit of underscores in plugin name (5?)

Legacy core class naming

The general core class name should be: core_optionalsubsystem_typeofclass_someclass

The algorithm for finding of the class file location from given class name is:

  1. we have a class core_aaa_bbb_ccc
  2. look for file /lib/classes/aaa_bbb_ccc.php

We could also hardcode exception for non-frankenstyle class names and custom file locations.

Potential candidates

  • new events classes
  • admin settings in plugins
  • any new core feature implemented using OOP
  • internal implementation of add-ons
  • some existing core subsytems
  • some existing plugins that already use these rules (ex.: tinymce plugins)

Backwards compatibility

There should not be any significant problems because the classes subdirectory is searched only if class not already included - classloader is used only for missing classes. Please note this proposal does not change Frankenstyle class naming rules for plugins in any way.

We should probably require the use of automatic class loading only in new APIs and let add-on developers decide the rest for themselves. It is also technically possible to migrate some existing classes from lib.php files to /classes/ while keeping 100% backwards compatibility.

Implementation steps

  1. Finalise rules for class names, class file names and locations.
  2. Implement basic loader using current (slow) plugin API.
  3. Improve performance and stability by rewriting get_plugin_types(), get_plugin_list() and friends.
  4. Frankenstyle plugin info API should be self contained without any dependencies.

Frequently asked questions

Why not use existing class loading standard? 
The proposal builds on top of PSR-0, but it must take into account our ambiguous plugin naming rules and dynamic plugin locations.
Is it compatible with 3rd party libraries? 
Most probably yes, Frankenstyle was supposed to resolve this. This biggest current problem are short names without the "core_" prefix, this proposal would finally require all new core things to start with "core_". It is unlikely that other projects use frankenstyle in top most namespace.
Is this compatible with other classloaders? 
Yes. spl_autoload_register() supports multiple class loaders, Frankenstyle loader should be the last one because it will be most expensive.
Is this compatible with code obfuscators? 
No! Moodle already breaks with them and we will never support it. This is GPL, there is no reason to hide anything.
Why only one class per file? 
Because it makes things easier for everybody.

See also