Why do libraries use "! function_exists('function')" always when there is a statement of a function?

Asked

Viewed 134 times

5

I’ve used several PHP libraries and realized that they always use the same statement, whenever there is a declaration of a new function.

if (! function_exists('funcao')) {
    function funcao($arg) {

    }
}

That is, the function should only be declared if it does not exist.

But why this kind of practice? Why worry whether the function exists or not?

If this is to avoid name collision, with the new versions of PHP, which implement namespace, which also function for functions, there is need to make such a statement?

  • 1

    Maybe to support older versions of PHP that do not have the function, for example, hash_equals which only has PHP 5.6 (and above) and support for those who use PHP 5.5 in some way. This can occur within the "system" itself, Wordpress has several versions... If you make a plugin there may or may not be a function, depending on the version you are using, then you use the function_exists to know if it exists or not. These are the possible uses I see. P

  • Got it, @Inkeliz, a lack of standardization in this case, can screw up everything, since in PHP function collision generates a Fatal Error.

3 answers

6


A common example of this is Laravel, specifically the reason is that the functions have names well simpleton and easy conflict with other scripts, as it may be that other scripts have already used it

The reason you don’t use namespaces for functions, which is possible, is so that such functions are accessible without calling them with namespace or use function, this is to facilitate as they are a series of simple functions as said.

In the case of the specific Laravel to observe are actually a number of useful functions that in a future even PHP itself could implement in the core, my opinion

If you have a function that conflicts with an existing function, can be native or not, this will cause a Exception, then this would be a side effect, as per the PSR-1 this is one of the side effects (side-effects) that we should avoid, ie together the statements should never be made:

  • Change behaviors (e.g.: ini_set, error_reporting)
  • Send reply to output (output)
  • Cause Exception

That is, the functions can do this, but only at the moment they are called.

Example of side effects:

Imagine we have a global.php which should contain the statements, it will be included in all files:

<?php

//Pode causar um efeito colateral se já existir uma função com mesmo nome
function view()
{
   //Algo aqui....
}

//Pode causar efeito colateral acaso file.php não exista
include 'file.php';

//Causa efeito colateral, pois envia conteúdo para a saída
echo "<html>\n";

Example of declaration and use without side effect:

global.php:

<?php

//Evita conflito com outros scripts
if (!function_exists('view')) {
    function view()
    {
        //Algo aqui....
    }
}

3rdparty.php:

"Third party" file, which you are using:

<?php

function foo() { ... }
function view() { ... }
function bar() { ... }

index php.:

<?php

include '3rdparty.php';
include 'global.php';
include 'file.php';

echo "<html>\n";

1

Usually this type of check serves more to make a polyfill, ie, have a function that does something if it does not exist.

A common use I see for these cases is how much support for multi byte. Let’s look at the function str_len to get a better idea.

We have three extensions that provide a character count function in a string:

Note that php’s native function does not correctly treat characters that are in some encodings (such as UTF-8), as characters can take more than 1 byte.

For this reason, the most correct is to use the Mb or iconv counting function. But which one is available?

With the following code, we can easily declare a function according to the extensions that are available in php:

if(function_exists('iconv_strlen')) {
  function meu_strlen($entrada) {
    return iconv_strlen($entrada);
  }
} else if (function_exists('mb_strlen') {
  function meu_strlen($entrada) {
    return mb_strlen($entrada);
  }
} else {
  /* Tudo falhou, vamos usar a função do PHP mesmo :( */
  function meu_strlen($entrada) {
    return strlen($entrada);
  }
}

-2

This causes such a function to be defined only if it does not yet exist. Interesting if you need to overwrite any of them, you define yours, and then the framework "question": This function here that I’m going to define now, has the user done it before? If yes, I won’t reset, I’ll let him use the one he did. Otherwise, I’ll define it

Browser other questions tagged

You are not signed in. Login or sign up in order to post.