Construindo CRUD genérico com PHP e PDO

CRUD genérico com PDO no PHPNesse artigo vamos demonstrar um CRUD genérico no PHP utilizando a biblioteca PDO. Ando meu ausente nas publicações devido ao último semestre da faculdade estar corrido, mas a partir de agora pretendo voltar a publicar constantemente. Nesse artigo vou demonstrar uma classe contendo CRUD genérico que construí para acelerar algumas fases no desenvolvimento de projetos em PHP. Como tenho o costume de trabalhar orientado a objetos em PHP, antigamente escrevia classes CRUDs individuais para cada tabela do meu banco de dados, inclusive já postei algumas dessas classes aqui no blog.
 
Outros posts sobre PDO que podem interessar:
 

Vantagens em usar um CRUD genérico

Observando com calma o funcionamento dessas classes, cheguei a conclusão que com algumas modificações e melhorias seria possível utilizar apenas uma classe para realizar operações de INSERT, UPDATE, DELETE e SELECT em qualquer tabela, sem a necessidade criar classes individuais, ou seja, um CRUD genérico.

Sempre que trabalho com CRUD no PHP utilizo a biblioteca PDO por vários motivos, aqui no blog já postei vários artigos sobre PDO demonstrando suas vantagens e principais características. Essa classe foi testada com sucesso apenas com o SGBD MySQL, SQL Server 2008 e PostgreSQL, mas acredito que não haverá problemas com outros banco de dados uma vez que o PDO é extremamente portável para esse tipo de mudança e as instruções SQL são simples não envolvendo características particulares de nenhum tipo de SGBD, facilitando a ideia de um CRUD genérico.

Abaixo vou postar a classe e em seguida explico a funcionalidade de cada método com detalhes:

 

 

Post relacionado:  Consulta - Sistema de Cadastro com PHP + PDO e MySQL

Vamos as explicações dessa classe para CRUD genérico!!

1 – Atributos:

A classe possui 3 atributos privados, o primeiro $pdo guarda a conexão PDO passada como parâmetros no momento da instanciação da classe, o segundo $tabela guarda o nome da tabela que vamos trabalhar no banco de dados, ou seja, uma vez que informamos exemplo ‘TAB_CLIENTE’ todos os métodos irão modificar os dados somente dessa tabela. Terceiro e último atributo $crud é estático e tem a finalidade  de guardar uma instância da própria classe uma vez que estamos trabalhando com padrão de projeto (Criacional) SINGLETON.
 
2 – Método construtor da classe:
O método privado __construct também está seguindo o padrão SINGLETON, ou seja, estou escondendo o método construtor da classe para que a mesma não possa ser instanciada sem passar pelo método getInstance() que veremos adiante. Esse construtor recebe 2 parâmetros ($conexao, $tabela), que serão atribuídos aos seus respectivos atributos da classe.
 

3 – Método getInstance():

O método público e estático getInstance() tem a finalidade de verificar se existe uma instância da classe Crud em memória, se existir ele devolve a mesma senão instância um novo objeto Crud chamando o construtor da classe (__construct) e passando os 2 parâmetros($conexao, $tabela), esse método também faz parte do padrão de projeto SINGLETON.

 

4 – Método para construção da instrução SQL de INSERT:

O método privado buildInsert() tem a função de construir uma instrução SQL de INSERT e posteriormente retornar essa instrução em forma de string. Esse método recebe como parâmetro ($arrayDados) uma array contendo o nome dos campos como chave e os dados que serão inseridos como valores da array. Observem que a partir de agora vamos utilizar uma das vantagens do PDO, montar instruções SQL com parâmetros representados por ‘?‘, ainda não estamos passando os valores para instrução, mais adiante será explicados o porque.
 
5 – Método para construção da instrução de SQL de UPDATE:
O método privado buildUpdate() tem a função semelhante ao método buildInsert(), pois constrói uma instrução SQL e retorna em forma de string, mas dessa vez será para UPDATE dos dados. Outra diferença são os parâmetros que agora são 2, primeiro array de dados ($arrayDados) com chaves contendo o nome dos campos e os dados que serão inseridos como valores, o segundo parâmetro ($arrayCondicao) tem a finalidade de informar quais campos, operadores e valores estarão presentes na cláusula WHERE, esse parâmetro traz maior flexibilidade para classe, uma vez que podemos precisar de várias condições e operadores na instrução UPDATE.

 

Post relacionado:  (Parte 2) Importando planilhas do Excel para o MySQL usando PHP com PDO

6 – Método para construção da instrução SQL de DELETE:

O método privado buildDelete() comos os demais que iniciam com ‘build‘, tem a função de construir uma instrução SQL para DELETE e retornar em forma de string. Esse método recebe apenas 1 parâmetro ($arrayCondicao) tem a finalidade de informar quais campos, operadores e valores estarão presentes na cláusula WHERE.
 
7 – Método para inserir da dados

O método público insert() chama o método privado buildInsert() para montar a instrução SQL de INSERT e repassa o parâmetro ($arrayDados), posteriormente os valores que serão inseridos são carregados com um loop foreach para instrução. Essa função retorna um valor booleano indicando TRUE para sucesso e FALSE para erro.
 
8 – Método para atualizar dados

O método público update() chama o método privado buildUpdate() para montar a instrução SQL de UPDATE e repassa o parâmetro ($arrayDados, $arrayCondicao), posteriormente os valores que serão atualizados são carregados com um loop foreach para instrução e também os valores da condição WHERE  são passados. Essa função retorna um valor booleano indicando TRUE para sucesso e FALSE para erro.

  9- Método para excluir dados

O método público delete() chama o método privado buildDelete() para montar a instrução SQL de DELETE e repassa o parâmetro ($arrayCondicao), posteriormente os valores da condição WHERE são passados. Essa função retorna um valor booleano indicando TRUE para sucesso e FALSE para erro.

10- Método para consultar dados

No método público getSQLGeneric() não usamos nenhum outro método auxiliar na construção da instrução SQL, pois na minha opinição iria deixar mais complexo os parâmetros do método, uma vez que temos características diferentes entre os SGBDs e sairia do objetivo real da classe que é disponibilizar um CRUD genérico. Nesse caso no parâmetro $sql é passado a instrução SQL integra inclusive com o nome da tabela, SELECT, FROM, WHERE, ORDER BY, GROUP BY e etc fica a gosto do usuário, podendo ser acrescentado funcionalidades proprietárias de cada SGBD. No segundo parâmetro $arrayParams são passados os parâmetros da cláusula WHERE na forma de um array, onde geralmente utilizo ‘?’ na instrução clásula WHERE para indicar que será passado um valor através do bindValue() do PDO, esse parâmetro não é obrigatório, uma vez que nem todas as instruções SELECT possuem cláusula WHERE e também podemos optar em passar os valores da condição direto no primeiro parâmetro $sql. O último parâmetro $fetchAll que por defaul vem como TRUE indicando que serão retornadas várias linhas da consulta, se passarmos FALSE será retornado apenas a primeira linha da consulta.

Depois das explicações vou demonstrar como usar essa classe chamando os métodos desse CRUD genérico, como exemplo de conexão vou usar uma tabela de usuários ‘TAB_USUARIO’ e a classe de conexão que já foi explicada nesse link:

 
Observem que nas operações de INSERT, UPDATE e DELETE, foi passado como parâmetro uma array contendo os dados e possui como chave o mesmo nome do campo na tabela ‘TAB_USUARIO’ (‘nome’ => ‘João’), dessa forma a classe identifica qual campo está sendo alterado.

Bom pessoal nesse artigo demonstrei um CRUD genérico, que pode ser utilizada com vários tipos de banco de dados. Utilizo essa classe diariamente em meus sistemas PHP conectados ao MySQL 5.5, SQL Server 2008 R2 e PostgreSQL 9.1 então posso afirmar com toda certeza que ela supre a grande maioria das necessidades de um sistema de cadastro.

Importante salientar também que esse CRUD genérico não resolve todos os problemas na parte de lógica de negócios envolvendo cadastros, existem cenários mais complexos onde essa classe pode não se adaptar como deveria, exigindo instruções mais específicas.

Para o leitor que tiver disponibilidade em testar essa classe com outros SGBDs, deixo aberto a seção de comentários para postar suas experiências e sugestões de melhorias.

 
Abraço e até a próxima …
Tags:,
Show Buttons
Hide Buttons