Trabalhar com funções dinamicamente em PHP é extremamente simples, basta utilizar uma das duas funções: call_user_func  ou call_user_func_array .

Ambas fazem a mesma coisa, recebem o nome de uma função como uma string e quantos parâmetros forem necessários, em seguida executam a função.

call_user_func  pode receber apenas strings como parâmetros, sendo o primeiro deles o nome da função, e o restante os argumentos. call_user_func_array  recebe o primeiro parâmetro como uma string e o restante como um array.

Você pode executar tanto funções nativas do PHP quanto funções que você mesmo criou com ambas, call_user_func ou call_user_func_array .

Vamos ver na prática como executar funções de maneira dinâmica em PHP.

call_user_func

Vamos fazer uma utilização básica de call_user_func  com uma função nativa do PHP, veja:

<?php
// Uma frase que precisa ser corrigida
$valor = '       Uma     frase    cheia   de espaços    ';

// Converte todos os espaços em apenas um
$valor = call_user_func('preg_replace', '/s+/', ' ', $valor);

// Retorna: Uma frase cheia de espaços 
echo $valor;
?>

Perceba que o primeiro parâmetro é o nome da função que estou tentando executar (neste caso preg_replace), o restante são todos parâmetros para a função que estou executando (ainda preg_replace).

Você pode estar pensando: “Mas por que não chamar a função preg_replace diretamente?“. Eu também pensei a mesma coisa quando vi pela primeira vez as funções call_user_func  e call_user_func_array , porém, em algum momento você vai precisar chamar uma função dinamicamente no seu script, aí elas farão todo o sentido.

Por exemplo, imagine que eu tenho uma função pronta:

<?php
function exibe ( $valor ) {
	echo $valor;
}
?>

Agora vamos supor que eu queira uma função de callback para tratar o valor enviado antes de retornar qualquer coisa, porém, outro desenvolvedor irá criar a nova função, você só precisa deixar uma opção para ele enviar a nova função como parâmetro para a sua função.

Na verdade, isso é muito simples, veja:

<?php
// Sua função agora não é tão simples assim
function exibe ( $valor, $callback = false ) {

	// O parâmetro $callback não é obrigatório, mas se
	// for enviado, chama a função e envia o $valor como
	// parâmetro.
	if ( $callback ) {
	
		// O valor retornado pela função de callback
		// altera o valor de $valor
		$valor = call_user_func( $callback, $valor );
		
	}
	
	// Exibe o novo valor
	echo $valor;
}

// Nossa função de callback remove tudo
// o que não é letra ou número
function callback ( $valor ) {

	return preg_replace('/[^0-9a-zA-Z]/', '', $valor);

}

// Retorna: Oie
exibe( 'Oie!!!', 'callback' );
?>

Se você está acostumado a desenvolver para WordPress, provavelmente já deve estar acostumado a utilizar funções de callback. É exatamente dessa maneira que isso é realizado.

call_user_func_array

É a mesma coisa da função que acabei de descrever, porém, o segundo parâmetro deve ser um array contendo os parâmetros que você está enviando para a função a ser executada. Veja:

<?php
// Valor que precisa de trim
$valor = '       Legal        ';

// É igual a call_user_func, mas só aceita dois parâmetros,
// sendo o segundo sempre um array com todos os argumentos que deseja,
// mesmo que apenas um (como abaixo).
$valor = call_user_func_array( 'trim', array( $valor ) );

// Retorna: "Legal"
echo '"' . $valor . '"';
?>

É exatamente a mesma coisa!

call_user_func e call_user_func_array em classes

Para chamar qualquer uma das funções acima dentro de uma classe, é necessário utilizar o seguinte método:

array( $nome_da_classe, 'nome_da_funcao');

Veja um exemplo:

<?php
class Tutsup
{
	function __construct() {
		// Basta adicionar array( $nome_da_classe, 'função' )
		call_user_func( array( $this, 'exibe'), 'Estou dentro de uma classe!' );
	}
	
	public function exibe( $valor ) {
		echo $valor;
	}
}

// Exibe: Estou dentro de uma classe!
$tutsup = new Tutsup();
?>

Veja o mesmo exemplo com call_user_func_array:

<?php
class Tutsup
{
	function __construct() {
		// Basta adicionar array( $nome_da_classe, 'função' )
		call_user_func_array( array( $this, 'exibe'), array( 'Estou dentro de uma classe!' ) );
	}
	
	public function exibe( $valor ) {
		echo $valor;
	}
}

// Exibe: Estou dentro de uma classe!
$tutsup = new Tutsup();
?>

Concluindo

Conforme descrevi no artigo, você deve utilizar este método com sabedoria, não faz sentido chamar uma função diretamente utilizando call_user_func e call_user_func_array, apenas dinamicamente.

Não deixe de conferir o manual do PHP para maiores informações:

Caso tenha qualquer dúvida, basta perguntar nos comentários.