Back-End

5 fev, 2007

Simulando Sobrecarga de Métodos no PHP

Publicidade

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!