Come decidere tra module_exists e function_exists?


8

Ho familiarità con l'utilizzo module_existsin un modulo e l'utilizzo in situazioni come:

Tuttavia, esiste anche function_exists, come mostrato nella risposta a " È possibile dichiarare una dipendenza della libreria Javascript su Hook.info? ".

Ho l'impressione che l'utilizzo function_existssia un approccio più robusto (sicuro) rispetto a module_exists. Soprattutto se vuoi essere sicuro che alcune funzioni (aggiunte in una versione più recente di un modulo) siano disponibili, mentre semplicemente usando module_existsrischi di incorrere in errori come quelli:

  • se un sito è ancora utilizzando una vecchia versione di un modulo, che non ha quella funzione ancora (quindi non si dovrebbe cercare di usarlo ancora ).
  • se un sito è già utilizzando una nuova versione di un modulo, che non ha che la funzione più (quindi non si dovrebbe cercare di usarlo più ).

La mia domanda : quali sono i criteri tipici, o pro / contro, per decidere se utilizzare entrambi i module_existsversus function_exists?

Risposte:


13

È necessario programmare sempre l'API e non l'implementazione. Se Drupal fornisce un meccanismo per fare qualcosa, usalo.

module_exists()dovrebbe quasi sempre essere usato per dipendenze morbide su qualcosa fornito da un modulo Drupal. Puoi sempre ottenere informazioni sulla versione e decidere cosa fare, utilizzando system_get_info(). Ci sono stati casi in cui le funzioni sono disponibili quando i moduli sono stati disabilitati (alcuni moduli del caricatore automatico di classe presentano questo problema).

function_exists()dovrebbe essere riservato per verificare se una funzione o libreria PHP è disponibile. Core ne ha alcuni esempi in alcuni drupal_wrapper per la manipolazione delle stringhe e la conversione dei set di caratteri.


10

module_existsè una funzione API Drupal utilizzata per determinare se un modulo è installato , non è progettato per fornire garanzie sulla funzionalità che un modulo potrebbe contenere, incluse le funzioni che dichiara.

function_exists è una funzione principale di PHP che determina letteralmente se esiste una funzione con un determinato nome nella richiesta corrente.

In quanto tali, non sono realmente comparabili tra loro, li usi per cose diverse. In effetti sarebbe facile, sebbene potenzialmente ridondante, che si completino a vicenda, ad es

// Do something with a specific module 
if (module_exists('foo')) {
  // Check what's available 
  if (function_exists('foo_bar')) {
    // ...
  }
  elseif (function_exists('foo_baz')) {
    // ...
  }
}

Sono d'accordo che non sono davvero paragonabili tra loro
Jimmy Ko

Intendi il modulo della biblioteca fare il check-in MODULENAME_requirementsnel post collegato? Sì, avrebbe più senso una chiamata a module_exists. Come menzionato MPD, il modo più alto / più astratto per garantire che una dipendenza abbia determinate funzionalità consiste nell'esaminare il codice per una versione e fare in modo che il codice si basi su una versione specifica con cui si conosce il codice. Proprio come fanno Composer / NPM / Bundler / ecc.
Clive

4

Hai ragione, function_existsè un modo più efficace per verificare l'esistenza della funzione API fornita dal modulo contrib. È molto adatto per utilizzare direttamente l'API del modulo contrib.

Uso l' API della cache di sessione come esempio:

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

Tuttavia, alcuni moduli contrib forniscono solo alcune proprietà o funzionalità extra, è molto difficile dire quale sia la funzione dipendente. In questo caso, è necessario utilizzaremodule_exists

Uso Elements come esempio:

if (module_exists('elements')) {
  $form['url'] = array(
    '#type' => 'urlfield',
    // other code
  );
}
else {
  $form['url'] = array(
    '#type' => 'textfield',
    // other code
  );
}

Interessante! Avrò bisogno di più tempo per "digerire" ...
Pierre.Vriens,

1
Come faresti a sapere se session_cache_setè stato fornito da drupal.org/project/session_cache o da un altro modulo, e quindi fa quello che vuoi?
mpdonadio

1
@MPD Dipende se credi in tutti usando la stessa strategia di denominazione suggerita. function_existspuò prevenire errori di funzione indefiniti quando il modulo contrib ha cambiato la sua API dopo l'aggiornamento. Naturalmente, il metodo più garanzia è avvolgere function_existscon module_exitscome @Clive menzionato, ma, per me, è troppo noioso.
Jimmy Ko,

1
@MPD In teoria, rispondere all'interfaccia è un approccio migliore e mi piacerebbe seguirlo. Ma in pratica, function_exitsimpedisci davvero che il sito si rompa completamente ...
Jimmy Ko

4

Le precedenti 3 (interessanti) risposte mi sembrano confermare in qualche modo la mia "percezione" (come ho descritto nella mia domanda). È interessante notare che quelle risposte sono state originariamente scritte indipendenti l'una dall'altra (sono state pubblicate più o meno nello stesso momento, come illustrato nella sequenza temporale di questa domanda , utilizzare il "formato di commutazione" per vedere "minuti").

La risposta di Jimmy Ko (+ commenti sotto di essa), illustra alcuni altri esempi di come l'uso function_existspuò rendere un modulo più robusto rispetto alle possibili modifiche in alcuni altri moduli che un modulo utilizza (dipende da).

La risposta di Clive mostra che potresti anche combinare module_existse function_exists, mentre il commento qui sotto ha risolto i miei dubbi sul mio function_existsesempio (cioè dovrebbe piuttosto usare module_exists).

La risposta di mpdonadio (+ commenti sotto di essa) è, almeno per me, la più difficile da digerire. Ma dopo aver esaminato il commento di Shawn Conn sotto di esso, ho trovato alcuni altri collegamenti che forniscono maggiori dettagli su tutto questo, vale a dire:

"La mia conclusione" (dopo aver digerito le risposte precedenti): lascialo al core di Drupal da usare function_exists, e i moduli forniti / personalizzati dovrebbero cercare, per quanto possibile, di attenersi a module_exists... anche se ci sono eccezioni ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.