Question

Is there a way to define few similar php function dynamically in a manner like

define('MAX_LOG_LEVEL', 10);

_log_level( $string, $level = 0 ) {
   global $loglevel;
   if( $level >= $loglevel ) {
     file_put_contents(...);
   }
}

for($level = 0; $level < MAX_LOG_LEVEL; $level++) {
   function _log$level( $string ) {
      _log_level( $string, $level );
   }
}

that's because i have to create my own log routines and to quickly add an log information on demand.

I know the php built in create_function that do not really do what i exactly want because will be necessary to import the reference variable in the function/method that use that

I can't also use the eval() function as explained in this question since it is disabled on the final application hosting.

Was it helpful?

Solution

One way to do it is to assign an anonymous function to a variable and call it like so:

foreach (range(1, 9) as $i)
{

  ${'_log' . $i} = function($string) use ($i)
  {
    echo 'Log ' . $i . ': ' . $string;
  };

}

// Outputs Log 9: Test
$_log9('Test');

Another possibility is to use eval (although you can't use it on your current application it might be possible in future environments):

foreach (range(1, 9) as $i)
{

  eval('

    function _log' . $i . '($string)
    {
      echo \'Log ' . $i . ': \' . $string;
    }

  ');

}

// Outputs Log 9: Test
_log9('Test');

If using this latter method take note of the warning in the manual:

Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.

However, as others have mentioned in the comments, it is perhaps best to not define a unique function for each log-level: instead define a single function with the log-level as a parameter:

function _log($i, $string)
{
  echo 'Log ' . $i . ': ' . $string;
}

// Outputs Log 9: Test
_log(9, 'Test');

A further extension to this is to define the log levels to make it clearer to both yourself and to future programmers what exactly is being logged:

define('_LOG_CRITICAL_ERROR', 9);

function _log($i, $string)
{
  echo 'Log ' . $i . ': ' . $string;
}

// Outputs Log 9: Test
_log(_LOG_CRITICAL_ERROR, 'Test');

OTHER TIPS

Yes, it is possible; you can do this:

$function = '_log' . $level;
$function($string);

This is known as a variable function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top