Ich arbeite derzeit an einem Modul, das eine PHP-Bibliothek eines Drittanbieters benötigt, die im Wesentlichen eine einzelne PHP-Klasse ist. Normalerweise würde ich es in ein include / -Unterverzeichnis legen und hinzufügen
files[] = includes/Foo.php
in meine .info Datei und lass den Drupal 7 Klasse Autoloader sein Ding machen, wenn ich a $foo = new Foo()
.
Ich habe jedoch die Erlaubnis, dieses Modul der Öffentlichkeit zugänglich zu machen, und möchte die Bibliothek lieber nicht in das Modul aufnehmen. Ich bin mir der Komplikationen in Bezug auf die Lizenzierung durchaus bewusst, möchte sie jedoch wegen dieser Frage ignorieren.
Es gibt eine ähnliche Frage: Wie binde ich eine PHP-Bibliothek ein? , aber ich glaube nicht, dass dies mein Dilema beantwortet.
Diese Antworten auf diese Frage sagen , im Wesentlichen die verwenden Bibliotheken API , aber jedes einzelne Modul , dass ich gefunden habe , dass Verwendungen dies nur funktioniert eine libraries_get_path()
die basepath zu bekommen (und enthält Ausweichpfad , wenn es nicht verfügbar ist) und dann tut einem require
oder include
mit einigen Fehlerprüfung (oder nicht). Alle machen so etwas wie:
if (!class_exists('Foo')) {
$path = function_exists('libraries_get_path') ?
libraries_get_path('foo') : 'sites/all/libraries/foo';
if (!include($path . '/Foo.php')) {
// handle this error
}
}
In diesem Fall macht die Bibliotheks-API eigentlich nichts. Ich sehe keinen Vorteil darin, diese gegenüber der alten Methode zu verwenden, bei der Benutzer aufgefordert werden, eine Kopie herunterzuladen und sie im Modulordner selbst abzulegen. Und es ist immer noch das Problem , dass die Modulentwickler noch muss manuell mit der Last tun include
/ require
. Das Facebook-Modul lädt beispielsweise nur die Bibliothek in a hook_init
und das HTML-Purifier-Modul verfügt über eine interne Funktion, mit der jedes Mal geprüft und geladen werden kann, wenn die Bibliothek benötigt wird.
Dies mag eine weit verbreitete Praxis sein, aber es scheint keine bewährte Praxis zu sein.
Sollte mein Modul die Initiative ergreifen und ein deklarieren, hook_libraries_info
damit ich es verwenden kann libraries_load('foo')
? Auch das scheint seltsam.
if (libraries_load($name)) {..}
ist, eine WSOD zu vermeiden, falls die Bibliothek nicht vorhanden ist.Antworten:
In Branch 2.x des Libraries API-Moduls können Entwickler über hook_libraries_info () oder eine .info-Datei für die Bibliothek die folgenden Informationen definieren (siehe libraries.api ):
Die Liste der zu ladenden Dateien wird verwendet, um diese Dateien zu laden, wenn die Bibliothek benötigt wird. Dies bedeutet, dass Ihr Modul keine CSS- und JavaScript-Dateien mit
drupal_add_css()
oder laden mussdrupal_add_js()
, da dies bereits über das Bibliotheks-API-Modul erfolgt. Das Laden der Abhängigkeiten erfolgt über das Bibliotheks-API-Modul, ohne dass das aufrufende Modul etwas unternimmt.Das Modul verwendet lediglich den folgenden Code zum Laden einer Bibliothek. (Siehe Verwenden der Bibliotheks-API 2.x (als Modulentwickler) .)
Wenn Sie nur feststellen müssen, ob eine Bibliothek vorhanden ist, sollte das Modul einen Code verwenden, der dem folgenden ähnlich ist.
Zwischen den Eigenschaften
hook_libraries_info()
kann auch zurückkehren,'download url'
was eigentlich nicht verwendet wird, auch nicht in der Verzweigung 3.x. Möglicherweise wird es in Zukunft verwendet, oder Module von Drittanbietern könnten sich in das Bibliotheks-API-Modul einbinden und die angeforderten, aber fehlenden Bibliotheken herunterladen.quelle
Nach einigem Graben bin ich immer noch nicht davon überzeugt, was die beste Vorgehensweise ist. Inspiriert vom PHPMailer- Modul biete ich dies für klassenbasierte PHP-Bibliotheken an:
Dies verwendet hook_registry_files_alter , um zu prüfen, ob eine Klasse existiert, und fügt der Klassenregistrierung eine Datei hinzu, falls diese nicht gefunden wird (das Äquivalent zu einer
files[] = ...
Zeile in einer Modul-INFO-Datei). Dann stehen die in foo.php definierten Klassen mit dem Autoloader zur Verfügung, sodass die Datei nicht explizit geladen werden muss, bevor die Klasse verwendet wird.Dadurch wird auch eine Softwareanforderung für die Bibliotheks-API erstellt und verwendet, sofern verfügbar. Andernfalls wird ein angemessener Standard verwendet.
Es ist auch eine gute Idee, einige Prüfungen über hook_requirements hinzuzufügen , um sicherzustellen, dass die Datei vorhanden ist, dass der Autoloader die Klasse, die Versionsprüfung usw. findet.
Es ist auch erwähnenswert, dass ein Autoload-Ansatz für die Bibliotheks-API in der Problemwarteschlange diskutiert wird .
quelle
Kurz gesagt: Wenn Sie vorhaben, das Modul für die Öffentlichkeit freizugeben und die Bibliothek (von Drittanbietern) nicht unter GPL steht, müssen Sie Bibliotheken als Abhängigkeit verwenden oder Benutzer bitten, diese Dateien manuell herunterzuladen (dies ist jedoch nicht möglich) Autoload aus der .info-Datei)
In etwas länger:
Der Grund, warum wir das Bibliotheksmodul benötigen, ist im Grunde genommen die Lizenzierung. Egal, ob Sie dieses Modul verwenden oder nicht, Sie schließen diese Datei auf irgendeine Weise ein.
Nun, ich denke, Sie haben keine guten Beispiele für solche Bibliotheken gefunden, die mit dem Modul geliefert wurden. Check out SMTP-Modul und es kommt mit den erforderlichen Klassen, wie es in der GPL ist. ( .info file blob ).
Siehe auch simplehtmldom- Modul, das nur die Datei enthält, aber sonst nichts.
Das nützlichste Modul für Bibliotheken ist, dass Sie Benutzer auffordern können, die Datei an einer beliebigen Stelle hochzuladen. Es ist nicht offensichtlich, dass Benutzer es in den Ordner sites / all / libraries hochladen. Es können sites / example.com / libraries oder ähnliches sein. Das Bibliotheksmodul kann Ihnen dabei helfen, sich auf Ihre eigentliche Arbeit zu konzentrieren, indem es das Verzeichniserkennungsmaterial für Sie erledigt.
Bei benutzerdefinierten Modulen, die ich für meine Kunden entwickle, füge ich normalerweise Dateien in den Modulordner ein und verwende je nach Verwendung der Bibliothek den Eintrag require_once oder .info.
Lizenzprobleme sind nicht der einzige Grund, das Bibliotheksmodul zu verwenden. Was ist, wenn die Bibliothek eines Drittanbieters schnelle Veröffentlichungszyklen aufweist und Ihr Modul nur minimal entwickelt ist? Wenn Sie es in das Modul aufnehmen, müssen Sie jedes Mal eine neue Version erstellen. Sie werden wahrscheinlich kein Release 7.x-1.99 wollen, das dem 7.x-1.0 sehr ähnlich ist.
quelle
Das Hauptproblem scheint das automatische Laden zu sein.
Sie können das Bibliotheksmodul und das xautoload- Modul verwenden.
Dann tun Sie dies in Ihrem eigenen Modul
Dies wird hier ausführlicher erklärt:
xautoload.api.php Weitere Informationen
zum Argument $ api.
Hinweis: Sie können auch eigene "Handler" schreiben, um exotischere Old-School-Muster jenseits von PSR-0 oder PEAR zu implementieren. Wenn Sie dabei Hilfe benötigen, stellen Sie ein Problem in die Warteschlange von xautoload.
Hinweis: Es gibt mehrere Möglichkeiten, die Namespaces Ihrer Bibliothek zu registrieren. Dies ist die einfachste Methode, wenn die Namespaces in jeder Anforderung registriert werden sollen.
quelle