PHP – Função com número de parâmetros indefinido

Para criar uma função que recebe um número variável de parâmetros precisaremos conhecer as funções built-in do PHP, func_num_args, func_get_args, e func_get_arg.

– func_num_args() – Retorna a quantidade de argumentos passados para a função
– func_get_args() – Retorna array de argumentos passados para a função
– func_get_arg(int $pos) – Retorna o argumento da posição informada
 
Exemplo:
 
function hello() {
	if (func_num_args() > 0) {
		$args = func_get_args();
		foreach($args as $arg){
			echo $arg;
		}
	} else {
		echo "Você não passou nenhum param";
	}
}
hello("andafter",".","org"); // Aparecerá "andafter.org"
hello(); // Aparecerá "Você não passou nenhum param" 

Usando funções de callback em javascript para sucesso ou erro

Em mais um post sobre funções como parâmetro de outras funções no javascript, vou mostrar como fazer para passar uma série de funções para determinados fins – como em caso de sucesso, em caso de falha, etc…

Onde sempre vemos isso? Frameworks como jQuery e Prototype dão a opção de você escolher uma função de callback para sucesso de um evento, outra para falha, outra para quando se inicia o drag de um elemento na tela, e por aí vai. Isso é feito passando, ao invés de uma função, uma lista de funções. No caso, para poder dar nome a elas, usamos a estrutura de chave/valor (key/value).

O exemplo abaixo explica como a função wrapper() passa 2 parâmetros e duas funções de callback: uma para sucesso, outra para falha. Na primeira chamada, a função de callback chamada será a de sucesso, pois é possível efetuar a rotina. No outro caso, dará erro, então será usada a função de falha.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script type="text/javascript">
function wrapper(par1, par2) {
    //verifica se o último parâmetro é uma função para chamá-la;
    //os demais parámetros são repassados para a função

    var lastArgument = arguments[arguments.length-1];
   
    try {
        //Classe Math possue o método max(), que retorna o maior valor entre dois parâmetros
        var sum = Math.max(par1, par2);
        //se não for erro, joga (throw) erro
        if(isNaN(sum))
            throw "not a valid result";
        //se chegar até aqui, é um resultado válido e chama função de sucesso
        lastArgument.onSuccess.call(this, sum);
    } catch(e) {
        //se não, chama a função de erro
        lastArgument.onFailure.call(this, e);
    }
       
   
}

function errorHandler(e) {
    alert("Error: " + e);
}

function myFunction(sum) {
    alert(sum);
}
wrapper(10, 2, {onSuccess: myFunction, onFailure:errorHandler}); //será chamado sucesso
wrapper(10, "a", {onSuccess: myFunction, onFailure:errorHandler}); //será chamado erro
</script>
</head>
<body>

</body>
</html>

 

Passando uma função e outros parâmetros para outra função em javascript

Seguindo o que comecei a explicar nesse post sobre como passar funções como parâmetro para outra no javascript, vou mostrar agora rapidamente como passar outros parâmetros – texto, string, o que você precisar.

Esse exemplo abaixo funciona para o caso de você saber exatamente quantos parâmetros serão passados para a função e quantos recebidos pela função de callback.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script type="text/javascript">
function wrapper(par1, par2) {
    //verifica se o último parâmetro é uma função para chamá-la;
    //os demais parámetros são repassados para a função  
    if(arguments.length>0) {
        var lastArgument = arguments[arguments.length-1];
        if(typeof(lastArgument)=="function") {
            lastArgument.call(this, par1, par2);   
        }
    }
}
function myFunction(par1, par2) {
    alert(par1);
    alert(par2);
}
wrapper("a", "b", myFunction);
</script>
</head>
<body>
</body>
</html>

O exemplo funciona da seguinte forma: a função wrapper recebe duas strings e uma função. Nela, verifica-se se o último parâmetro é uma funcão e, se for, ela chama essa função passando essas duas strings como parâmetro.
Note que esse exemplo vale para a função sendo passada como último parâmetro. Ela pode ser passada em outra ordem, mas aí deve ser feita a devida checagem.

Nos próximos post, mostro como receber uma quantidade aleatória de parâmetros e tratar de repassá-los (usando JSON) e como definir funções de callback específicas dependendo de condições na wrapper.

Passando uma função como parâmetro para outra função em javascript

Uma coisa que é muito comum, com a popularização dos frameworks/bibliotecas javascript, é passar uma função como parâmetro para outra, e essa função ser executada depois de algum evento (finalizar uma requsição assíncrona ou acabar o drag"n drop de um elemento, por exemplo).

Mas, como funciona isso? Simples: no javascript, uma function é um Object do javascript. Com isso, ela pode ser passada como parâmetro com a mesma sintaxe de uma variável. Um bom exemplo é:

function myFunction() {
  //faz algo
}

function wrapper(parameter) {
 //faz algo
}

wrapper(myFunction);

No caso, passamos para a função wrapper a função myFunction como parâmetro.

Agora, como fazer para que essa função seja chamada dentro da função wrapper()? Toda função do javascript tem alguns métodos padrão. Um deles é o call(), que com que a função seja exetucada.

function wrapper(parameter) {
    parameter.call(); //executa parameter, que no caso é a função passada como parâmetro
}

Uma boa prática é checar se o parâmetro é mesmo uma função. Para isso, usamos a função typeof() que verifica o tipo do objeto:

function wrapper(parameter) {
    if(typeof(parameter)=="function")
        parameter.call();
}

Segue abaixo o exemplo completo do código para testes:

<html>
<head>
<title>Passando uma função como parâmetro para outra</title>
<script type="text/javascript">
function wrapper(parameter) {
    if(typeof(parameter)=="function")
        parameter.call();
}
function myFunction() {
    alert("teste");
}
wrapper(myFunction);
</script>
</head>
<body>
</body>
</html>

Ao rodar esse exemplo, deverá aparecer na tela um alert com o "teste" impresso.

No próximo post vou explicar como passar além da função outros parâmetros e fazer com que a função wrapper() reconheça os mesmos e repasse para a função myFunction().