In einer Reihe von Modulen, die ich geschrieben habe, verwende ich hook_module_implements_alter (), um die * .module-Datei aufzuteilen und Hook-Implementierungen in separate Dateien zu verschieben.
Der Hauptgrund ist, dass ich lange Dateien leidenschaftlich hasse. (und ja, das macht mich unglücklich über viele der Dateien in Drupal 7 und Contrib)
Beispiele:
Ich weiß, dass einige Dinge zu beachten sind:
- Es funktioniert möglicherweise nicht für alle Hooks. ZB booten oder installieren oder Hooks, die nicht über module_implements () aufgerufen werden.
- Aufgrund der Funktionsweise von module_implements () ist es wichtig, die entsprechende Datei in die Implementierung von hook_module_implements_alter () aufzunehmen.
Jetzt hörte ich von einem langjährigen und bekannten Drupal-Entwickler, dass diese Praxis problematisch ist. https://drupal.org/node/2230319 (Themenstarter und Kommentare Nr. 5 und Nr. 11).
Bevor ich anfange, Funktionen zu verschieben, möchte ich von anderen hören, ob und warum dies sowohl technisch als auch ästhetisch schlecht ist.
EDIT: Ich denke, dies könnte in zwei Fragen aufgeteilt werden:
- Ist es gut oder schlecht, Ihre * .module-Datei aufzuteilen, damit Hook-Implementierungen an anderer Stelle ausgeführt werden?
- Ist hook_module_implements_alter () zuverlässig genug oder sollte ich es lieber
include_once __DIR__ . '/MYMODULE.filename.inc'
direkt in der * .module-Datei verwenden? Was könnte möglicherweise schief gehen, wenn Sie dazu hook_module_implements_alter () verwenden?
Antworten:
Ich habe gerade die fehlende Information gefunden.
EDIT: Und noch eine.
Problem mit module_invoke ()
module_invoke_all()
ruft immer aufmodule_implements()
, wodurch die Modul-Include-Datei überprüft wird, indem sowohlhook_hook_info()
und als auch überprüft werdenhook_module_implements_alter()
.Allerdings
module_invoke()
nur Scheckshook_hook_info()
und nichthook_module_implements_alter()
.module_invoke()
heißt zB in_block_render_blocks()
fürhook_block_view()
. Dies bedeutet, dass dieshook_module_implements_alter()
keine gute Lösung ist, um einehook_block_view()
Implementierung in eine separate Datei aufzuteilen .Dies war ein Problem in Crumbs, siehe https://www.drupal.org/node/2328535 .
Bei anderen Hooks funktioniert es im Allgemeinen in Ordnung, aber Sie wissen nie, ob ein bestimmtes Modul
module_invoke()
anstelle von verwendet werden sollmodule_invoke_all()
.Modul_implements () Cache im Bootstrap verschmutzt.
Ein weiteres Problem wird durch ein Kernproblem verursacht, das hier gemeldet wird:
module_implements_cache () kann durch Hook_boot () -Implementierungen verschmutzt werden, die module_invoke_all () direkt oder indirekt aufrufen
Dies gilt nur für Nicht-Boot-Module , bei denen es vorkommen kann, dass die Implementierung von
hook_module_implements_alter()
nie erkannt wird.module_implements($hook)
dass von aufgerufen wirdhook_boot()
.Dies
$hook
kann ein beliebiger zufälliger Hook sein, er muss nicht mit dem Modul verknüpft sein, an dem wir arbeiten.module_implements('module_implements_alter')
dazu, dass aufgerufen wird.hook_module_implements_alter()
. Zu diesem ZeitpunktMODULENAME.module
ist noch nicht enthalten.Für den Rest der Anforderung geht Drupal daher davon aus, dass die Implementierung
MODULENAME_module_implements_alter()
nicht vorhanden ist.MODULENAME_module_implements_alter()
nicht ausgeführt werden.Alternativen
einmalig benötigt
Alternativen wurden bereits erwähnt. Anstelle dieser Tricks kann man die Datei direkt einbinden. Es kann eine winzige Auswirkung auf die Leistung geben, aber dies wird wahrscheinlich von vielen anderen Dingen in Drupal überschattet.
Aber anstatt zu verwenden
module_load_include()
, würde ich eine direktere Lösung vorschlagen:Oder um PHP 5.2-kompatibel zu sein:
Warum nicht module_load_include ()?
Es besteht im Allgemeinen keine Notwendigkeit zum Aufrufen
module_load_include()
, es kann sogar schädlich sein, wenn die * .module-Datei von you-dont-know-where (z. B. fromsettings.php
) enthalten ist und Sie nicht wissen, ob siemodule_load_include()
verfügbar ist.Diese Funktion dient hauptsächlich dazu, den Standort anderer Module zu bestimmen . Wenn Sie jedoch in dasselbe Modul aufnehmen , ist es im Allgemeinen sicherer und einfacher und schneller, mit relativen Dateipfaden und expliziten zu arbeiten
require_once
.Rufen Sie die Hilfsfunktion auf
Wie von Jimajamma erwähnt, können Sie den Hook auch in der Hauptdatei implementieren
*.module
, dann eine andere Datei einschließen und von dort aus eine Hilfsfunktion aufrufen. Dies erfolgt zB in der Display Suite.Diese Lösung ist in Ordnung, obwohl ich denke, dass sie die Hauptdatei immer noch überfüllt und Ihnen noch mehr Orte bietet, an denen Sie suchen können.
Und auch hier können Sie require_once anstelle von verwenden
module_load_include()
, wenn es sich innerhalb desselben Moduls befindet.quelle
require
die zusätzlichen Dateien. Eine gute Namenskonvention für diese Dateien hilft auch, und dann wird das Ganze viel besser analysierbar.hook_hook_info_alter()
stattdessen? Treffen die gleichen Überlegungen / Probleme zu, wenn ichhook_hook_info_alter()
die Hook-Implementierungen in eine separate Datei aufteile?Jedes große Projekt, an dem ich gearbeitet habe, hat die Dinge in überschaubare und leicht zuzuordnende Teile zerlegt. Im Grunde genommen endet es wie hier erwähntes @tenken oder bis zu dem Punkt, an dem es
foo.module
am Ende nur noch Folgendes beinhaltet:Natürlich habe ich auch Situationen gesehen und verwendet, in denen nur Administratoren oder auf andere Weise selten verwendete Hooks enthalten sind, wie:
quelle
Wenn ich versuche, meine .module-Datei auf mehrere Dateien aufzuteilen, mache ich in der Regel das, was Features for D7 für die "enthaltenen" Dateien tut, für die include_once () verwendet wird:
Für D7 verwende ich weiterhin den Namen meines Moduls "Funktionsnamensraum" für diese enthaltenen Dateien, und den Funktionen des privaten Moduls wird normalerweise das Präfix "_MYMODULE_foo ()" vorangestellt.
Diese Antwort ignoriert die gewünschte Verwendung von Autoloading-Klassen und alle OO-bezogenen Muster, die Sie in Ihrem Code verwenden möchten (Code-Abhängigkeiten usw.).
In Ihrer verknüpften Ausgabe möchten Sie hook_module_implements_alter () verwenden, um einen lesbaren Index dafür zu erhalten, welche Dateien welche Funktionen in Ihrer .module-Datei haben. Ich denke, ein vernünftiger Dateiname 'MYMODULE.PURPOSE.inc' reicht aus, um einen Entwickler auf die Verwendung dieser Include-Datei in Ihrem Modul hinzuweisen.
quelle