62
Class MyClass{
  private $data=array('action'=>'insert');
  public function insert(){
    echo 'called insert';
  }

  public function run(){
    $this->$this->data['action']();
  }
}

This doesn't work:

$this->$this->data['action']();

Is the only possibility to use call_user_func();?

2 Answers 2

138

Try:

$this->{$this->data['action']}();

Be sure to check if the action is allowed and it is callable


<?php

$action = 'myAction';

// Always use an allow-list approach to check for validity
$allowedActions = [
    'myAction',
    'otherAction',
];

if (!in_array($action, $allowedActions, true)) {
    throw new Exception('Action is not allowed');
}

if (!is_callable([$this, $action])) {
    // Throw an exception or call some other action, e.g. $this->default()
    throw new Exception('Action is not callable');
}

// At this point we know it's an allowed action, and it is callable
$this->$action();

Sign up to request clarification or add additional context in comments.

5 Comments

Be sure to check if the function exists: function_exists() first!
It works. Should I use any security tricks like function exists or functions allowed array ?
@MarekBar If input comes from user, you should always escape it properly.Ideally, use a white-list with allowed actions.
@JesseBunch you don't need to use function_exist if you allready check with is_callable
Worth mentioning that in some versions of PHP, is_callable doesn't respect visibility, as commented in the documentation
17

Reemphasizing what the OP mentioned, call_user_func() and call_user_func_array() are also good options. In particular, call_user_func_array() does a better job at passing parameters when the list of parameters might be different for each function.

call_user_func_array(
    array($this, $this->data['action']),
    $params
);

Comments

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.