Como criar formulário com etapas com PHP


Neste tutorial, será apresentado como criar um formulário em etapas com PHP. 

Primeiramente, será mostrado como identificar em qual etapa o usuário está por meio da sessão. 

Em seguida, será apresentado como exibir somente o formulário da etapa atual do usuário. 

Por fim, será mostrado como salvar no banco de dados o formulário em etapas.

Download do código fonte desenvolvido na aula: Download

Curso de PHP Developer: Mais Detalhes do Curso

Receber as aulas gratuitas do curso de PHP Developer: Acessar


Para começar, é criado o arquivo "index.php" com a estrutura básica do HTML e é verificado através da sessão qual formulário deve ser carregado.

<?php

session_start(); // Iniciar a sessão

// Verificar se está criada a sessão para controlar as etapas
if (!isset($_SESSION['etapa'])) {

    // Criar a sessão para armazenar a etapa
    $_SESSION['etapa'] = 1;
}
?>
<!DOCTYPE html>
<html lang="pt-br">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/custom.css">
    <title>Celke</title>
</head>

<body>

    <div class="form-container">        
        <div class="content">
            <?php

            // Imprimir as mensagens de erro ou sucesso
            echo $mensagem;
            $mensagem = "";

            // Verificar se deve carregar o formulário da etapa 1
            if ($_SESSION['etapa'] == 1) {

                // Incluir o arquivo com o formulário cadastrar usuário
                include_once './formulario_cadastrar_usuario.php';
            } elseif ($_SESSION['etapa'] == 2) {  // Verificar se deve carregar o formulário da etapa 2

                // Incluir o arquivo com o formulário cadastrar endereço
                include_once './formulario_cadastrar_endereco.php';
            } elseif ($_SESSION['etapa'] == 3) {  // Verificar se deve carregar o formulário da etapa 3

                // Incluir o arquivo com o formulário cadastrar empresa
                include_once './formulario_cadastrar_empresa.php';
            }
            ?>
        </div>
    </div>

</body>

</html>

Criado o arquivo "formulario_cadastrar_usuario.php" com o formulário para cadastrar usuário.

<!-- Formulário da etapa 1, cadastrar usuário -->
<form method="POST" action="" class="form-adm">

    <h2 class="title">Dados do Usuário</h2>

    <?php
    $nome = "";
    if (isset($dados['nome'])) {
        $nome = $dados['nome'];
    }
    ?>
    <div class="row-input">
        <div class="column">
            <label class="title-input">Nome: <span class="text-danger">*</span></label>
            <input type="text" name="nome" class="input-adm" placeholder="Nome completo" value="<?php echo $nome; ?>">
        </div>
    </div>

    <?php
    $email = "";
    if (isset($dados['email'])) {
        $email = $dados['email'];
    }
    ?>
    <div class="row-input">
        <div class="column">
            <label class="title-input">E-mail: <span class="text-danger">*</span></label>
            <input type="email" name="email" class="input-adm" placeholder="Melhor e-mail" value="<?php echo $email; ?>">
        </div>
    </div>

    <p class="obrigatorio">* Campo Obrigatório</p>

    <button type="submit" name="cadUsuario" class="btn-success" value="Cadastrar">Cadastrar</button>

</form>

Criado o arquivo "formulario_cadastrar_endereco.php" com o formulário para cadastrar endereço.

<!-- Formulário da etapa 2, cadastrar endereço -->
<form method="POST" action="" class="form-adm">

    <h2 class="title">Endereço</h2>

    <?php
    $logradouro = "";
    if (isset($dados['logradouro'])) {
        $logradouro = $dados['logradouro'];
    }
    ?>
    <div class="row-input">
        <div class="column">
            <label class="title-input">Logradouro: </label>
            <input type="text" name="logradouro" class="input-adm" placeholder="Avenida, Rua ..." value="<?php echo $logradouro; ?>">
        </div>
    </div>


    <?php
    $numero = "";
    if (isset($dados['numero'])) {
        $numero = $dados['numero'];
    }
    ?>
    <div class="row-input">
        <div class="column">
            <label class="title-input">Número: </label>
            <input type="text" name="numero" class="input-adm" placeholder="Número da residência" value="<?php echo $numero; ?>">
        </div>
    </div>


    <button type="submit" name="cadEndereco" class="btn-success" value="Cadastrar">Cadastrar</button>
    <button type="submit" name="novoUsuario" class="btn-primary" value="NovoUsuario">Novo Usuário</button>

</form>

Criado o arquivo "formulario_cadastrar_empresa.php" com o formulário para cadastrar empresa.

<!-- Formulário da etapa 3, cadastrar empresa -->
<form method="POST" action="" class="form-adm">

    <h2 class="title">Empresa</h2>

    <?php
    $razao_social = "";
    if (isset($dados['razao_social'])) {
        $razao_social = $dados['razao_social'];
    }
    ?>
    <div class="row-input">
        <div class="column">
            <label class="title-input">Razão Social: </label>
            <input type="text" name="razao_social" class="input-adm" placeholder="Razão social" value="<?php echo $razao_social; ?>">
        </div>
    </div>

    <?php
    $cnpj = "";
    if (isset($dados['cnpj'])) {
        $cnpj = $dados['cnpj'];
    }
    ?>
    <div class="row-input">
        <div class="column">
            <label class="title-input">CNPJ: </label>
            <input type="text" name="cnpj" class="input-adm" placeholder="CNPJ" value="<?php echo $cnpj; ?>">
        </div>
    </div>

    <button type="submit" name="cadEmpresa" class="btn-success" value="Cadastrar">Cadastrar</button>
    <button type="submit" name="novoUsuario" class="btn-primary" value="NovoUsuario">Novo Usuário</button>

</form>

Criado o arquivo "etapas.php" para apresentar em qual etapa o usuário está.

<div class="header">
    <ul class="steps">
        <li class="step <?php echo ($_SESSION['etapa'] == 1 ? 'active' : '') ?>">1</li>
        <li class="step <?php echo ($_SESSION['etapa'] == 2 ? 'active' : '') ?>">2</li>
        <li class="step <?php echo ($_SESSION['etapa'] == 3 ? 'active' : '') ?>">3</li>
    </ul>
</div>

Incluído o arquivo "etapas.php" no arquivo "index.php".

// Incluir o arquivo com as etapas
include_once './etapas.php';

Criada a base de dados "celke" com as tabelas usuários, endereços e empresas.

CREATE TABLE IF NOT EXISTS `usuarios` (
  `id` int NOT NULL AUTO_INCREMENT,
  `nome` varchar(220) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email` varchar(220) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `enderecos` (
  `id` int NOT NULL AUTO_INCREMENT,
  `logradouro` varchar(220) COLLATE utf8mb4_unicode_ci NOT NULL,
  `numero` varchar(44) COLLATE utf8mb4_unicode_ci NOT NULL,
  `usuario_id` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `empresas` (
  `id` int NOT NULL AUTO_INCREMENT,
  `razao_social` varchar(220) COLLATE utf8mb4_unicode_ci NOT NULL,
  `cnpj` varchar(44) COLLATE utf8mb4_unicode_ci NOT NULL,
  `usuario_id` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Com a base de dados criada, é necessário criar o arquivo "conexao.php" para conectar o projeto com o banco de dados.

<?php

$host = "localhost";
$user = "root";
$pass = "";
$dbname = "celke";
$port = 3306;

try{
    //Conexão com a porta
    //$conn = new PDO("mysql:host=$host;port=$port;dbname=" . $dbname, $user, $pass);

    //Conexão sem a porta
    $conn = new PDO("mysql:host=$host;dbname=" . $dbname, $user, $pass);

    //echo "Conexão com banco de dados realizado com sucesso!";
}  catch(PDOException $err){
    echo "Erro: Conexão com banco de dados não realizado com sucesso. Erro gerado " . $err->getMessage();
}

Necessário incluir o arquivo de conexão com o banco de dados no arquivo "index.php".

// Incluir o arquivo com conexão ao banco de dados
include_once './conexao.php';

Criado o arquivo "cadastrar_usuario.php", responsável por cadastrar o usuário no banco de dados.

<?php
// Verificar se o usuário clicou no botão cadastrar usuário
if (isset($dados['cadUsuario'])) {

    // Verificar se os campos estão preenchidos
    if (empty($dados['nome'])) {
        $mensagem = "<div class='alert-danger'>Erro: Necessário preencher o campo nome!</div>";
    }elseif (empty($dados['email'])) {
        $mensagem = "<div class='alert-danger'>Erro: Necessário preencher o campo e-mail!</div>";
    } else {
        // Criar a QUERY cadastrar no banco de dados
        $query_usuario = "INSERT INTO usuarios (nome, email) VALUES (:nome, :email)";

        // Preparar a QUERY
        $cad_usuario = $conn->prepare($query_usuario);

        // Substituir os links pelos valores do formulário
        $cad_usuario->bindParam(':nome', $dados['nome']);
        $cad_usuario->bindParam(':email', $dados['email']);

        // Executar a QUERY
        $cad_usuario->execute();

        // Verificar se cadastrou no banco de dados
        if ($cad_usuario->rowCount()) {

            // Recuperar o ultimo id inserido
            $_SESSION['usuario_id'] = $conn->lastInsertId();

            // Salvar o número da próxima etapa na sessão
            $_SESSION['etapa'] = 2;

            // Criar mensagem de sucesso
            $mensagem = "<div class='alert-success'>Dados do usuário cadastrado com sucesso!</div>";

        } else {

            // Criar mensagem de sucesso
            $mensagem = "<div class='alert-danger'>Dados do usuário não cadastrado!</div>";
        }
    }
}

Criado o arquivo "cadastrar_endereco.php", responsável por cadastrar o endereço no banco de dados.

<?php
// Verificar se o usuário clicou no botão cadastrar endereço
if (isset($dados['cadEndereco'])) {

    // Verificar se os campos estão preenchidos
    if (empty($dados['logradouro'])) {
        $mensagem = "<div class='alert-danger'>Erro: Necessário preencher o campo logradouro!</div>";
    }elseif (empty($dados['numero'])) {
        $mensagem = "<div class='alert-danger'>Erro: Necessário preencher o campo número!</div>";
    } else {
        // Criar a QUERY cadastrar no banco de dados
        $query_endereco = "INSERT INTO enderecos (logradouro, numero, usuario_id) VALUES (:logradouro, :numero, :usuario_id)";

        // Preparar a QUERY
        $cad_endereco = $conn->prepare($query_endereco);

        // Substituir os links pelos valores do formulário
        $cad_endereco->bindParam(':logradouro', $dados['logradouro']);
        $cad_endereco->bindParam(':numero', $dados['numero']);
        $cad_endereco->bindParam(':usuario_id', $_SESSION['usuario_id']);

        // Executar a QUERY
        $cad_endereco->execute();

        // Verificar se cadastrou no banco de dados
        if ($cad_endereco->rowCount()) {

            // Salvar o número da próxima etapa na sessão
            $_SESSION['etapa'] = 3;

            // Criar mensagem de sucesso
            $mensagem = "<div class='alert-success'>Endereço cadastrado com sucesso!</div>";
        } else {

            // Criar mensagem de sucesso
            $mensagem = "<div class='alert-danger'>Endereço não cadastrado!</div>";
        }
    }
}

Criado o arquivo "cadastrar_empresa.php", responsável por cadastrar a empresa no banco de dados.

<?php
// Verificar se o usuário clicou no botão cadastrar empresa
if (isset($dados['cadEmpresa'])) {

    // Verificar se os campos estão preenchidos
    if (empty($dados['razao_social'])) {
        $mensagem = "<div class='alert-danger'>Erro: Necessário preencher o campo razão social!</div>";
    }elseif (empty($dados['cnpj'])) {
        $mensagem = "<div class='alert-danger'>Erro: Necessário preencher o campo CNPJ!</div>";
    } else {
        // Criar a QUERY cadastrar no banco de dados
        $query_empresa = "INSERT INTO empresas (razao_social, cnpj, usuario_id) VALUES (:razao_social, :cnpj, :usuario_id)";

        // Preparar a QUERY
        $cad_empresa = $conn->prepare($query_empresa);

        // Substituir os links pelos valores do formulário
        $cad_empresa->bindParam(':razao_social', $dados['razao_social']);
        $cad_empresa->bindParam(':cnpj', $dados['cnpj']);
        $cad_empresa->bindParam(':usuario_id', $_SESSION['usuario_id']);

        // Executar a QUERY
        $cad_empresa->execute();

        // Verificar se cadastrou no banco de dados
        if ($cad_empresa->rowCount()) {

            // Salvar o número da próxima etapa na sessão
            $_SESSION['etapa'] = 1;

            // Criar mensagem de sucesso
            $mensagem = "<div class='alert-success'>Empresa cadastrada com sucesso!</div>";
        } else {

            // Criar mensagem de sucesso
            $mensagem = "<div class='alert-danger'>Empresa não cadastrada!</div>";
        }
    }
}

No arquivo "index.php", é necessário receber os dados do formulário e incluir os arquivos responsáveis pelo cadastro no banco de dados.

// Criar a variável para receber as mensagens de erro ou sucesso
$mensagem = "";

// Receber os dados do formulário
$dados = filter_input_array(INPUT_POST, FILTER_DEFAULT);

// Verificar se o usuário clicou no botão novo usuário
if (isset($dados['novoUsuario'])) {

    // Atribuir a etapa um para cadastrar novo usuário
    $_SESSION['etapa'] = 1;
}

/************* SALVAR OS DADOS DO USUÁRIO ***************/
include_once './cadastrar_usuario.php';

/************* SALVAR OS DADOS DO ENDEREÇO ***************/
include_once './cadastrar_endereco.php';

/************* SALVAR OS DADOS DA EMPRESA ***************/
include_once './cadastrar_empresa.php';

Para finalizar, é criado o arquivo "css/custom.css" para receber a estilização do formulário.

@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap');

:root {
    --main-color: #3a7afe;
    --first-color:  #fff;
    --second-color: #d4def7;  
    --third-color: #ededed;
    --fourth-color: #cecece;
    --five-color: #ddd;
    --six-color: #131b38;   
    --seven-color: #585858;   
    --primary-color: #0088cc;
    --success-color: #47a447;
    --danger-color: #d2322d;
    --success-color-second: #d1e7dd;
    --danger-color-second: #f8d7da;
}

body {
    font-family: Arial, sans-serif;
}

.form-container {
    max-width: 600px;
    margin: 0 auto;
}

.header {
    width: 100%;
    height: 60px;
    padding-top: 1px;
    margin-bottom: 15px;
    background:  var(--first-color);
    border-bottom: 1px solid var(--third-color);
    box-shadow: 0 2px 8px var(--fourth-color);
}

.steps {
    display: flex;
    justify-content: space-around;
    list-style: none;
    padding: 0;
    margin: 20px 0;
}

.step {
    display: inline-block;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background-color: var(--five-color);
    text-align: center;
    line-height: 30px;
    font-weight: bold;
}

.step.active {
    background-color: var(--main-color);
    color:  var(--first-color);
}

.content {
    width: 100%;
    min-height: 200px;
    background:  var(--first-color);
    border-bottom: 1px solid var(--third-color);
    box-shadow: 0 2px 8px var(--fourth-color);
    padding-top: 5px;
}

.form-adm {
    width: 100%;
    position: relative;
    margin: 10px auto 0 auto;
    padding: 0 15px 15px 15px;
}

.title{
    color: var(--seven-color);
}

.row-input {
    width: 100%;
    display: grid;
    margin-bottom: 20px;
    padding-right: 10px;
}

.title-input {
    color: var(--six-color);
    font-size: 14px;
}

input.input-adm {
    width: 90%;
    font-weight: 400;
    padding: 8px 10px;
    border-radius: 5px;
    border: 1.2px solid var(--second-color);
    margin-top: 5px;
}

@media (max-width: 767px) {
    input.input-adm{
        width: 90%; /* Defina a largura para 100% em dispositivos móveis */
        box-sizing: border-box; /* Isso inclui a borda e o preenchimento na largura total */
    }
}

input.input-adm:focus {
    outline: none;
    border-color: var(--main-color);
}

.obrigatorio{
    color: var(--danger-color);
    margin-bottom: 10px;
    font-size: 14px;
}

.text-danger{
    color: var(--danger-color);
}

.alert-success {
    background-color: var(--success-color-second);
    color: var(--success-color);
    margin: 10px 15px;
    border-radius: 4px;
    padding: 12px 7px;
}

.alert-danger {
    background-color: var(--danger-color-second);
    color: var(--danger-color);
    margin: 10px 15px;
    border-radius: 4px;
    padding: 12px 7px;
}

.btn-primary {
    background-color: var(--primary-color);
    color: var(--first-color);
    padding: 5px 8px;
    border: 1px solid var(--primary-color);
    border-radius: 4px;
    cursor: pointer;
    font-size: 15px;
    transition: all .3s ease;
}

.btn-primary:hover {
    background-color: var(--first-color);
    color: var(--primary-color);
}

.btn-success {
    background-color: var(--success-color);
    color: var(--first-color);
    padding: 5px 8px;
    border: 1px solid var(--success-color);
    border-radius: 4px;
    cursor: pointer;
    font-size: 15px;
    transition: all .3s ease;
}

.btn-success:hover {
    background-color: var(--first-color);
    color: var(--success-color);
}


Baixar o código-fonte completo do projeto.

Bom, era isso. Espero que o tutorial tenha sido útil!