28
CRUD Genéricos em PHP. 1ª Parte: Create criado por Marcio Alexandre em 02/05/2010 3:13pm Primeramente explicando o que é CRUD: Create [criar], Retrieve [recuperar], Update [atualizar] e Delete [excluir]. Quero deixar registrado que o foco aqui não é a performance do sistema, ok?! Afinal de contas, as 'tags' que caracterizam esse artigo é bem específico ;) Vamos iniciar, com este, um conjunto de 5 artigos explicando como fazer o famoso CRUD em php orientado à objetos, de forma que não precisemos criar este conjunto de ações a quantidade de vezes que houver funções de acesso a base. Ou seja, nossos objetos estarão mais enxutos e não importando a regra de negócio, poderemos obter as informações necessárias, puxadas no banco de dados, nas camadas acima, utilizando SEMPRE a mesma função, modificando apenas os parâmetros enviados. Basicamente, nas estruturas DAO, já temos os dados do objeto em questão. Como já sabemos para cada objeto temos a estrutura que receberá cada dado referente à sua tabela no banco. Além disso temos também todas as ações deste objeto no sistema (inserts, updates, deletes, selects). Sabendo que este objeto tem um estrutura semelhando à tabela do banco, podemos incrementar um pouco mais essas informações afim de que ela se comunique com nossas classes genéricas, e execute o que está sendo solicitado. Por questão de organização e segurança, deixei as classes CRUD dentro do objeto de conexão com o banco. E nos objetos (DAO) nós importamos as classe e alimentamos os parâmetros. Vamos lá, trazendo o código referente a um funcionário (funcionarioDAO.php), já no padrão de acesso às classes genéricas: class funcionario{ private $nome_tabela = 'tb_funcionario'; private $camposInsert = 'fun_nome,fun_data'; var $id_funcionario; var $fun_nome; var $fun_data;

CRUD Genéricos em PHP

Embed Size (px)

Citation preview

Page 1: CRUD Genéricos em PHP

CRUD Genéricos em PHP. 1ª Parte: Create

criado por Marcio Alexandre em 02/05/2010 3:13pm Primeramente explicando o que é CRUD: Create [criar], Retrieve [recuperar], Update [atualizar] e Delete [excluir].

Quero deixar registrado que o foco aqui não é a performance do sistema, ok?! Afinal de contas, as 'tags' que caracterizam esse artigo é bem específico ;)

Vamos iniciar, com este, um conjunto de 5 artigos explicando como fazer o famoso CRUD em php orientado à objetos, de forma que não precisemos criar este conjunto de ações a quantidade de vezes que houver funções de acesso a base. Ou seja, nossos objetos estarão mais enxutos e não importando a regra de negócio, poderemos obter as informações necessárias, puxadas no banco de dados, nas camadas acima, utilizando SEMPRE a mesma função, modificando apenas os parâmetros enviados.

Basicamente, nas estruturas DAO, já temos os dados do objeto em questão. Como já sabemos para cada objeto temos a estrutura que receberá cada dado referente à sua tabela no banco. Além disso temos também todas as ações deste objeto no sistema (inserts, updates, deletes, selects).Sabendo que este objeto tem um estrutura semelhando à tabela do banco, podemos incrementar um pouco mais essas informações afim de que ela se comunique com nossas classes genéricas, e execute o que está sendo solicitado.

Por questão de organização e segurança, deixei as classes CRUD dentro do objeto de conexão com o banco. E nos objetos (DAO) nós importamos as classe e alimentamos os parâmetros.Vamos lá, trazendo o código referente a um funcionário (funcionarioDAO.php), já no padrão de acesso às classes genéricas:class funcionario{private $nome_tabela    =       'tb_funcionario';private $camposInsert   =       'fun_nome,fun_data';var $id_funcionario;var $fun_nome;          var $fun_data;public function setDados($id_funcionario,$fun_nome,$fun_data){        if (isset($id_funcionario)){ $this->id_funcionario = $id_funcionario ; }else{$this->id_funcionario = null; }        $this->fun_nome         =       $fun_nome       ;        $this->fun_data         =       $fun_data       ;}public function getId(){ return $this->id_funcionario;}public function getNome()       { return $this->fun_nome; }public function getDataBr()     { /*modelo brasil (00/00/0000 00:00)*/ $temp = explode(' ',$this->fun_data); $temp_data = explode('-',$temp[0]); $data = $temp_data[2].'/'.$temp_data[1].'/'.$temp_data[0]; $hora = $temp[1];  return $data.' '.$hora ; }public function getDataEn()     { return $this->fun_data; }

public function getNomeTabela() { return $this->nome_tabela;     }public function getNomeCampos() { return $this->camposInsert; }public function getValorCampos()        { return "'".$this->fun_nome."','".$this->fun_data."' "; }

Page 2: CRUD Genéricos em PHP

public function Salvar($objeto,$db){ $db->insertObjectToDB($objeto); }public function Atualizar($objeto,$db){ $db->updateObjectToDB($objeto); }public function Pegar($fields,$values,$db){ return $db->selectDataDb($this->getNomeTabela(),$fields,$values);}public function PegarTodos($fields,$values,$db){ return $db->selectDatasDb($this->getNomeTabela(),$fields,$values); }public function Deletar($fields,$values,$db){ $db->DeleteDataDb($this->getNomeTabela(), $fields,$values); }}

Observe que adicionamos mais duas variáveis privadas, no objeto, uma que traz o nome da tabela no banco, e a outra trazendo os fields (campos), em sequência como utilizamos nos inserts em sql. Também inserimos duas funções para trazer os valores dessas duas variáveis.

Adicionamos também uma função ( getVAlorCampos() ) que retorna uma string com alguns dados na mesma seqüência da variável privada referente aos campos da tabela ($camposInsert), para inserir os dados. A outras variáveis e funções são comuns aos DAOs.

Na função salvar nós enviamos o objeto em questão, já alimentado, e a variável de referencia ao banco, que traz as classes genéricas.

Observe que é necessário um padrão de nomenclaturas entre o objeto (nome dele mesmo) e o nome da tabela e seus campos. Para tornar o fluxo de informação viável numa classe genérica temos que usar estes padrões:• Nome dos objetos: funcionarioDAO,clienteDAO,produtoDAO.• Nome da classe:funcionario,cliente,produto (respectivamente)• Nome das tabelas: tb_funcionario,tb_cliente,tb_produto (respectivamente).• Nome das páginas: funcionario.php,cliente.php,produtos.php (respectivamente).

Adotando este padrão será possível acessar qualquer tabela baseada no objeto enviado, pois o nome será lido a partir do objeto inserido na classe, e o fluxo automático de páginas no sistema.

Vejamos como a classe de inserção é construída, esta classe estará dentro do objeto ‘banco.php’ (que traz consigo também a abertura de fechamento do banco Mysql):class Banco{        private $local;        private $user;        private $senha;        private $msg0;        private $msg1;        private $nome_db;        private $db;public function __construct(){        $this->local    =       'localhost';        $this->user     =       'root';        $this->senha    =       '';        $this->msg0     =       'Conexão falou, erro: '.mysql_error();        $this->msg1     =       'Não foi possível selecionar o banco de dados!';        $this->nome_db  =       'db_sistemaqualquer';        }public function abrir(){

Page 3: CRUD Genéricos em PHP

        $this->db = mysql_connect($this->local,$this->user,$this->senha) or die($this->msg0);        mysql_select_db($this->nome_db,$this->db) or die($this->msg1);        }public function fechar(){        //analisar se o mysql_close precisa ser colocado numa variável        $closed = mysql_close($this->db);$closed = NULL;}public function insertObjectToDB($objeto){         $db = new Banco();        $db->abrir();        $sql = "INSERT INTO ".$objeto->getNomeTabela()."(".$objeto->getNomeCampos().") VALUES ( ".$objeto->getValorCampos().")";        $query = mysql_query($sql) or die ($sql.' '.mysql_error());        $db->fechar();         unset($objeto);        $temp_id = explode('_',$objeto->getNomeTabela());        header('location: '.$temp_id[1].'.php?msg=Inserido');}} //class

Simples assim, a classe recebe via parâmetro o objeto que quer inserir no banco. A string SQL é montada automaticamente de acordo com os dados que já existem no objeto (neste caso sem wheres, mas nos próximos artigos mostraremos como montar as strings SQL com 1 ou mais wheres).E com os próprios dados que vem do objeto, obedecendo os padrões de nomenclaturas adotados previamento já direciona para próxima página após a inserção.

Agora o mais simples, o formulário de inserção:<html><head><title>Cadastro de Funcion&aacute;rio</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"></head><body><?php if (!$_POST){ $msg    = @$_REQUEST['msg'];if (isset($msg)){echo '<font color="red"> '.$msg.'</font><br><br>';}$link = explode('/',$_SERVER ['REQUEST_URI']);$qtd = count($link); echo '<br>';?><form action="<?php echo $link[$qtd-1]; ?>" method="post"><table width="50%" border="0" cellspacing="0" cellpadding="0">    <tr>       <td width="17%">Nome</td>      <td width="49%"><input name="txtNome" type="text" id="txtNome" size="50"></td>    </tr>    <tr>      <td> </td>      <td> </td>    </tr>    <tr>       <td> </td>      <td><input type="submit" name="Submit" value="Enviar"></td>    </tr>

Page 4: CRUD Genéricos em PHP

    <tr>       <td> </td>      <td> </td>    </tr>  </table></form><?php}else{ require('uses/banco.php');$db = new Banco();require('uses/funcionarioDAO.php');$fun_nome       =       $_POST['txtNome'];$fun_data       =       date('Y-m-d H:i:s');$func = new funcionario();$func->setDados(null,$fun_nome,$fun_data);$func->salvar($func,$db); } ?></body></html>

Portanto, instanciamos o $func, onde alimentamos o objeto com os dados fornecidos pelo formulário, e depois salvamos enviando ele mesmo ($func) e a instância do objeto do banco ($db), via parâmetro.

Só para clarear, utilizamos o $_SERVER ['REQUEST_URI'] para dar o refresh automático, para não precisar se preocupar com mais este campo do formulário, deixando mais dinâmico.

Bom, é isso aí, espero ter contribuído com uma programação mais prática e sem frameworks pesados e muitas vezes desnecessários.Até a 2ª Parte...

CRUD Genéricos em PHP. 2ª Parte: Retrieve (de um objeto)

criado por Marcio Alexandre em 17/06/2010 1:56pm Mais uma vez vamos nós, utilizando o mesmo principio de antes, sem foco no desempenho, e utilização de SQL dinâmicas para suportar o conceito genérico em OO PHP.

Observando os mesmo conceitos da parte ‘CREATE’ destes 5 artigos. Continuemos agora com o Retrieve (ou as famosas ‘consultas’).

Atenção: Este artigo se referente às consultas de um determinado dado que alimentará um objeto, e não o retorno de uma lista de objetos (isso ficará para o próximo artigo, porque tornar possível a leitura de qualquer table, e ‘varrer’ suas possíveis fields, é realmente muito complicado, achei melhor dividir).

Tornarei a repetir algumas conceitos teóricos, para deixar os artigos independentes.

Como já sabemos, para cada objeto temos a estrutura que receberá cada dado referente à

Page 5: CRUD Genéricos em PHP

sua tabela no banco, ou seja, este objeto tem um estrutura semelhando à tabela do banco.

Por questão de organização e segurança, deixei as classes CRUD dentro do objeto de conexão com o banco. E nos objetos (DAO) nós importaremos as classe e alimentamos os parâmetros (aqui estará o segredo de manipulação das wheres).

Vamos lá, trazendo o código referente a um funcionário (funcionarioDAO.php), já no padrão de acesso às classes genéricas:

class funcionario{private $nome_tabela    =       'tb_funcionario';private $camposInsert   =       'fun_nome,fun_data';var $id_funcionario;var $fun_nome;          var $fun_data;public function setDados($id_funcionario,$fun_nome,$fun_data){        if (isset($id_funcionario)){ $this->id_funcionario = $id_funcionario ; }else{$this->id_funcionario = null; }        $this->fun_nome         =       $fun_nome       ;        $this->fun_data         =       $fun_data       ;}public function getId(){ return $this->id_funcionario;}public function getNome()       { return $this->fun_nome; }public function getDataBr()     { /*modelo brasil (00/00/0000 00:00)*/ $temp = explode(' ',$this->fun_data); $temp_data = explode('-',$temp[0]); $data = $temp_data[2].'/'.$temp_data[1].'/'.$temp_data[0]; $hora = $temp[1];  return $data.' '.$hora ; }public function getDataEn()     { return $this->fun_data; }

public function getNomeTabela() { return $this->nome_tabela;     }public function getNomeCampos() { return $this->camposInsert; }public function getValorCampos()        { return "'".$this->fun_nome."','".$this->fun_data."' "; }

public function Salvar($objeto,$db){ $db->insertObjectToDB($objeto); }public function Atualizar($objeto,$db){ $db->updateObjectToDB($objeto); }public function Pegar($fields,$values,$db){ return $db->selectDataDb($this->getNomeTabela(),$fields,$values);}public function PegarTodos($fields,$values,$db){ return $db->selectDatasDb($this->getNomeTabela(),$fields,$values); }public function Deletar($fields,$values,$db){ $db->DeleteDataDb($this->getNomeTabela(), $fields,$values); }}

Observe que adicionamos mais duas variáveis privadas, no objeto, uma que traz o nome da tabela no banco, e a outra trazendo os fields (campos), em sequência como utilizamos nos inserts em sql. Também inserimos duas funções para trazer os valores dessas duas variáveis. Tudo deve ser analisado, inclusive segurança.

Utilizaremos, portanto, nas camadas superiores a função ‘Pegar’.Explicando os parâmetos, ‘$fields’ e ‘$values’ são vetores que trazem os campos e seus valores, com os quais filtraremos nossos dados no banco (refiro-me à where). Aqui está um dos pontos principais do artigo, pois sendo assim, a where pode ser determinada pelo desenvolvedor sem problemas, e pode ser 01 ou mais filtros, basta informar campo e valor, respectivamente, nos vetores.

Page 6: CRUD Genéricos em PHP

Após enviar os parâmetros para função Pegar, a função do banco selectDataDb as recebe, adicionando a função da própria classe getNomeTabela(), e retorna um valor (que iremos abordar mais adiante).

Nos objetos, conforme vemos no code acima, sempre teremos a função getNomeTabela() que retorna nossa variável privada $nome_tabela, previamente alimentada com o nome da tabela no banco a que se refere. Isso torna cada objeto responsável pela sua tabela no banco. No caso, o objeto funcionarioDAO.php consulta só, e somente só, a tabela ‘tb_funcionario‘, e assim sucessivamente, como por exemplo clienteDAO.php acessaria somente a tabela ‘tb_cliente’. Observe a importância de manter o nome da tabela nos demais arquivos.

Ok. Já explicamos a comunicação do objeto consigo mesmo, na chamada da função Pegar. Agora vamos ver a comunicação da aplicação.Faremos aqui uma combo (HTML) básica, alimentaremos o objeto funcionárioDAO com todos os dados do banco, passando os filtros, e imprimiremos o nome dele:

<html><head><title>Atualiza Funcionário</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"></head><body><?php require('uses/banco.php');$db = new Banco();require('uses/funcionarioDTO.php');$fun = new funcionario();if (!$_POST){ $fields[1]      = 'id_funcionario';$values[1]      = $_REQUEST['id'];$objeto         = $fun->Pegar($fields,$values,$db);?><input name="txtNome" type="text" id="txtNome" value="<?php echo $objeto->getNome(); ?>"></body></html>

Até aqui nenhuma novidade. Importamos as classes banco e funcionario. E agora alimentaremos o vetor $fields e $value para filtrar os dados do select. Neste exemplo, estamos querendo trazer um funcionário pelo id dele. Simples, informamos o campo e o valor, respectivamente. Lembro também que caberia aqui qualquer outra Field do banco, ok?! Nenhuma complicação.

Agora vamos entrar na classe do banco e entender.

<?phpclass Banco{        private $local;        private $user;        private $senha;        private $msg0;        private $msg1;        private $nome_db;

Page 7: CRUD Genéricos em PHP

        private $db;        public function __construct(){                $this->local    =       'localhost';                $this->user     =       'root';                $this->senha    =       '';                $this->msg0     =       'Conexão falou, erro: '.mysql_error();                $this->msg1     =       'Não foi possível selecionar o banco de dados!';                $this->nome_db  =       'db_exitosistemas';        }        public function abrir(){                $this->db = mysql_connect($this->local,$this->user,$this->senha) or die($this->msg0);                mysql_select_db($this->nome_db,$this->db) or die($this->msg1);        }        public function fechar(){                //analisar se o mysql_close precisa ser colocado numa variável                $closed = mysql_close($this->db);                $closed = NULL;        }        public function BuscaValor($campo,$tb_name,$fields_where,$values_where){                 $qtd = count($fields_where);                if ($qtd != count($values_where)){ // verifica o numero de fields e values ?>                        <script language="javascript">                                alert('Função: selectDataDb. Erro: Quantidade de campos diferente da quantidade de valores');                </script>        <?php  }else{                // Monta a string SQL=====================                $sql = "select ".$campo." from ".$tb_name;                if ($qtd != 0 ) {                        for ($j=1;$j<=$qtd;$j++){                                if ($j == 1) { $sql .= ' where '; } //garante que o where entre caso tenha algum parâmetro                                $sql .= $fields_where[$j].' = '.$values_where[$j];                                              if ($j<$qtd )  { $sql .= ' and '; }                }                } //=======================================                        $res = mysql_query($sql) or die ($sql .mysql_error());                        $linha = mysql_fetch_array($res);                        return $linha[$campo]; // retorna o valor do campo especifico, com os parametros enviados (podendo ser nenhum ou vários)                }//else        }//public function

        public function selectDataDb($tb_name,$fields_where,$values_where){ // nome da tabela, vetores: campos(fields), valores(values) da consulta                $obj = explode('_',$tb_name);                $new_objeto = new $obj[1];                $db = new Banco();                $db->abrir();

Page 8: CRUD Genéricos em PHP

                $fields = mysql_list_fields('db_tabelaqualquer',$tb_name); // informa os fields/campos da tabela do banco                $columns = mysql_num_fields($fields); //conta o número de campos                for ($i = 0; $i < $columns; $i++) {                        $fields_name    = mysql_field_name($fields, $i);                        $fields_values = $this->BuscaValor(mysql_field_name($fields, $i),$tb_name,$fields_where,$values_where);                         $new_objeto->$fields_name = $fields_values;                }                $db->fechar();                return $new_objeto;        }?>

Ok! Aqui está a classe. Não se assuste pelo tamanho e pela quantidade de laços de repetição. Vamos entender...(eu fiz alguns comentários no código, talvez ajude).

A função selectDataDb() recebe os parâmetros enviados pela função Pegar em FuncionarioDAO. Simples assim! Nenhuma novidade...

Sabemos que ao acessar o banco, precisamos ‘criar’ um objeto de retorno de dados (obedecendo ao Data Access Object). Sendo assim, minha classe tem que entender qual objeto será carregado após o select no banco. Como fazer minha função entender qual objeto o banco irá popular? Agora vai a importância de manter a nomenclatura da tabela do nosso banco, nas demais partes do sistema (nome do objeto, da classe, e por aí vai...).Ao acessar a função selectDataDb(), o nome da tabela é ‘quebrada’ (ultizando o explode do php), para só então, o sistema entender qual objeto será carregado.

               $obj = explode('_',$tb_name);                $new_objeto = new $obj[1];

Nisso tornamos genérica nossa classe. Qualquer objeto pode ser carregado. E sabendo que o objeto carrega em si o nome da própria tabela a que se refere, é automático.

Após isso, nós adentramos e colhemos no banco, quais e quantas fields que lá existe, ‘fisicamente’. Baseado na quantidade de campos existente, fazemos um laço, para buscar o nome do campo e o valor deste campo.Buscar o nome é simples, utilizaremos a função do mysql: mysql_field_name. Onde informamos a posição da Field. Para entender melhor: se numa tabela eu tenho ‘nome,endereco,contato,sexo’, nome seria a posição: 1, endereco: 2, contato: 3, e assim sucessivamente.

               $fields = mysql_list_fields('db_tabelaqualquer',$tb_name); // informa os fields/campos da tabela do banco                $columns = mysql_num_fields($fields); //conta o número de campos                for ($i = 0; $i < $columns; $i++) {                        $fields_name    = mysql_field_name($fields, $i);                        $fields_values = $this->BuscaValor(mysql_field_name($fields, $i),$tb_name,$fields_where,$values_where);

Page 9: CRUD Genéricos em PHP

                        $new_objeto->$fields_name = $fields_values;                }

Para buscar o valor, precisaremos de uma função de auxílio. Senão o código fica muito complicado. E é aqui que fica a construção de nossa SQL Dinâmica.

Envia-se o nome do campo desejado, o nome da tabela, e os vetores que construirão nossas wheres.

$this->BuscaValor(mysql_field_name($fields, $i),$tb_name,$fields_where,$values_where);

Entraremos então na função BuscaValor.Logo na entrada cuidaremos de nosso filtro do select. Quantas cláusulas formarão a where? É necessário saber, e já tratamos isso logo no início.

               $qtd = count($fields_where);

Validamos se a quantidade de fields e seus valores correspondem no IF abaixo.

               if ($qtd != count($values_where)){ // verifica o numero de fields e values ?>                        <script language="javascript">                                alert('Função: selectDataDb. Erro: Quantidade de campos diferente da quantidade de valores');                </script>        <?php  }else{

Caso esteja tudo ok. Prosseguimos para a construção real do select. Um coisa linda (me empolguei... hehehehehe).

               // Monta a string SQL=====================                $sql = "select ".$campo." from ".$tb_name;                if ($qtd != 0 ) {                        for ($j=1;$j<=$qtd;$j++){                                if ($j == 1) { $sql .= ' where '; } //garante que o where entre caso tenha algum parâmetro                                $sql .= $fields_where[$j].' = '.$values_where[$j];                                              if ($j<$qtd )  { $sql .= ' and '; }                }                }

A variável $sql recebe o texto concatenado com os novos valores das variáveis. O IF garante que nossa where receberá algo para ser trabalhado. O laço de repetição varre o vetor, até a quantidade de campos e valores existe no vetor, trazendo TODOS os que fora passados. O primeiro IF depois do For, garante que o a palavra ‘where’ seja concatenada na string $sql, e logo após é concatenado os campos e valores respectivamente. O próximo IF é somente para concatenar a palavra ‘and’ à string citada, caso haja mais campos e valores a serem concatenados.

Nenhum segredo até então. É só substituir o nomes que costumeiramente é usando nos SQL de consulta, por variáveis que receberão os valores em tempo de execução. E nisso consiste a idéia principal do artigo.

Page 10: CRUD Genéricos em PHP

Bom pessoal, sou Marcio Alexandre. Encerro aqui mais este artigo. Talvez tenha ficado algo confuso, devido ao tamanho. Qualquer dúvida, é só entrar em contato.

E mais uma vez, agradeço a atenção, e espero ter contribuído com mais este conhecimento à comunidade OO PHP. =)

Próximo artigo: Retrieve (com retorno de um list de objetos populados). =)

CRUD Genéricos em PHP. 3ª Parte: Retrieve (de vários objetos)

criado por Marcio Alexandre em 23/06/2010 10:51am Mais uma vez vamos nós...

Utilizando o mesmo princípio de antes, sem foco no desempenho, e utilização de SQL dinâmicas para suportar o conceito genérico em OO PHP.

Observando os mesmo conceitos dos outros dois artigos [Create e Retrieve (de um objeto) ]. Continuemos agora com o Retrieve (ou as famosas ‘consultas’) com o retorno de vários objetos (utilizando vetores).

Acredito, que este será o artigo mais complexo, mas nada que não venhamos entender, tendo paciência e atenção.

Tornarei a repetir alguns conceitos teóricos, para deixar este artigo independente dos demais.

Como já sabemos, para cada objeto temos a estrutura que receberá cada dado referente à sua tabela no banco, ou seja, este objeto tem uma estrutura semelhando à tabela do banco. Por questão de organização e segurança, deixei as “classes CRUDs” dentro do objeto ‘banco’. E nos objetos (DAO) nós importaremos as classes e alimentaremos os parâmetros (aqui estará o segredo de manipulação das wheres).

Vamos lá, trazendo o código referente a um funcionário (funcionarioDAO.php), já no padrão de acesso às classes genéricas:

class funcionario{private $nome_tabela    =       'tb_funcionario';private $camposInsert   =       'fun_nome,fun_data';var $id_funcionario;var $fun_nome;          var $fun_data;public function setDados($id_funcionario,$fun_nome,$fun_data){        if (isset($id_funcionario)){ $this->id_funcionario = $id_funcionario ; }else{$this->id_funcionario = null; }        $this->fun_nome         =       $fun_nome       ;        $this->fun_data         =       $fun_data       ;}public function getId(){ return $this->id_funcionario;}

Page 11: CRUD Genéricos em PHP

public function getNome()       { return $this->fun_nome; }public function getDataBr()     { /*modelo brasil (00/00/0000 00:00)*/ $temp = explode(' ',$this->fun_data); $temp_data = explode('-',$temp[0]); $data = $temp_data[2].'/'.$temp_data[1].'/'.$temp_data[0]; $hora = $temp[1];  return $data.' '.$hora ; }public function getDataEn()     { return $this->fun_data; }

public function getNomeTabela() { return $this->nome_tabela;     }public function getNomeCampos() { return $this->camposInsert; }public function getValorCampos()        { return "'".$this->fun_nome."','".$this->fun_data."' "; }

public function Salvar($objeto,$db){ $db->insertObjectToDB($objeto); }public function Atualizar($objeto,$db){ $db->updateObjectToDB($objeto); }public function Pegar($fields,$values,$db){ return $db->selectDataDb($this->getNomeTabela(),$fields,$values);}public function PegarTodos($fields,$values,$db){ return $db->selectDatasDb($this->getNomeTabela(),$fields,$values); }public function Deletar($fields,$values,$db){ $db->DeleteDataDb($this->getNomeTabela(), $fields,$values); }}

Observe que adicionamos mais duas variáveis privadas, no objeto, uma que traz o nome da tabela no banco, e a outra trazendo os fields (campos), em sequência como utilizamos nos inserts em sql. Também inserimos duas funções para trazer os valores dessas duas variáveis. Tudo deve ser analisado, inclusive segurança.

Utilizaremos, portanto, nas camadas superiores a função ‘PegarTodos’.Explicando os parâmetos, ‘$fields’ e ‘$values’ são vetores que trazem os campos e seus valores, com os quais filtraremos nossos dados no banco (refiro-me à where). Aqui está um dos pontos principais do artigo, pois sendo assim, a where pode ser determinada pelo desenvolvedor sem problemas, e pode ser 01 ou mais filtros, basta informar campo e valor, respectivamente, nos vetores.

Após enviar os parâmetros para função PegarTodos, a função do banco selectDatasDb as recebe, adicionando a função da própria classe getNomeTabela(), e retorna um valor (que iremos abordar mais adiante).

Nos objetos, conforme vemos no exemplo acima, sempre teremos a função getNomeTabela() que retorna nossa variável privada $nome_tabela, previamente alimentada com o nome da tabela no banco a que se refere. Isso torna cada objeto responsável pela sua tabela no banco. No caso, o objeto funcionarioDAO.php consulta só, e somente só, a tabela ‘tb_funcionario‘, e assim sucessivamente, como por exemplo clienteDAO.php acessaria somente a tabela ‘tb_cliente’. Observe a importância de manter o nome da tabela nos demais arquivos.

Ok. Já explicamos a comunicação do objeto consigo mesmo, na chamada da função PegarTodos. E vimos que até agora não existe qualquer diferença com o artigo anterior de pegar apenas um objeto em específico.

Agora vamos ver a comunicação da aplicação com o objeto. Faremos aqui uma combo (HTML) básica, alimentaremos o objeto funcionárioDAO com todos os dados do banco, passando os filtros, e traremos todos eles para nossa aplicação:

Page 12: CRUD Genéricos em PHP

<html><body><?php require('uses/banco.php');$db = new Banco();?><select name="id_funcionario"><?phprequire('uses/funcionario_.php');$func = new funcionario();        $objeto = $func->PegarTodos($fields,$values,$db);        foreach($objeto as $m => $obj){ ?>      <option value="<?php echo $obj->getId(); ?>"><?php echo $obj->getNome(); ?></option>        <?php } ?></select></body></html>

Até aqui nenhuma novidade. Importamos as classes banco e funcionario. Agora alimentaremos o vetor $fields e $value para filtrar os dados do select dentro do objeto. Neste exemplo, estamos querendo trazer todos os funcionários existente na base, por isso os fields e values estão vazios, porque não precisa de where específica. Lembro também que caberia aqui QUALQUER filtro, caso houvesse necessidade, ok?! Sem nenhum problema.

Agora vamos entrar na classe do banco e entender. É extremamente parecido com o artigo anterior, porém agora estamos trazendo um ‘list’ de objetos.

<?phpclass Banco{        private $local;        private $user;        private $senha;        private $msg0;        private $msg1;        private $nome_db;        private $db;        public function __construct(){                $this->local    =       'localhost';                $this->user     =       'root';                $this->senha    =       '';                $this->msg0     =       'Conexão falou, erro: '.mysql_error();                $this->msg1     =       'Não foi possível selecionar o banco de dados!';                $this->nome_db  =       'db_exitosistemas';        }public function abrir(){                $this->db = mysql_connect($this->local,$this->user,$this->senha) or die($this->msg0);                mysql_select_db($this->nome_db,$this->db) or die($this->msg1);        }

        public function fechar(){                //analisar se o mysql_close precisa ser colocado numa variável                $closed = mysql_close($this->db);

Page 13: CRUD Genéricos em PHP

                $closed = NULL;        }

        public function BuscaValor( $campo, $tb_name, $fields_where, $values_where ){                 $qtd = count($fields_where);                if ($qtd != count($values_where)){ // verifica o numero de fields e values ?>                        <script language="javascript">                                alert('Função: selectDataDb. Erro: Quantidade de campos diferente da quantidade de valores');                        </script>                <?php  }else{                // Monta a string SQL=====================                $sql = "select ".$campo." from ".$tb_name;                if ($qtd != 0 ) {                        for ($j=1;$j<=$qtd;$j++){                                if ($j == 1) { $sql .= ' where '; }//garante que o where entre caso tenha algum parametro                                $sql .= $fields_where[$j].' = '.$values_where[$j];                                              if ($j<$qtd )  { $sql .= ' and '; }                        }                } //=======================================                        $res = mysql_query($sql) or die ($sql .mysql_error());                        $linha = mysql_fetch_array($res);                        return $linha[$campo]; // retorna o valor do campo especifico, com os parametros enviados (podendo ser nenhum ou vários)                }//else        }//public function                public function selectDatasDb( $tb_name, $fields_where, $values_where){  // nome da tabela, vetores: campos(fields), valores(values) da consulta                $obj = explode('_',$tb_name);                $qtd = count($fields_where);                $db = new Banco();                $db->abrir();

                // <Monta a string SQL> =====================                $sql = "SELECT id_".$obj[1]." FROM ".$tb_name;                if ($qtd >= 1 ) {                        for ($j=1;$j<=$qtd;$j++){                                if ($j == 1) { $sql .= ' WHERE '; }//garante que o where entre caso tenha algum parametro                                $sql .= $fields_where[$j].' = '.$values_where[$j];                                              if ($j<$qtd )  { $sql .= ' AND '; }                        }                } //==================== </Monta a string SQL>

                $query = mysql_query($sql) or die ($sql .mysql_error());                $h = 0; // inicializamos a variável// Laço que trará TODOS os objetos já alimentados        while ($linha = mysql_fetch_array($query)){                        $objDTO = new $obj[1];$fields_where[$qtd+1] = 'id_'.$obj[1];                        $values_where[$qtd+1] =

Page 14: CRUD Genéricos em PHP

$linha[$fields_where[$qtd+1]];                        $fields = mysql_list_fields('db_exitosites',$tb_name); // informa os fields/campos da tabela do banco                        $columns = mysql_num_fields($fields); //conta o número de campos                        $new_objeto[$h] = clone $objDTO; //Aqui declaramos um novo objeto que é clone de nosso DAO, no momento sendo apenas um DTO.                        for ($i = 0; $i < $columns; $i++) {                                $fields_name    = mysql_field_name($fields, $i);                                $fields_values = $this->BuscaValor(mysql_field_name($fields, $i),$tb_name,$fields_where,$values_where);                                $new_objeto[$h]->$fields_name = $fields_values;                        }                        $h += 1; //chamamos o próximo objeto                } //fecha o while, terminando nosso vetor de objetos.                $db->fechar();                return $new_objeto; //retorna todos os objetos populados        }?>

Ok! Aqui está a tão temida classe. Não se assuste pelo tamanho e pela quantidade de laços de repetição (mais do que do artigo anterior). Vamos entender...(eu fiz alguns comentários no código, talvez ajude).

A função selectDatasDb() recebe os parâmetros enviados pela função PegarTodos em FuncionarioDAO. Simples assim! Nenhuma novidade...

Sabemos que ao acessar o banco, precisamos ‘criar’ um objeto de retorno de dados (obedecendo ao Data Access Object). Sendo assim, minha classe tem que entender qual objeto será carregado após o select no banco. Como fazer minha função entender qual objeto o banco irá popular? Agora vai a importância de manter a nomenclatura da tabela do nosso banco, nas demais partes do sistema (nome do objeto, da classe, e por aí vai...).

Ao acessar a função selectDatasDb(), o nome da tabela é ‘quebrada’ (ultizando o ‘explode’ do php), para só então, o sistema entender qual objeto será carregado.

 $obj = explode('_',$tb_name);  $new_objeto = new $obj[1];

Nisso tornamos genérica nossa classe. Qualquer objeto pode ser carregado. E sabendo que o objeto carrega em si o nome da própria tabela a que se refere, é automático.

Aqui montaremos nosso select para saber os registros (linhas) que existem no banco, e colhemos o id de cada um, para só então colhermos os fields e seus valores, e posteriormente popular o objeto:

               // <Monta a string SQL> =====================                $sql = "SELECT id_".$obj[1]." FROM ".$tb_name;                if ($qtd >= 1 ) {                        for ($j=1;$j<=$qtd;$j++){                                if ($j == 1) { $sql .= ' WHERE ';

Page 15: CRUD Genéricos em PHP

}//garante que o where entre caso tenha algum parametro                                $sql .= $fields_where[$j].' = '.$values_where[$j];                                              if ($j<$qtd )  { $sql .= ' AND '; }                        }                } //==================== </Monta a string SQL>

Após isso, enquanto houver registro no banco (linhas ou tuplas), que nós determinamos no while:

while ($linha = mysql_fetch_array($query)){

então ‘varremos’ os dados de cada linha, lembrando que alimentamos mais uma vez os fields e os values dinamicamente. Afinal precisamos dizer qual registro precisamos obter, e passamos por parâmetro o id colhido no select acima:

$fields_where[$qtd+1] = 'id_'.$obj[1];$values_where[$qtd+1] = $linha[$fields_where[$qtd+1]];

Buscar o nome é simples, utilizaremos a função do mysql: mysql_field_name. Onde informamos a posição da Field. Para entender melhor: se numa tabela eu tenho ‘nome,endereco,contato,sexo’, nome seria a posição: 1, endereco: 2, contato: 3, e assim sucessivamente.

               $fields = mysql_list_fields('db_exitosites',$tb_name); // informa os fields/campos da tabela do banco                        $columns = mysql_num_fields($fields); //conta o número de campos                        $new_objeto[$h] = clone $objDTO; //Aqui declaramos um novo objeto que é clone de nosso DAO, no momento sendo apenas um DTO.                        for ($i = 0; $i < $columns; $i++) {                                $fields_name    = mysql_field_name($fields, $i);                                $fields_values = $this->BuscaValor( mysql_field_name( $fields, $i),$tb_name,$fields_where,$values_where);                                $new_objeto[$h]->$fields_name = $fields_values; //aqui populamos com todos os campos e valores o objeto.                        }

Para buscar o valor, precisaremos de uma função de auxílio. Senão o código fica muito complicado. E é aqui que fica a construção de nossa SQL Dinâmica.

Desta vez o nosso ‘for’ ficará dentro de outro laço de repetição ‘while’. Que populará a quantidade de objetos referente às tublas da tabela no banco. Conforme já explicado !

Envia-se o nome do campo desejado, o nome da tabela, e os vetores que construirão nossas wheres.

$this->BuscaValor(mysql_field_name($fields, $i),$tb_name,$fields_where,$values_where);

Entraremos então na função BuscaValor.

Page 16: CRUD Genéricos em PHP

Logo na entrada cuidaremos de nosso filtro do select. Quantas cláusulas formarão a where? É necessário saber, e já tratamos isso logo no início.

               $qtd = count($fields_where);

Validamos se a quantidade de fields e seus valores correspondem no IF abaixo.

               if ($qtd != count($values_where)){ // verifica o numero de fields e values ?>                        <script language="javascript">                                alert('Função: selectDataDb. Erro: Quantidade de campos diferente da quantidade de valores');                </script>        <?php  }else{

Caso esteja tudo ok. Prosseguimos para a construção real do select.

               // Monta a string SQL=====================                $sql = "select ".$campo." from ".$tb_name;                if ($qtd != 0 ) {                        for ($j=1;$j<=$qtd;$j++){                                if ($j == 1) { $sql .= ' where '; } //garante que o where entre caso tenha algum parâmetro                                $sql .= $fields_where[$j].' = '.$values_where[$j];                                              if ($j<$qtd )  { $sql .= ' and '; }                }                } //=======================================

A variável $sql recebe o texto concatenado com os novos valores das variáveis. O IF garante que nossa where receberá algo para ser trabalhado. O laço de repetição varre o vetor, até a quantidade de campos e valores existe no vetor, trazendo TODOS os que fora passados. O primeiro IF depois do For, garante que o a palavra ‘where’ seja concatenada na string $sql, e logo após é concatenado os campos e valores respectivamente. O próximo IF é somente para concatenar a palavra ‘and’ à string citada, caso haja mais campos e valores a serem concatenados.Nenhum segredo até então. É só substituir o nomes que costumamente é usando nos SQL de consulta, por variáveis que receberão os valores em tempo de execução. E nisso consiste a idéia principal do artigo.

A função 'BuscaValor' é idêntica a utilizada na função do artigo anterior, que traz apenas um objeto populado. A modificação (entre trazer um objeto ou um vetor com todos os objetos) aqui é apenas dentro do ‘SelectDatasDb’, que varre todos os registros existentes no banco.Ainda dentro do ‘SelectDatasDb’, para concluir os processos, fechamos o banco e retornamos o vetor com todos os objetos populados:

               $db->fechar();                return $new_objeto; //retorna todos os objetos populados

Pronto! Um pouco complexo, mas factível. =)

O Desempenho aqui deve cair, mas temos uma grande vantagem, na hora da manutenção não precisamos cair nas funções dento do objeto do banco. Basta nos

Page 17: CRUD Genéricos em PHP

preocupar com o carregamento do objeto desejado e à alimentação dos vetores que farão as 'wheres'. Percebam que a ‘regra de negócio’ fica numa camada muito acima, e numa forma de comunicação nada trivial.

Bom pessoal, sou Marcio Alexandre. Encerro aqui mais este artigo. Talvez tenha ficado algo ainda mais confuso, devido ao tamanho. Qualquer dúvida, é só entrar em contato.

E mais uma vez, agradeço a atenção, e espero ter contribuído com mais este conhecimento à comunidade OO PHP.

Próximo artigo: Update. =)

CRUD Genéricos em PHP. 4ª Parte: Update

criado por Marcio Alexandre em 02/04/2012 5:12pm Hellow Comunidade!

Depois de quase dois anos após a implementação dos códigos, e confecção do primeiro artigo sobre CRUD Genérico em PHP, aqui estou!!!

Vamos comentar sobre o Update do assunto abordado no título.

Bom, alerto que por inexperiência, talvez, não usufruí de alguns conceitos OO (herança, overload, overinding, abstract, interface), enfim... o objetivo aqui é outro! Mas, desde já, quem tiver os conceitos solidificados, corrijam em seus códigos. =)

Tornarei a repetir algumas conceitos teóricos, para deixar os artigos independentes.

Como já sabemos, para cada objeto temos a estrutura que receberá cada dado referente à sua tabela no banco, ou seja, este objeto tem um estrutura semelhando à tabela do banco.

Por questão de organização e segurança, deixei as classes CRUD dentro do objeto de conexão com o banco. E nos objetos (DAO) nós importaremos as classe e alimentamos os parâmetros (aqui estará o segredo de manipulação das wheres).

Vamos lá, trazendo o código referente a um funcionário (funcionarioDAO.php), já no padrão de acesso às classes genéricas:

class funcionario{private $nome_tabela    =       'tb_funcionario';private $camposInsert   =       'fun_nome,fun_data';var $id_funcionario;var $fun_nome;          var $fun_data;public function setDados($id_funcionario,$fun_nome,$fun_data){        if (isset($id_funcionario)){ $this->id_funcionario = $id_funcionario ; }else{$this->id_funcionario = null; }        $this->fun_nome         =       $fun_nome       ;

Page 18: CRUD Genéricos em PHP

        $this->fun_data         =       $fun_data       ;}public function getId(){ return $this->id_funcionario;}public function getNome()       { return $this->fun_nome; }public function getDataBr()     { /*modelo brasil (00/00/0000 00:00)*/ $temp = explode(' ',$this->fun_data); $temp_data = explode('-',$temp[0]); $data = $temp_data[2].'/'.$temp_data[1].'/'.$temp_data[0]; $hora = $temp[1];  return $data.' '.$hora ; }public function getDataEn()     { return $this->fun_data; }

public function getNomeTabela() { return $this->nome_tabela;     }public function getNomeCampos() { return $this->camposInsert; }public function getValorCampos()        { return "'".$this->fun_nome."','".$this->fun_data."' "; }

public function Salvar($objeto,$db){ $db->insertObjectToDB($objeto); }public function Atualizar($objeto,$db){ $db->updateObjectToDB($objeto); }public function Pegar($fields,$values,$db){ return $db->selectDataDb($this->getNomeTabela(),$fields,$values);}public function PegarTodos($fields,$values,$db){ return $db->selectDatasDb($this->getNomeTabela(),$fields,$values); }public function Deletar($fields,$values,$db){ $db->DeleteDataDb($this->getNomeTabela(), $fields,$values); }}

Observe que adicionamos mais duas variáveis privadas, no objeto, uma que traz o nome da tabela no banco, e a outra trazendo os fields (campos), em sequência como utilizamos nos inserts em sql. Também inserimos duas funções para trazer os valores dessas duas variáveis. Tudo deve ser analisado, inclusive segurança.

Utilizaremos, portanto, nas camadas superiores a função ‘Atualizar’.

Nos artigos anteriores eu expliquei os parâmetos, ‘$fields’ e ‘$values’ que seriam vetores que trazem os campos e seus valores, com os quais filtraríamos nossos dados no banco (refiro-me à where). Estraríamos aqui um dos pontos principais dos artigos anteriores, pois sendo assim, a where poderia ser determinada pelo desenvolvedor sem problemas, e poderia ser 01 ou mais filtros, bastando informar campo e valor, respectivamente, nos vetores.Neste artigo não precisamos abordar os campos e seus valores. Basicamente, o que teremos é uma lista de objetos sendo exibida na tela (no caso, serão os funcionários, para exemplificar) e ao clicar em uma opção, carregaremos de imediato aquele objeto (utilizando a função “Pegar”, conforme já entendemos no segundo artigo desta série). Após carregar nosso objeto, exibimos os dados no HTML, alteramos o que achamos necessário, e o retornamos para a função “Atualizar” da classe “funcionário”.

Pergunta provável: Como o banco vai saber qual tupla atualizar, onde está o id?

Ao ser exibida a lista de funcionários, o link para alterá-lo deverá enviar o id do objeto escolhido, ou enviar via ‘hidden’. Muito simples de se entender, concorda?Na página de exibição dos dados a serem alterados, teríamos a seguinte estrutura:

//instancio o banco, onde tem minhas funções genéricasrequire('uses/banco.php');$db = new Banco();//Instancio minha classe funcionario

Page 19: CRUD Genéricos em PHP

require('uses/funcionario_.php');$fun = new funcionario();

//Aqui digo que se não for um ‘post’, então é para exibir os dados do funcionário escolhidoif (!$_POST){ //verifica se é uma submissão de formulário ou não// recebo o id do funcionario$fields[1]      = 'id_funcionario';$values[1]      = $_REQUEST['id'];$objeto         = $fun->Pegar($fields,$values,$db);

Para tornar toda estrutura o mais dinâmico possível:// mensagem que informará se foi atualizado, uma vez que é dado o refresh$msg            = @$_REQUEST['msg'];if (isset($msg)){echo '<font color="red"> '.$msg.'</font><br><br>';}//captura do link da página para que o refresh seja automático$link = explode('/',$_SERVER ['REQUEST_URI']);$qtd = count($link); echo '<br>';

Feito isso, inicializamos o formulário de atualização:

<form action="<?php echo $link[$qtd-1]; ?>" method="post">  <table width="50%" border="0" cellspacing="0" cellpadding="0">    <tr>       <td width="17%">Nome</td>      <td width="49%"><input name="txtNome" type="text" id="txtNome" value="<?php echo $objeto->getNome(); ?>"></td>    </tr>    <tr>      <td>        <input type="hidden" name="id_funcionario" id="id_funcionario" value="<?php echo $objeto->getId(); ?>">        <input type="hidden" name="fun_data" id="fun_data" value="<?php echo $objeto->getDataEn(); ?>">      </td>      <td> </td>    </tr>    <tr>       <td> </td>      <td><input type="submit" name="Submit" value="Atualizar"></td>    </tr>    <tr>       <td> </td>      <td> </td>    </tr>  </table></form>

Caso submeta o formulário, os dados serão processados (refresh):

<?php }else{ //buscando os dados REQUEST$id_funcionario = $_POST['id_funcionario']; if (!isset($id_funcionario) || $id_funcionario != ''){        $fun_nome       = $_POST['txtNome']     ;        $fun_data       = $_POST['fun_data'];                        //inserindo no objeto

Page 20: CRUD Genéricos em PHP

        $fun->id_funcionario    = $id_funcionario;        $fun->fun_nome  = $fun_nome;        $fun->fun_data  = $fun_data;                        //chamando função para envio dos dados dinâmicamente      

            $fun->Atualizar($fun,$db);}else{ ?>        <script language="javascript">                alert('Identificador do conteúdo não especificado');                location.href='index.php';             </script><?php  } // else do if (!isset($id_funcionario) ...} // else do if (!$_POST){ ?>

Como vimos nos artigos anteriores... a função/método ‘Atualizar’ da classe Funcionario, evoca o método ‘updateObjectToDB’do banco enviado, enviando o objeto já populado. Como não haverá retorno (o que poderia, a critério do programador, trazer um true ou false, correspondendo a algum critério de controle de try - catch, enfim, possibilidades são inúmeras).

Pronto! Entendido estas arestas que não tratei na época...vamos ao coração deste artigo!

Vamos entrar na classe do banco e entender. As explicações vem no código, e é de fácil entendimento considerando o nome intuitivo dos métodos.

### Updater                     public function updateObjectToDB($objeto){ //15abr2010                // Processando, em execução, a obtenção de dados do objeto passado!                $temp_id                =       explode('_',$objeto->getNomeTabela());                $id_nome                =       'id_'.$temp_id[1]; //criando variável que será representará o id do objeto passado. Aqui é válido informar que há uma padronização no banco de dados em todas as tabelas, no que se refere à nomenclatura                $temp_campos    =       explode(',',$objeto->getNomeCampos()); // Aqui teremos os nomes dos campos da tabela, conforme foi alimentado no objeto.                $temp_valores           =       explode(',',$objeto->getValorCampos()); // Novos dados (ou não) que serão substituidos no banco. Vale lembrar que todos os campos serão substituído, por mais que os dados novos e antigos sejam os mesmos. Um brecha aqui para futuras melhorias, para não perder no quesito processo.                $qtd_campos             =       count($temp_campos); //Variável que armazenará a qtd de campos, afim de nortear a criação dinâmica da string SQL.                //MONTANDO STRING SQL Dinamicamente--------------------------------                $new_string = 'UPDATE '.$objeto->getNomeTabela().' set ';                for ($i=0;$i <= $qtd_campos-1;$i++){                         // concatenação de valores                        $new_string .= $temp_campos[$i].' = '.$temp_valores[$i];                        if ($i < $qtd_campos-1){ $new_string .= ','; }

Page 21: CRUD Genéricos em PHP

                }                // concatena a SQL com a cláusula where.                $new_string .= ' WHERE '.$id_nome.' = '.$objeto->getId().'';                //-----------------------------------------------------                //echo $new_string; break; // caso queria imprimir a string SQL para algum teste (e somente para isto), desabilitar.                //abre o banco submete à mysql_query e fecha                $db = new Banco();                 $db->abrir();                $sql = $new_string;                $query = mysql_query($sql) or die ($sql.' '.mysql_error());                $db->fechar();                 //Redirecionando para página de atualização referida   header('Location:'.$temp_id[1].'_update.php?id='.$objeto->getId().'&msg=Atualizado');        }

Bom, é isso!! Espero que seja útil à comunidade, a intenção é somente esta.

* Estou pensando em hospedar estes codes em algum site controlador de versões, que trabalhe com open source. A ideia é construímos, juntos, esta camada CRUD, baseada em collections (arrays), de maneira simples e segura. Isto pode facilitar muito a vida de alguns analistas/programadores, que prefiram trabalhar com SQL Dinâmicas, e não fazer mais 'n' funções para gerenciar o fluxo de dados entre o banco e a aplicação, e vice-versa. Acredito que com esta despretensiosa solução, podemos atender melhor (quesito: tempo) a gerencia de requisitos e sua manipulação, atendendo inclusive aos conceitos de "metodologias agéis", pois TODA aplicação estaria em cima de cinco funções somente, ou seja, qualquer alteração ou nova implementação, seria rápida e facilmente gerenciável.