Sistema de Cadastro em PHP e MySQL usando PDO

      Nenhum comentário em Sistema de Cadastro em PHP e MySQL usando PDO

Autor: Roberto Beraldo
Fonte: http://blog.ultimatephp.com.br/sistema-de-cadastro-php-mysql-pdo/

Um módulo que está presente em praticamente todos os projetos é o Sistema de Cadastro.

Seja de usuários, de produtos ou de qualquer outra coisa, quase sempre precisamos de cadastros.

Neste artigo vou mostrar como desenvolver um simples sistema de cadastro, usando PHP e MysQL, utilizando a biblioteca PDO.

Vamos fazer um sistema de cadastro de usuários, com nome, email, gênero (sexo) e data de nascimento.

E tem duas surpresas!

Você ainda vai ganhar de brinde funções para converter datas e calcular idade! 🙂

Estrutura do Sistema de Cadastro

Vamos fazer um sistema de cadastro simples, porém bem estruturado e seguro.

Teremos uma tela de listagem de usuários, uma de cadastro, uma de edição e outra de remoção.

O famoso CRUD.

No final, vamos ficar com estes arquivos:

  • add.php: script que processa o cadastro de usuário
  • delete.php: script que processa a remoção de usuário
  • edit.php: script que processa a edição de usuário
  • form-add.php: formulário de cadastro de usuário
  • form-edit.php: formulário de edição de usuário
  • functions.php: arquivo de funções
  • index.php: listagem de usuários cadastrados
  • init.php: arquivo de inicialização (Bootstrapping)

Parece muita cosia?

Calma…

É coisa simples.

Vamos ver parte por parte, uma de cada vez.

Estrutura do Banco de Dados

Como dizem: “First Things First“.

Vamos começar pelo começo: modelagem do banco de dados.

Nosso banco será bem simples, apenas com uma tabela de usuários.

1
2
3
4
5
6
7
8
CREATE TABLE users(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT, -- id
    name VARCHAR(60) NOT NULL, -- nome
    email VARCHAR(80) NOT NULL, -- email
    gender ENUM('m', 'f') NOT NULL, -- gênero (masculino, feminino)
    birthdate DATE NOT NULL, -- data de nascimento
    PRIMARY KEY(id)
) COLLATE=utf8_unicode_ci;

Arquivo de Funções

Nosso arquivo de funções, o functions.php, terá este conteúdo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
 
/**
 * Conecta com o MySQL usando PDO
 */
function db_connect()
{
    $PDO = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8', DB_USER, DB_PASS);
 
    return $PDO;
}
 
/**
 * Converte datas entre os padrões ISO e brasileiro
 */
function dateConvert($date)
{
    if ( ! strstr( $date, '/' ) )
    {
        // $date está no formato ISO (yyyy-mm-dd) e deve ser convertida
        // para dd/mm/yyyy
        sscanf($date, '%d-%d-%d', $y, $m, $d);
        return sprintf('%02d/%02d/%04d', $d, $m, $y);
    }
    else
    {
        // $date está no formato brasileiro e deve ser convertida para ISO
        sscanf($date, '%d/%d/%d', $d, $m, $y);
        return sprintf('%04d-%02d-%02d', $y, $m, $d);
    }
    return false;
}
/**
 * Calcula a idade a partir da data de nascimento
 *
 */
function calculateAge($birthdate)
{
    $now = new DateTime();
    $diff = $now->diff(new DateTime($birthdate));
    
    return $diff->y;
}

A função db_connect faz a conexão com o MySQL, usando a Biblioteca PDO. Se você não conhece PDO ou não sabe como usá-la, veja este meu artigo, onde explico, passo-a-passo, como usar PDO com MySQL.

A função dateConvert converte datas entre os formatos ISO e brasileiro. Você pode ler mais sobre isso neste meu artigo.

Por fim, a função calculateAge calcula a idade a partir da data de nascimento, no formato YYYY-MM-DD. Para esse cálculo, usei a Classe DateTime. Se você não conhece a classe DateTime, recomendo ler este meu artigo.

Arquivo de Inicialização

Aqui vamos criar o arquivo init.php, definindo algumas configurações gerais do nosso projeto.

Isso inclui as credenciais de acesso ao banco de dados.

Mas você pode colocar neste arquivo qualquer outra configuração do PHP, como definir timezone, habilitar e desabilitar exibições de erro e por aí vai.

O arquivo de inicialização (Bootstrapping) deve ser chamado em todos os nossos scripts. Assim teremos um ambiente consistente e organizado, sempre com todas as mesmas configurações.

Se quiser ir um pouco mais a fundo nesse assunto, recomendo ler este meu artigo, onde falo sobre Bootstrapping. Mostro algumas técnicas um pouco mais avançadas sobre esse tema.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
 
// constantes com as credenciais de acesso ao banco MySQL
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'ultimatephp_artigos');
 
// habilita todas as exibições de erros
ini_set('display_errors', true);
error_reporting(E_ALL);
date_default_timezone_set('America/Sao_Paulo');
 
// inclui o arquivo de funçõees
require_once 'functions.php';

Página Inicial do Sistema de Cadastro

Chegamos à nossa index.php, onde vamos exibir a lista de usuários já cadastrados.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
require_once 'init.php';
// abre a conexão
$PDO = db_connect();
// SQL para contar o total de registros
// A biblioteca PDO possui o método rowCount(), mas ele pode ser impreciso.
// É recomendável usar a função COUNT da SQL
$sql_count = "SELECT COUNT(*) AS total FROM users ORDER BY name ASC";
// SQL para selecionar os registros
$sql = "SELECT id, name, email, gender, birthdate FROM users ORDER BY name ASC";
// conta o toal de registros
$stmt_count = $PDO->prepare($sql_count);
$stmt_count->execute();
$total = $stmt_count->fetchColumn();
// seleciona os registros
$stmt = $PDO->prepare($sql);
$stmt->execute();
?>
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Sistema de Cadastro - ULTIMATE PHP</title>
    </head>
    <body>
        
        <h1>Sistema de Cadastro - ULTIMATE PHP</h1>
        
        <p><a href="form-add.php">Adicionar Usuário</a></p>
        <h2>Lista de Usuários</h2>
        <p>Total de usuários: <?php echo $total ?></p>
        <?php if ($total > 0): ?>
        <table width="50%" border="1">
            <thead>
                <tr>
                    <th>Nome</th>
                    <th>Email</th>
                    <th>Gênero</th>
                    <th>Data de Nascimento</th>
                    <th>Idade</th>
                    <th>Ações</th>
                </tr>
            </thead>
            <tbody>
                <?php while ($user = $stmt->fetch(PDO::FETCH_ASSOC)): ?>
                <tr>
                    <td><?php echo $user['name'] ?></td>
                    <td><?php echo $user['email'] ?></td>
                    <td><?php echo ($user['gender'] == 'm') ? 'Masculino' : 'Feminino' ?></td>
                    <td><?php echo dateConvert($user['birthdate']) ?></td>
                    <td><?php echo calculateAge($user['birthdate']) ?> anos</td>
                    <td>
                        <a href="form-edit.php?id=<?php echo $user['id'] ?>">Editar</a>
                        <a href="delete.php?id=<?php echo $user['id'] ?>" onclick="return confirm('Tem certeza de que deseja remover?');">Remover</a>
                    </td>
                </tr>
                <?php endwhile; ?>
            </tbody>
        </table>
        <?php else: ?>
        <p>Nenhum usuário registrado</p>
        <?php endif; ?>
    </body>
</html>

Os principais pontos estão comentados no script.

Um ponto importante é o que está destacado entre as linhas 7 a 11.

Para contar o número de registros, costumamos usar mysqli_num_rows (ou mysql_num_rows, na antiga biblioteca mysql). Porém no PDO isso pode ser um pouco mais trabalhoso.

Até existe o método rowCount, mas ele pode não funcionar com alguns SGBDs. Com o MySQL ele funciona. Você pode usar rowCount em vez de executar a query do COUNT, mas eu preferi mostrar a forma portável (que funciona com outros SGBDs também), afinal, se estamos usando PDO, queremos ter independência de SGBD, certo?

Você pode entender melhor por que não é recomendado usar rowCount com consultas SELECT lendo o Exemplo #2 da documentação de rowCount.

Dito isso, vamos ver o que o script exibe…

Obviamente, nada, pois não cadastramos nenhum usuário.

Se você for uma pessoa impaciente, pode fazer um INSERT direto no MySQL, para ver como ele vai aparecer na tela.

Mas não se desespere. Vamos criar a parte de cadastro agora mesmo.

Formulário de Cadastro

Agora vamos começar a dar vida ao nosso Sistema de Cadastro!

Vamos criar o formulário por onde vamos cadastrar novos usuários.

Crie o arquivo form-add.php com este conteúdo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
require 'init.php';
?>
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Cadastro de Usuário - ULTIMATE PHP</title>
    </head>
    <body>
        <h1>Sistema de Cadastro - ULTIMATE PHP</h1>
        <h2>Cadastro de Usuário</h2>
        
        <form action="add.php" method="post">
            <label for="name">Nome: </label>
            <br>
            <input type="text" name="name" id="name">
            <br><br>
            <label for="email">Email: </label>
            <br>
            <input type="text" name="email" id="email">
            <br><br>
            
            Gênero:
            <br>
            <input type="radio" name="gender" id="gener_m" value="m">
            <label for="gener_m">Masculino </label>
            <input type="radio" name="gender" id="gener_f" value="f">
            <label for="gener_f">Feminino </label>
            
            <br><br>
            <label for="birthdate">Data de Nascimento: </label>
            <br>
            <input type="text" name="birthdate" id="birthdate" placeholder="dd/mm/YYYY">
            <br><br>
            <input type="submit" value="Cadastrar">
        </form>
    </body>
</html>

Sem segredos…

Só um simples formulário.

Script de Cadastro

Agora precisamos processar o envio do formulário de cadastro.

Aqui entra o add.php, que terá este conteúdo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
require_once 'init.php';
// pega os dados do formuário
$name = isset($_POST['name']) ? $_POST['name'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$gender = isset($_POST['gender']) ? $_POST['gender'] : null;
$birthdate = isset($_POST['birthdate']) ? $_POST['birthdate'] : null;
// validação (bem simples, só pra evitar dados vazios)
if (empty($name) || empty($email) || empty($gender) || empty($birthdate))
{
    echo "Volte e preencha todos os campos";
    exit;
}
// a data vem no formato dd/mm/YYYY
// então precisamos converter para YYYY-mm-dd
$isoDate = dateConvert($birthdate);
// insere no banco
$PDO = db_connect();
$sql = "INSERT INTO users(name, email, gender, birthdate) VALUES(:name, :email, :gender, :birthdate)";
$stmt = $PDO->prepare($sql);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);
$stmt->bindParam(':gender', $gender);
$stmt->bindParam(':birthdate', $isoDate);
if ($stmt->execute())
{
    header('Location: index.php');
}
else
{
    echo "Erro ao cadastrar";
    print_r($stmt->errorInfo());
}

A validação está super simples. Apenas verifico se os campos possuem valor.

O objetivo aqui é mostrar como fazer um Sistema de Cadastro, por isso não dei muito foco à validação.

Ok…

Agora já dá pra começar a brincar.

Cadastre alguns usuários, e você verá a lista deles na página inicial.

Formulário de Edição

Agora vamos implementar a edição de usuários.

Começando pelo formulário, no arquivo form-edit.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
require 'init.php';
// pega o ID da URL
$id = isset($_GET['id']) ? (int) $_GET['id'] : null;
// valida o ID
if (empty($id))
{
    echo "ID para alteração não definido";
    exit;
}
// busca os dados du usuário a ser editado
$PDO = db_connect();
$sql = "SELECT name, email, gender, birthdate FROM users WHERE id = :id";
$stmt = $PDO->prepare($sql);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// se o método fetch() não retornar um array, significa que o ID não corresponde a um usuário válido
if (!is_array($user))
{
    echo "Nenhum usuário encontrado";
    exit;
}
?>
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Edição de Usuário - ULTIMATE PHP</title>
    </head>
    <body>
        <h1>Sistema de Cadastro - ULTIMATE PHP</h1>
        <h2>Edição de Usuário</h2>
        
        <form action="edit.php" method="post">
            <label for="name">Nome: </label>
            <br>
            <input type="text" name="name" id="name" value="<?php echo $user['name'] ?>">
            <br><br>
            <label for="email">Email: </label>
            <br>
            <input type="text" name="email" id="email" value="<?php echo $user['email'] ?>">
            <br><br>
            
            Gênero:
            <br>
            <input type="radio" name="gender" id="gener_m" value="m" <?php if ($user['gender'] == 'm'): ?> checked="checked" <?php endif; ?>>
            <label for="gener_m">Masculino </label>
            <input type="radio" name="gender" id="gener_f" value="f" <?php if ($user['gender'] == 'f'): ?> checked="checked" <?php endif; ?>>
            <label for="gener_f">Feminino </label>
            
            <br><br>
            <label for="birthdate">Data de Nascimento: </label>
            <br>
            <input type="text" name="birthdate" id="birthdate" placeholder="dd/mm/YYYY" value="<?php echo dateConvert($user['birthdate']) ?>">
            <br><br>
            <input type="hidden" name="id" value="<?php echo $id ?>">
            <input type="submit" value="Alterar">
        </form>
    </body>
</html>

Em linhas gerais, esse arquivo é bem parecido com o form-add.php.

O que muda é o seguinte…

No começo, temos que pegar o ID da URL e buscar os dados do usuário, para deixar os inputs preenchidos.

Depois colocamos esses valores nos inputs. Detalhe para os radio buttons, que precisam de um if para definir o valor do atributo checked.

o ID do registro a ser editado é armazenado em um campo oculto (hidden), para que seja resgatado no edit.php, via POST.

Script de Edição

Agora vamos criar o script que recebe os valores para edição e atualiza no banco de dados.

Crie o arquivo edit.php com este conteúdo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
require_once 'init.php';
// resgata os valores do formulário
$name = isset($_POST['name']) ? $_POST['name'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$gender = isset($_POST['gender']) ? $_POST['gender'] : null;
$birthdate = isset($_POST['birthdate']) ? $_POST['birthdate'] : null;
$id = isset($_POST['id']) ? $_POST['id'] : null;
// validação (bem simples, mais uma vez)
if (empty($name) || empty($email) || empty($gender) || empty($birthdate))
{
    echo "Volte e preencha todos os campos";
    exit;
}
// a data vem no formato dd/mm/YYYY
// então precisamos converter para YYYY-mm-dd
$isoDate = dateConvert($birthdate);
// atualiza o banco
$PDO = db_connect();
$sql = "UPDATE users SET name = :name, email = :email, gender = :gender, birthdate = :birthdate WHERE id = :id";
$stmt = $PDO->prepare($sql);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);
$stmt->bindParam(':gender', $gender);
$stmt->bindParam(':birthdate', $isoDate);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
if ($stmt->execute())
{
    header('Location: index.php');
}
else
{
    echo "Erro ao alterar";
    print_r($stmt->errorInfo());
}

Bem parecido com o nosso add.php, né?

Poucas coisas mudaram…

Além de nome, email, gênero e data de nascimento, pegamos o ID, que estava no campo oculto.

Depois, em vez do INSERT, fizemos um UPDATE, filtrando pelo id na cláusula WHERE.

Agora já podemos cadastrar e alterar. Só falta remover…

Script de Remoção

Nosso arquivo delete.php terá este conteúdo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
require_once 'init.php';
// pega o ID da URL
$id = isset($_GET['id']) ? $_GET['id'] : null;
// valida o ID
if (empty($id))
{
    echo "ID não informado";
    exit;
}
// remove do banco
$PDO = db_connect();
$sql = "DELETE FROM users WHERE id = :id";
$stmt = $PDO->prepare($sql);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
if ($stmt->execute())
{
    header('Location: index.php');
}
else
{
    echo "Erro ao remover";
    print_r($stmt->errorInfo());
}

Pronto!

Agora está tudo 100%!

Dá pra listar, cadastrar, editar e remover!

Nosso CRUD está completo!

Conclusão

Deu um pouco de trabalho, né?

Mas viu como ficou simples, no final?

Ficamos com vários arquivos, mas cada um faz tarefas bem específicas.

Assim tudo fica bem separado e organizado.

Sobre as validações, lembre-se de que é possível usar Expressões Regulares para validar emails e datas, por exemplo.

Falo bastante sobre isso no Curso ULTIMATE PHP 2.0. Aliás, fiz um módulo 100% dedicado a ensinar Expressões Regulares, pois sei que elas são muito úteis, porém muitas pessoas acham que é algo difícil. No curso eu mostro como tudo pode ficar simples. 🙂

Todos os códigos aqui ficaram bem comentados, com todas as explicações. Mas se você tiver alguma dúvida, coloque aqui nos comentários, que eu ajudo.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *