Wer ein etwas komplexeres Modul erstellt, wird seinen Source-Code dafür in der Regel auf mehrere Ordner und Dateien aufteilen. Diese Ressourcen müssen an der richtigen Stelle geladen werden. In der Drupal-Dokumentation wird hierfür die Funktion module_load_include empfohlen. Die Anwendung führt aber manchmal zu Problemen, die im folgenden dargestellt werden.
Der Einsatz der Funktion module_load_include erfordert, dass Drupal vollständig geladen wurde (Dokumentation: 'fully bootstrapped'). Verwende ich aber hooks in meinem Modul, die schon während des Bootprozesses oder bei der Registrierung des Moduls greifen, z.B. hook_block_info, so scheitert das Laden der Ressourcen mit module_load_include, weil die Funktion drupal_get_path noch nicht zur Verfügung steht (s. Source-Code in der Dokumentation).
Es ist deshalb sicherer, diese Funktion nur einzusetzen, wenn man abhängig vom aktuellen Programmzustand weitere PHP-Sourcen benötigt. Es ergibt sich von selbst, dass man dies nur in Ausnahmesituationen machen sollte, z.B. wenn aus Performance- oder Speicherplatzgründen bestimmte Programmteile dynamisch nachgeladen werden.
Ansonsten gilt für das Einbinden von PHP-Sourcen folgende Regel:
- In der .info - Moduldatei werden mittels files[]=xyz.class.inc oder ähnlich hauptsächlich Klassen und Interfaces angemeldet, die dann von Drupal an der richtigen Stelle geladen werden.
- In der .module - Datei werden in include-Dateien organisierte Funktionen ganz konventionell mit dirname(__FILE__) und require_once (...) geladen.
Folgendes Snippet stellt ein Beispiel für die richtige Deklaration von Include-Dateien in einem Modul dar:
<?php /** * dosomething module file * * Contains all hooks for this module. * The module does something. * * @author Wolfgang Hauertmann <info@hauertmann.com> * @copyright (c) 2014 Wolfgang Hauertmann * @license http://www.gnu.org/licenses/gpl-2.0.html GPL-2.0 * */ // Don't do that: // module_load_include('inc', 'dosomething', 'inc/functions1'); // module_load_include('inc', 'dosomething', 'inc/functions2'); // Do this instead: $modulpath = dirname(__FILE__); require_once("$modulpath/inc/functions1.inc"); require_once("$modulpath/inc/functions2.inc"); /** * Implements hook_block_info(). */ function dosomething_block_info() { .... // this is a critical hook for 'module_load_include' if a function .... // in functions1.inc or functions2.inc is used here. } ...
Da man in der Regel am Anfang eines Projekts nicht genau weiß, welche Hooks man verwendet, sollte man Include-Dateien für Funktionen grundsätzlich immer so einbinden. Klassen und Interfaces werden dann grundsätzlich immer per files[] in der .info-Datei registriert.