Como decidir entre module_exists e function_exists?

8

Eu estou familiarizado com o uso module_existsem um módulo e em situações como:

No entanto, também existem function_exists, como mostrado na resposta a " É possível declarar uma dependência da biblioteca Javascript no Hook.info? ".

Tenho a impressão de que usar function_existsé uma abordagem mais robusta (segura) em comparação com module_exists. Especialmente se você quiser ter certeza de que alguma função (adicionada em uma versão mais recente de um módulo) está disponível, enquanto, ao usá- module_existslo, você corre o risco de encontrar erros como os seguintes:

  • se um site está ainda usando uma antiga versão de um módulo, que não tem essa função ainda (para que você não deve tentar usá-lo ainda ).
  • se um site está usando uma nova versão de um módulo, que não tem essa função mais (para que você não deve tentar usá-lo mais ).

Minha pergunta : quais são os critérios típicos, ou prós / contras, para decidir usar um module_existsversus function_exists?

Pierre.Vriens
fonte

Respostas:

13

Você sempre deve programar para a API e não para a implementação. Se o Drupal fornece um mecanismo para fazer alguma coisa, use-o.

module_exists()quase sempre deve ser usado para dependências simples de algo fornecido por um módulo Drupal. Você sempre pode obter informações da versão e decidir o que fazer usando system_get_info(). Houve casos em que as funções estão disponíveis quando os módulos foram desativados (alguns dos módulos do carregador automático de classe têm esse problema).

function_exists()deve ser reservado para verificar se um recurso ou biblioteca PHP está disponível. O Core tem alguns exemplos disso em alguns dos drupal_wrappers para manipulação de string e conversão de conjunto de caracteres.

mpdonadio
fonte
10

module_existsé uma função da API Drupal usada para determinar se um módulo está instalado , não foi projetado para fornecer garantias da funcionalidade que um módulo pode conter, incluindo as funções que ele declara.

function_exists é uma função principal do PHP que literalmente determina se existe uma função com um determinado nome na solicitação atual.

Como tal, eles não são realmente comparáveis ​​entre si, você os usa para coisas diferentes. De fato, seria fácil, embora potencialmente redundante, se complementarem, por exemplo,

// 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
fonte
Concordo que eles não são realmente comparáveis entre si
Jimmy Ko
Você quer dizer que o módulo da biblioteca faz check-in MODULENAME_requirementsna postagem vinculada? Sim, isso faria mais sentido como uma chamada para module_exists. Como o MPD mencionou, a maneira de mais alto nível / mais abstraída de garantir que uma dependência tenha certa funcionalidade é examinar o código para uma liberação e fazer com que seu código dependa de uma versão específica com a qual você sabe que seu código funciona. Assim como o Compositor / NPM / Bundler / etc, faça-o
Clive
4

Você está certo, function_existsé uma maneira mais robusta de verificar a existência da função API fornecida pelo módulo contrib. É muito adequado para usar diretamente a API do módulo contrib.

eu uso API de cache de sessão como um exemplo:

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

No entanto, alguns módulos contrib fornecem apenas algumas propriedades ou recursos extras, é muito difícil dizer qual é a função dependente. Nesse caso, você precisa usarmodule_exists

Eu uso o Elements como um exemplo:

if (module_exists('elements')) {
  $form['url'] = array(
    '#type' => 'urlfield',
    // other code
  );
}
else {
  $form['url'] = array(
    '#type' => 'textfield',
    // other code
  );
}
Jimmy Ko
fonte
Interessante! Vou precisar de mais algum tempo para "digerir" ...
Pierre.Vriens
11
Como você saberia se session_cache_setestá sendo fornecido pelo drupal.org/project/session_cache ou outro módulo e, portanto, faz o que deseja?
mpdonadio
11
@MPD Depende se você acredita em todos que usam a mesma estratégia de nomenclatura sugerida. function_existspode impedir erro de função indefinido quando o módulo contrib mudou sua API após a atualização. Claro, o método mais garantia é embrulhar function_existscom module_exitscomo @Clive mencionado, mas, para mim, é muito tedioso.
Jimmy Ko
11
@MPD Teoricamente, a interface de resposta é uma abordagem melhor, e eu adoraria seguir. Mas, na prática, function_exitsna verdade, evitar que o site de completamente intermediação para baixo ...
Jimmy Ko
4

As três respostas (interessantes) anteriores me parecem de alguma forma confirmar minha "percepção" (como descrevi na minha pergunta). Curiosamente, essas respostas foram originalmente escritas independentemente umas das outras (elas foram postadas mais ou menos no mesmo momento, conforme ilustrado na linha do tempo desta pergunta , use o "formato de alternância" para ver "min").

Jimmy KoA resposta de (+ comentários abaixo) ilustra mais alguns exemplos de como o uso function_existspode tornar um módulo mais robusto em relação a possíveis alterações em algum outro módulo que um módulo usa (depende).

A resposta de Clive mostra que você também pode combinar module_existse function_exists, enquanto o comentário abaixo resolveu minhas dúvidas sobre o meu function_existsexemplo (ou seja, ele deveria usarmodule_exists ).

A resposta do mpdonadio (+ comentários abaixo) é, pelo menos para mim, a mais difícil de digerir. Mas depois de revisar o comentário de Shawn Conn abaixo, encontrei mais alguns links que fornecem mais detalhes sobre tudo isso, ou seja:

"Minha conclusão" (depois de digerir as respostas anteriores): deixe que o núcleo do Drupal use function_exists, e os módulos contribuídos / personalizados devem tentar, o máximo possível, manter-se module_exists... embora haja exceções ...

Pierre.Vriens
fonte