¿Cómo decidir entre module_exists y function_exists?


8

Estoy familiarizado con el uso module_existsen un módulo, y usarlo en situaciones como:

Sin embargo, también existe function_exists, como se muestra en la respuesta a " ¿Es posible declarar una dependencia de la biblioteca Javascript en Hook.info? ".

Tengo la impresión de que usar function_existses un enfoque más robusto (seguro) en comparación con module_exists. Especialmente si desea asegurarse de que alguna función (agregada en una versión más nueva de un módulo) esté disponible, mientras que con solo usarla module_exists, corre el riesgo de encontrarse con errores como esos:

  • si un sitio está siendo utilizando una vieja versión de un módulo, que no tiene esa función todavía (lo que no debería tratar de usarlo sin embargo ).
  • si un sitio está ya utilizando una nueva versión de un módulo, que no tiene esa función más (lo que no debería tratar de usarlo más ).

Mi pregunta : ¿cuáles son los criterios típicos, o pros / contras, para decidir el uso de module_existsversus function_exists?

Respuestas:


13

Siempre debe programar en la API y no en la implementación. Si Drupal proporciona un mecanismo para hacer algo, úselo.

module_exists()casi siempre debe usarse para dependencias suaves de algo provisto por un módulo Drupal. Siempre puede obtener información de la versión y decidir qué hacer usando system_get_info(). Ha habido casos en que las funciones están disponibles cuando los módulos se han deshabilitado (algunos de los módulos de carga automática de clase tienen este problema).

function_exists()debe reservarse para verificar si hay disponible una función o biblioteca de PHP. Core tiene algunos ejemplos de esto en algunos de los drupal_contenedores para la manipulación de cadenas y la conversión de juegos de caracteres.


10

module_existses una función API de Drupal que se utiliza para determinar si un módulo está instalado , no está diseñado para ofrecer garantías de la funcionalidad que puede contener un módulo, incluidas las funciones que declara.

function_exists es una función central de PHP que literalmente determina si existe una función con un nombre en la solicitud actual.

Como tal, no son realmente comparables entre sí, los usas para diferentes cosas. De hecho, sería fácil, aunque potencialmente redundante, que se complementaran entre sí, por ejemplo

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

Estoy de acuerdo en que no son realmente comparables entre sí
Jimmy Ko

¿Te refieres al registro del módulo de la biblioteca MODULENAME_requirementsen la publicación vinculada? Sí, eso tendría más sentido como una llamada a module_exists. Como mencionó MPD, la forma más abstracta / de nivel superior para garantizar que una dependencia tenga cierta funcionalidad es examinar el código para una versión y hacer que su código se base en una versión específica con la que sabe que funciona. Al igual que Composer / NPM / Bundler / etc, hazlo
Clive

4

Tiene razón, function_existses una forma más sólida de verificar la existencia de la función API proporcionada por el módulo contrib. Es muy adecuado para usar directamente la API del módulo contrib.

Uso la API de caché de sesión como ejemplo:

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

Sin embargo, algunos módulos contrib solo proporcionan algunas propiedades o características adicionales, es muy difícil decir qué función dependiente es. En este caso, debe usarmodule_exists

Yo uso Elements como ejemplo:

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

¡Interesante! Necesitaré más tiempo para "digerir" ...
Pierre.Vriens

1
¿Cómo saber si session_cache_setestá siendo proporcionada por drupal.org/project/session_cache u otro módulo, y por lo tanto hace lo que quiere?
mpdonadio

1
@MPD Depende de si crees que todos usan la misma estrategia de nomenclatura sugerida. function_existspuede evitar errores de función indefinidos cuando el módulo contrib cambió su API después de la actualización. Por supuesto, el método más garantía es envolver function_existscon module_exitstan @Clive mencionado, pero, para mí, es demasiado tedioso.
Jimmy Ko

1
@MPD Teóricamente, responder a la interfaz es un mejor enfoque, y me encantaría seguir. Pero en la práctica, de function_exitshecho , evite que el sitio se desplace por completo ...
Jimmy Ko

4

Las 3 respuestas (interesantes) anteriores me parecen de alguna manera confirmando mi "percepción" (como describí en mi pregunta). Curiosamente, esas respuestas se escribieron originalmente de forma independiente entre sí (se publicaron más o menos en el mismo momento, como se ilustra en la línea de tiempo de esta pregunta , use el "formato de alternar" para ver "minutos").

La respuesta de Jimmy Ko (+ comentarios debajo) ilustra algunos ejemplos más de cómo el uso function_existspuede hacer que un módulo sea más robusto con respecto a los posibles cambios en algún otro módulo que un módulo usa (depende de).

La respuesta de Clive muestra que también podrías combinar module_existsy function_exists, mientras que el comentario a continuación resolvió mis dudas sobre mi function_existsejemplo (es decir, debería usarlo module_exists).

La respuesta de mpdonadio (+ comentarios debajo) es, al menos para mí, la más difícil de digerir. Pero después de revisar el comentario de Shawn Conn debajo, encontré algunos enlaces más que proporcionan más detalles sobre todo esto, es decir:

"Mi conclusión" (después de digerir las respuestas anteriores): déjelo al núcleo de Drupal para que lo use function_exists, y los módulos contribuidos / personalizados deberían intentar, en la medida de lo posible, apegarse a module_exists... aunque hay excepciones ...

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.