0

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.

9
  • 1
    Explain pls, what you want to achieve? From your example - functions _log0, _log1,... _log9, which calls _log_level($s, 0..9)? Commented Jan 30, 2014 at 11:46
  • 2
    Why not use more descriptive terms like debug, info, warning, error, fatal, etc.? Commented Jan 30, 2014 at 11:48
  • 1
    @andy: simply i think is more elegant have a _log0( something ) instead of _log(0, something) Commented Jan 30, 2014 at 11:50
  • 1
    @user3025491, sorry but in common practice _log0().._log9() is far less elegant than _log(0..9,). It's has a real sense if you have meaningful names like .debug(), .info(), .warn(), .error(), and .critical() as @tyteen4a03 wrote. Commented Jan 30, 2014 at 11:58
  • 1
    Well it's not because you end up clogging the function spaces and it's nowhere near as flexible as the latter. If anything it's 10x worse. Commented Jan 30, 2014 at 11:59

2 Answers 2

3

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');
Sign up to request clarification or add additional context in comments.

Comments

0

Yes, it is possible; you can do this:

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

This is known as a variable function.

2 Comments

this is not I want to achieve: I want to call exactely _log0, _log1, ... Not to have a pointer to them
My code example does call the function with the specified log level in its name. If you want to call many of them, wrap the above in a loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.