Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Automatic class loading: Difference between revisions

From MoodleDocs
m (Note about intent to not migrate this page to moodledev.io)
 
(12 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Template:WillNotMigrate}}
{{Moodle 2.6}}
{{Moodle 2.6}}


Line 5: Line 6:
==Class naming==
==Class naming==


To be discoverable by the Moodle automatic classloader, classes must adhere to the following class naming rules:
To be discoverable by the Moodle automatic classloader, classes must adhere to some class naming and location rules:
* [[Frankenstyle]] Prefixes
** Core classes must start with the prefix ''core_''.
** Plugin class names must start with names such as ''plugintype_pluginname_''. For example: ''mod_forum_'' (in the example of /mod/forum)
* One class file for each class
* Class file names must be class name without Frankenstyle prefix
** e.g. Class '''mod_forum_some_class''' is stored in file '''mod/forum/classes/some_class.php'''
** e.g. Class '''core_frankenstyle''' class is stored in '''lib/classes/frankenstyle.php'''


==Class files and locations==
* Sit under the '''classes''' directory of every component:
** '''/lib/classes/''' for core component (core).
** '''SUBSYSTEMDIR/classes/''' for subsystem (core_subsystem).
** '''PLUGINDIR/classes/''' for plugins (plugintype_plugin).
:::Note: The list of valid subsystems and plugin types with their corresponding directories [https://github.com/moodle/moodle/blob/master/lib/components.json can be found in code].
* One class file for each class.
* Autoloading is always [[Frankenstyle|Frankenstyle-based]] and it will be important part of the discovery.
* It provides autoloading of both:
** '''Frankenstyle namespaced classes''', where the component name is the namespace ('''\core_user\example''' or '''\mod_forum\example'''). This is the [[Coding style#Namespaces|actual way]] to add new classes to Moodle.
** '''Frankenstyle prefixed classes''', where the component name is the prefix of the class ('''core_user_example''' or '''mod_forum_example'''). This is now considered deprecated and only should be used for existing code or APIs not supporting autoloading.
:::Note: Since June 2020 the later is deprecated, see MDLSITE-6087 for more information.


The Moodle automatic classloader looks for classes only in specific locations (all caps represents a symbolic name, replace it with a real location)
== Frankenstyle namespaced classes ==
* Core classes
** '''/lib/classes/''' and its subdirectories
** '''SUBSYSTEMDIR/classes/''' and its subdirectories
*** The list of subsystems and their respective directories can be found in code (/lib/classes/component.php, function fetch_subsystems)
* Plugin classes
** /PLUGIN/DIR/classes and its subdirectories


==Code Examples==
PHP namespaces are designed to improve code organisation in your projects. Directory structure in classes/ is matching the namespace structure. Main details about their implementation:


Example of autoloaded class in forum module:
* Actual, preferred.
* [[Frankenstyle]] Namespaces:
** Core classes must use the '''namespace core'''.
** Subsystem classes must use the '''namespace core_subsystem'''.
** Plugin classes must use the '''namespace plugintype_pluginname'''
** File names will be the class names (plus the php extension).
*** e.g. Class '''\mod_forum\some_class''' is stored in file '''mod/forum/classes/some_class.php'''
*** e.g. Class '''\core\frankenstyle''' is stored in file '''lib/classes/frankenstyle.php'''
** For more details about valid first and second level namespaces see [[Coding_style#Rules_for_level1]].
 
=== Code examples (namespaced) ===


<code php>
<syntaxhighlight lang="php">
<?php
<?php
// file mod/forum/classes/some_class.php


class mod_forum_some_class {
namespace core\event;
 
// file lib/classes/event/base.php


class base {
}
}
</code>
</syntaxhighlight>


<code php>
<syntaxhighlight lang="php">
<?php
<?php
// file mod/forum/lib.php


// no require_once() necessary here
namespace mod_forum\event;


$instance = new mod_forum_some_class();
// file mod/forum/classes/event/post_read.php


</code>
class post_read extends \core\event\base {


<code php>
}
</syntaxhighlight>


<syntaxhighlight lang="php">
<?php
<?php


// in any file
// in any file


if (class_exists('mod_forum_some_class')) {
\mod_forum\event\post_read::create($post->id, ...)->trigger();
  // do something
 
}
</syntaxhighlight>
</code>
 
== Frankenstyle prefixed classes (deprecated)==


==Namespaces==
Main details about their implementation:


PHP namespaces are designed to improve code organisation in your projects. Directory structure in classes/ is matching the namespace structure.
* Deprecated, only for BC and not autoloaded stuff.
* [[Frankenstyle]] Prefixes:
** Core classes must start with the prefix '''core_'''.
** Subsystem classes must start with the prefix '''core_subsystem'''.
** Plugin classes must start with the prefix '''plugintype_pluginname'''
** File names will be the class names '''without the prefix''' (plus the php extension).
*** e.g. Class '''mod_forum_some_class''' is stored in file '''mod/forum/classes/some_class.php'''
*** e.g. Class '''core_frankenstyle''' class is stored in '''lib/classes/frankenstyle.php'''


=== Code Examples (prefixed)===


Example:
Example of autoloaded class in forum module:


<code php>
<syntaxhighlight lang="php">
<?php
<?php
// file mod/forum/classes/some_class.php


namespace core\event;
class mod_forum_some_class {
 
// file lib/classes/event/base.php


class base {
}
}
</code>
</syntaxhighlight>


<code php>
<syntaxhighlight lang="php">
<?php
<?php
// file mod/forum/lib.php


namespace mod_forum\event;
// no require_once() necessary here


// file mod/forums/classes/event/post_read.php
$instance = new mod_forum_some_class();


class post_read extends \core\event\base {
</syntaxhighlight>


}
<syntaxhighlight lang="php"><?php
</code>
 
<code php>
<?php


// in any file
// in any file


\mod_forum\event\post_read::create($post->id, ...)->trigger();
if (class_exists('mod_forum_some_class')) {
 
  // do something
</code>
}
</syntaxhighlight>


Note there are restrictions on valid choices for the first and second level namespaces in Moodle - see [[Coding_style#Namespaces]] for more info.
== Backwards compatibility ==


==Backwards compatibility==
There are no known issues that could cause backwards incompatibility, however it is strongly recommended to use the classes subdirectory only for classes that are included automatically.
There are no know issues that could cause backwards incompatibility, however it is strongly recommended to use the classes subdirectory only for classes that are included automatically.


==Performance and developer mode==
== Performance and developer mode ==


Class autoloading improves performance and reduces memory footprint. Location of all classes is automatically stored in class map cache, the cache is updated automatically before upgrade or installation, during cache reset and in developer mode.
Class autoloading improves performance and reduces memory footprint. Location of all classes is automatically stored in class map cache, the cache is updated automatically before upgrade or installation, during cache reset and in developer mode.
Line 113: Line 128:
Otherwise the new class would not be found.
Otherwise the new class would not be found.


==See also==
== See also ==


* [[Frankenstyle]]
* [[Frankenstyle]]

Latest revision as of 16:19, 30 April 2024


Warning: This page is no longer in use. The information contained on the page should NOT be seen as relevant or reliable.


Moodle 2.6


This document describes how to use the functionality of the automatic classloader provided by Moodle.

Class naming

To be discoverable by the Moodle automatic classloader, classes must adhere to some class naming and location rules:

  • Sit under the classes directory of every component:
    • /lib/classes/ for core component (core).
    • SUBSYSTEMDIR/classes/ for subsystem (core_subsystem).
    • PLUGINDIR/classes/ for plugins (plugintype_plugin).
Note: The list of valid subsystems and plugin types with their corresponding directories can be found in code.
  • One class file for each class.
  • Autoloading is always Frankenstyle-based and it will be important part of the discovery.
  • It provides autoloading of both:
    • Frankenstyle namespaced classes, where the component name is the namespace (\core_user\example or \mod_forum\example). This is the actual way to add new classes to Moodle.
    • Frankenstyle prefixed classes, where the component name is the prefix of the class (core_user_example or mod_forum_example). This is now considered deprecated and only should be used for existing code or APIs not supporting autoloading.
Note: Since June 2020 the later is deprecated, see MDLSITE-6087 for more information.

Frankenstyle namespaced classes

PHP namespaces are designed to improve code organisation in your projects. Directory structure in classes/ is matching the namespace structure. Main details about their implementation:

  • Actual, preferred.
  • Frankenstyle Namespaces:
    • Core classes must use the namespace core.
    • Subsystem classes must use the namespace core_subsystem.
    • Plugin classes must use the namespace plugintype_pluginname
    • File names will be the class names (plus the php extension).
      • e.g. Class \mod_forum\some_class is stored in file mod/forum/classes/some_class.php
      • e.g. Class \core\frankenstyle is stored in file lib/classes/frankenstyle.php
    • For more details about valid first and second level namespaces see Coding_style#Rules_for_level1.

Code examples (namespaced)

<?php

namespace core\event;

// file lib/classes/event/base.php

class base {
}
<?php

namespace mod_forum\event;

// file mod/forum/classes/event/post_read.php

class post_read extends \core\event\base {

}
<?php

// in any file

\mod_forum\event\post_read::create($post->id, ...)->trigger();

Frankenstyle prefixed classes (deprecated)

Main details about their implementation:

  • Deprecated, only for BC and not autoloaded stuff.
  • Frankenstyle Prefixes:
    • Core classes must start with the prefix core_.
    • Subsystem classes must start with the prefix core_subsystem.
    • Plugin classes must start with the prefix plugintype_pluginname
    • File names will be the class names without the prefix (plus the php extension).
      • e.g. Class mod_forum_some_class is stored in file mod/forum/classes/some_class.php
      • e.g. Class core_frankenstyle class is stored in lib/classes/frankenstyle.php

Code Examples (prefixed)

Example of autoloaded class in forum module:

<?php
// file mod/forum/classes/some_class.php

class mod_forum_some_class {

}
<?php
// file mod/forum/lib.php

// no require_once() necessary here

$instance = new mod_forum_some_class();
<?php

// in any file

if (class_exists('mod_forum_some_class')) {
  // do something
}

Backwards compatibility

There are no known issues that could cause backwards incompatibility, however it is strongly recommended to use the classes subdirectory only for classes that are included automatically.

Performance and developer mode

Class autoloading improves performance and reduces memory footprint. Location of all classes is automatically stored in class map cache, the cache is updated automatically before upgrade or installation, during cache reset and in developer mode.

There is only one inconvenience - if you add new class or remove it you need to do one of the following:

  • visit yourserver/admin/index.php
  • purge caches
  • or add $CFG->debug = (E_ALL | E_STRICT); to your config.php

Otherwise the new class would not be found.

See also