Uma das funcionalidades que sinto falta no PHP é o suporte a sobrecarga. Neste primeiro artigo pretendo mostrar uma forma de simular esse recurso, apenas tratando os parâmetros recebidos pelas funções definidas pelo usuário. O resultado pode não ser muito elegante, mas o que nos resta é esperar que isso seja implementado em alguma versão futura.
Em outras linguagens como Java, por exemplo, é possível criar em nossas classes métodos com o mesmo nome mas que esperam parâmetros diferentes, seja na quantidade ou no tipo da variável a ser recebida.
Como em PHP não é possível redefinir um método, podemos fazer o tratamento de parâmetros dentro do próprio método, usando as funções func_num_args(), func_get_args() e algumas funções de verificação de tipo.
Exemplo
Suponha que o método insertUser() é responsável por cadastrar um usuário no sistema. Queremos que o método suporte a inserção de duas maneiras. A primeira é passando um array com todos os seus atributos, e a segunda é passando cada atributo como um parâmetro diferente. Dessa forma, poderíamos ter:
objTeste = new Teste;
objTeste->insertUser(1, "Pedro Padron", "padronaaargh.com.br");
ou então
objTeste = new Teste;
arrayUser = array("id" => 1, "nome" => "Pedro Padron", "email" => "padronaaargh.com.br");
Para isso, devemos criar um método sem a definição de parâmetros, e tratá-los internamente.
<?php
class Teste
{
function insertUser()
{
// obtém o número de parâmetros passados à função
numParametros = func_num_args();
// toma decisões baseando-se no número de parâmetros
if (numParametros == 1)
// se for apenas um parâmetro, espera-se que o mesmo seja
// um array com as informações do usuário
// obtém o primeiro parâmetro
user = func_get_arg(0);
// verifica se o primeiro parâmetro é realmente um array
if (is_array(user))
// aqui você deve inserir um tratamento no array
// para verificar se os campos necessários
// foram passados (id, nome e email)
// insere usuário no sistema
echo "Usuário inserido com sucesso.<br/>";
echo "ID: " . user["id"] . "<br/>";
echo "NOME: " . user["nome"] . "<br/>";
echo "EMAIL: " . user["email"] . "<br/>";
else
// gera um erro se não for um array
echo "Parâmetro passado não é um array: " . user . ".<br/>";
else if (numParametros == 3)
// caso a função receba 3 parâmetros, supõe-se
// que eles sejam 'id', 'nome' e 'email' respectivamente
// insere usuário no sistema
echo "Usuário inserido com sucesso.<br/>";
echo "ID: " . func_get_arg(0) . "<br/>";
echo "NOME: " . func_get_arg(1) . "<br/>";
echo "EMAIL: " . func_get_arg(2) . "<br/>";
else
// se o número de parâmetros for diferente de
// 1 e 3, um erro é gerado.
echo "Quantidade de parâmetros incorreta.<br/>";
echo "Parâmetros recebidos: " . func_num_args();
// crio um objeto da classe Teste
objTeste = new Teste();
// insiro um usuário passando um array com todos os dados
objTeste->insertUser(array("id" => 1, "nome" => "Pedro Padron", "email" => "padronaaargh.com.br"));
echo "<br/>";
// insiro um usuário fornecendo cada atributo como um parâmetro
objTeste->insertUser(2, "George W. Bush", "jackasswhitehouse.gov");
echo "<br/>";
// isso gerará um erro, pois foram passados apenas dois parâmetros
objTeste->insertUser(2, "Tony Blair");
?>
Como visto no exemplo, precisamos utilizar três funções do PHP para fazer o tratamento necessário:
func_num_args()
Retorna o número de parâmetros recebidos pela função.
http://www.php.net/manual/pt_BR/function.func-num-args.php
func_get_args()
Retorna um array de índice numérico contendo todos os parâmetros recebidos.
http://www.php.net/manual/pt_BR/function.func-get-args.php
func_get_arg(int posicao)
Retorna apenas o parâmetro que se encontra na posição “posicao” (início em zero).
http://www.php.net/manual/pt_BR/function.func-get-arg.php
Um exemplo de utilidade desse recurso é quando temos um sistema já em funcionamento e precisamos alterar apenas um método, de forma que ele aceite ser chamado de maneiras diferentes. Ao invés de criarmos um novo método ou renomear o antigo (o que daria um certo trabalho considerando um projeto grande) podemos simplesmente modificá-lo internamente, sem causar nenhum problema ao resto do sistema.
No próximo artigo veremos como podemos simular a sobrecarga de um método baseada no tipo de parâmetros recebidos, exemplo:
getUserInfo(intId);
getUserInfo(stringNome);
Abraços e até mais!