Wie entscheide ich mich zwischen module_exists und function_exists?

8

Ich bin mit der Verwendung module_existsin einem Modul vertraut und verwende es in Situationen wie:

Es gibt jedoch auch function_exists, wie in der Antwort auf " Ist es möglich, eine Abhängigkeit der Javascript-Bibliothek bei Hook.info zu deklarieren? " Gezeigt .

Ich habe den Eindruck, dass die Verwendung function_existsim Vergleich zu robuster (sicherer) ist module_exists. Insbesondere, wenn Sie sicherstellen möchten, dass eine Funktion (die in einer neueren Version eines Moduls hinzugefügt wurde) verfügbar ist. Wenn Sie jedoch nur diese Funktion verwenden module_exists, besteht die Gefahr, dass Fehler wie diese auftreten:

  • wenn eine Seite ist immer noch mit einer alten Version eines Moduls, das nicht diese Funktion hat noch (so sollte man es nicht versuchen , verwenden noch ).
  • Wenn eine Site bereits eine neue Version eines Moduls verwendet, das diese Funktion nicht mehr hat (Sie sollten also nicht mehr versuchen, sie zu verwenden ).

Meine Frage : Was sind die typischen Kriterien oder Vor- / Nachteile, um sich für die Verwendung von entweder module_existsversus zu entscheiden function_exists?

Pierre.Vriens
quelle

Antworten:

13

Sie sollten immer auf die API und nicht auf die Implementierung programmieren. Wenn Drupal einen Mechanismus bereitstellt, um etwas zu tun, verwenden Sie ihn.

module_exists()sollte fast immer für weiche Abhängigkeiten von etwas verwendet werden, das von einem Drupal-Modul bereitgestellt wird. Sie können jederzeit Versionsinformationen abrufen und mithilfe von entscheiden, was zu tun ist system_get_info(). Es gab Fälle, in denen Funktionen verfügbar waren, wenn Module deaktiviert wurden (einige der Klassen-Autoloader-Module haben dieses Problem).

function_exists()sollte für die Überprüfung reserviert werden, ob eine PHP-Funktion oder -Bibliothek verfügbar ist. Core hat einige Beispiele dafür in einigen drupal_Wrappern für die Manipulation von Zeichenfolgen und die Konvertierung von Zeichensätzen.

mpdonadio
quelle
10

module_existsist eine Drupal-API-Funktion, mit der bestimmt wird, ob ein Modul installiert ist. Sie soll keine Garantie für die Funktionalität eines Moduls geben, einschließlich der deklarierten Funktionen.

function_exists ist eine PHP-Kernfunktion, die buchstäblich bestimmt, ob eine Funktion mit einem bestimmten Namen in der aktuellen Anforderung vorhanden ist.

Als solche sind sie nicht wirklich miteinander vergleichbar, man benutzt sie für verschiedene Dinge. Tatsächlich wäre es für sie leicht, wenn auch möglicherweise überflüssig, sich zu ergänzen, z

// Do something with a specific module 
if (module_exists('foo')) {
  // Check what's available 
  if (function_exists('foo_bar')) {
    // ...
  }
  elseif (function_exists('foo_baz')) {
    // ...
  }
}
Clive
quelle
Ich bin damit einverstanden, dass sie nicht wirklich miteinander vergleichbar sind
Jimmy Ko
Meinen Sie damit, dass das Bibliotheksmodul MODULENAME_requirementsim verlinkten Beitrag eincheckt ? Ja, das wäre als Anruf sinnvoller module_exists. Wie von MPD erwähnt, besteht die übergeordnete / abstraktere Methode, um sicherzustellen, dass eine Abhängigkeit über bestimmte Funktionen verfügt, darin, den Code für eine Version zu untersuchen und Ihren Code auf eine bestimmte Version zu stützen, mit der Ihr Code funktioniert. Genau wie Composer / NPM / Bundler / etc
Clive
4

Sie haben Recht, dies function_existsist eine robustere Methode, um das Vorhandensein der vom Contrib-Modul bereitgestellten API-Funktion zu überprüfen. Es ist sehr gut geeignet, um die API des Contrib-Moduls direkt zu verwenden.

Ich verwende die Session Cache API als Beispiel:

if (function_exists('session_cache_set')) {
  session_cache_set($bin, $data)
}

Einige Contrib-Module bieten jedoch nur einige zusätzliche Eigenschaften oder Funktionen. Es ist sehr schwer zu sagen, um welche abhängige Funktion es sich handelt. In diesem Fall müssen Sie verwendenmodule_exists

Ich benutze Elements als Beispiel:

if (module_exists('elements')) {
  $form['url'] = array(
    '#type' => 'urlfield',
    // other code
  );
}
else {
  $form['url'] = array(
    '#type' => 'textfield',
    // other code
  );
}
Jimmy Ko
quelle
Interessant! Ich brauche noch etwas Zeit, um zu "verdauen" ...
Pierre.Vriens
1
Wie würden Sie wissen, ob session_cache_setes von drupal.org/project/session_cache oder einem anderen Modul bereitgestellt wird , und daher tun , was Sie wollen?
mpdonadio
1
@MPD Es hängt davon ab, ob Sie daran glauben, dass jeder dieselbe Namensstrategie wie vorgeschlagen verwendet. function_existskann undefinierte Funktionsfehler verhindern, wenn das Contrib-Modul seine API nach dem Update geändert hat. Natürlich ist die am meisten garantierte Methode das Umschließen function_existsmit module_exits@Clive, aber für mich ist es zu langweilig.
Jimmy Ko
1
@MPD Theoretisch ist die Beantwortung der Schnittstelle ein besserer Ansatz, und ich würde gerne folgen. Aber in der Praxis function_exitsverhindern Sie in der Tat, dass die Website vollständig herunterfährt ...
Jimmy Ko
4

Die vorherigen 3 (interessanten) Antworten scheinen mir irgendwie meine "Wahrnehmung" zu bestätigen (wie ich in meiner Frage beschrieben habe). Interessanterweise wurden diese Antworten ursprünglich unabhängig voneinander geschrieben (sie wurden mehr oder weniger im selben Moment veröffentlicht, wie in der Zeitleiste dieser Frage dargestellt . Verwenden Sie das "Umschaltformat", um "Minuten" anzuzeigen).

Die Antwort von Jimmy Ko (+ Kommentare darunter) zeigt einige weitere Beispiele dafür, wie die Verwendung function_existseines Moduls gegenüber möglichen Änderungen in einem anderen Modul, das ein Modul verwendet, robuster macht (abhängig davon).

Die Antwort von Clive zeigt, dass Sie sie auch kombinieren können, module_existsund function_existswährend der Kommentar unten meine Zweifel an meinem function_existsBeispiel auflöste (dh es sollte eher verwendet werden module_exists).

Die Antwort von mpdonadio (+ Kommentare darunter) ist zumindest für mich am schwersten zu verdauen. Aber nachdem ich Shawn Conns Kommentar darunter durchgesehen hatte, fand ich ein paar weitere Links, die mehr Details zu all dem enthalten, dh:

"Mein Fazit" (nach dem Zusammenfassen der vorherigen Antworten): Überlassen Sie die Verwendung dem Drupal-Kern function_exists, und beigesteuerte / benutzerdefinierte Module sollten so weit wie möglich versuchen, sich daran zu halten module_exists... obwohl es Ausnahmen gibt ...

Pierre.Vriens
quelle