1 / 0
A3
GameStock 2026 V2 · Aula 3
PHP 8, MVC e
Rotas Simples

Vamos transformar a interface em um projeto PHP organizado: entrada única em public/index.php, controllers, models, views e rotas básicas.

PHP 8
MVC
Front Controller
Rotas
Sem banco ainda
/public/index.php

Request

/games/create

Controller

GameController::create()

View

views/games/create.php

01
01·Objetivo da Aula
O que vamos entregar?
Entrada única
Todo acesso passa por public/index.php.
Rotas simples
Uma URL chama o controller e o método correto.
MVC real
Controllers chamam Models e carregam Views.
Dados mockados
Antes do PDO, vamos simular games com arrays.
A3
Recorte didáticoHoje não conectamos ao MySQL. A Aula 4 troca os arrays por PDO, sem desmontar a organização feita aqui.
02
02·Caminho da Requisição
Como o MVC responde?

1. Navegador

O usuário acessa /games ou /login.

2. Front Controller

public/index.php interpreta a rota.

3. Controller

Escolhe o Model e a View que devem participar.

4. Model

Por enquanto retorna dados simulados.

5. View

Recebe variáveis e monta HTML.

6. Resposta

O navegador recebe a página final.

03
03·Rotas do Projeto
URLs que o sistema entende
URLControllerMétodo
/GameControllerindex()
/gamesGameControllerindex()
/games/createGameControllercreate()
/loginAuthControllerlogin()
/usersUserControllerindex()
!
Simples de propósitoEsta aula usa um roteador pequeno para ficar claro. Depois podemos evoluir para rotas mais sofisticadas.
i
ConvençãoUma rota deve ter um destino claro. Exemplo: /games/create abre o formulário de cadastro de game.
04
04·Configuração
O arquivo config.php
app/config/config.php
PHP
<?php

// Caminhos principais do projeto
define('ROOT_PATH', dirname(__DIR__, 2));
define('APP_PATH', ROOT_PATH . '/app');
define('VIEW_PATH', APP_PATH . '/views');

// Ajuste conforme sua pasta no htdocs
define('BASE_URL', '/GameStock2026V2/public');

// Helper simples para carregar uma view
function view($path, $data = [])
{
    extract($data);
    $file = VIEW_PATH . '/' . $path . '.php';

    if (!file_exists($file)) {
        http_response_code(500);
        echo 'View nao encontrada: ' . $path;
        exit;
    }

    require $file;
}
1

Constantes

Evitam repetir caminhos longos em vários arquivos.

2

BASE_URL

Ajuda links e assets funcionarem no XAMPP.

3

Helper view()

Carrega uma tela e envia dados para ela.

05
05·Front Controller
O papel do public/index.php
public/index.php
PHP
<?php

require_once __DIR__ . '/../app/config/config.php';
require_once APP_PATH . '/models/BaseModel.php';
require_once APP_PATH . '/models/Game.php';
require_once APP_PATH . '/models/User.php';
require_once APP_PATH . '/controllers/GameController.php';
require_once APP_PATH . '/controllers/AuthController.php';
require_once APP_PATH . '/controllers/UserController.php';

$route = trim($_GET['url'] ?? '', '/');

switch ($route) {
    case '':
    case 'games':
        (new GameController())->index();
        break;

    case 'games/create':
        (new GameController())->create();
        break;

    case 'login':
        (new AuthController())->login();
        break;

    case 'users':
        (new UserController())->index();
        break;

    default:
        http_response_code(404);
        echo 'Pagina nao encontrada.';
}
FC
Front controllerUm arquivo central recebe a rota e decide qual controller responderá.
!
Por enquantoEstamos usando ?url=games. Mais tarde podemos deixar URLs amigáveis com .htaccess.
06
06·Controllers
GameController em ação
app/controllers/GameController.php
PHP
<?php

class GameController
{
    public function index()
    {
        $games = Game::all();

        view('games/index', [
            'titulo' => 'Loja de Games',
            'games' => $games
        ]);
    }

    public function create()
    {
        view('games/create', [
            'titulo' => 'Cadastrar Game'
        ]);
    }
}
1

index()

Lista games e manda os dados para a view.

2

create()

Mostra o formulário de cadastro.

3

Sem SQL aqui

Controller organiza o fluxo. Dados ficam no Model.

07
07·Models
Model sem banco ainda
app/models/BaseModel.php
PHP
<?php

class BaseModel
{
    // Na Aula 4 esta classe recebera a conexao PDO.
    protected static function fakeId()
    {
        return random_int(1, 999);
    }
}
app/models/Game.php
PHP
<?php

class Game extends BaseModel
{
    public static function all()
    {
        return [
            [
                'titulo' => 'Pixel Quest',
                'categoria' => 'Aventura',
                'preco' => '59.90',
                'estoque' => 12
            ],
            [
                'titulo' => 'Cyber Kart',
                'categoria' => 'Corrida',
                'preco' => '89.90',
                'estoque' => 8
            ]
        ];
    }
}
i
Por que usar mock?Com dados simulados, a turma entende MVC antes de lidar com conexão, query, erro de banco e credenciais.
08
08·Views
A View recebe os dados
app/views/games/index.php
PHP/HTML
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title><?= htmlspecialchars($titulo) ?></title>
    <link rel="stylesheet" href="<?= BASE_URL ?>/assets/css/style.css">
</head>
<body>
    <main class="container">
        <h1><?= htmlspecialchars($titulo) ?></h1>

        <section class="games-grid">
            <?php foreach ($games as $game): ?>
                <article class="game-card">
                    <h2><?= htmlspecialchars($game['titulo']) ?></h2>
                    <p><?= htmlspecialchars($game['categoria']) ?></p>
                    <strong>R$ <?= number_format($game['preco'], 2, ',', '.') ?></strong>
                </article>
            <?php endforeach; ?>
        </section>
    </main>
</body>
</html>
V
ViewA View não decide regra de negócio. Ela recebe dados prontos e monta a tela.
!
SegurançaUse htmlspecialchars() ao imprimir texto vindo de variáveis.
09
09·Auth e Users
Controllers de apoio
app/controllers/AuthController.php
PHP
<?php

class AuthController
{
    public function login()
    {
        view('auth/login', [
            'titulo' => 'Entrar no painel'
        ]);
    }
}
app/controllers/UserController.php
PHP
<?php

class UserController
{
    public function index()
    {
        $users = User::all();

        view('users/index', [
            'titulo' => 'Usuarios',
            'users' => $users
        ]);
    }
}
i
Ainda visualLogin real, sessão e senha com hash ficam para a aula específica de autenticação. Aqui montamos o caminho.
10
10·Erros e Testes
Quando a rota não existe
404 simples
PHP
default:
    http_response_code(404);

    view('errors/404', [
        'titulo' => 'Pagina nao encontrada',
        'route' => $route
    ]);
    break;
Teste no navegadorEsperado
?url=gamesLista mockada
?url=games/createFormulário
?url=loginTela de login
?url=usersUsuários mockados
?url=abcErro 404
OK
Teste bomUma rota boa deve abrir a tela certa. Uma rota errada deve falhar de forma clara, sem quebrar a aplicação inteira.
11
11·Exercícios
Prática da Aula 3
01
Explique o que é o front controller no GameStock.
FACIL
Ele é o public/index.php, o arquivo que recebe a rota e chama o controller certo.
02
Crie a rota ?url=games/create chamando GameController::create().
MEDIO
Adicione um case 'games/create' no switch do public/index.php.
03
Monte um Model User com método all() retornando dois usuários fake.
MEDIO
Siga a mesma ideia do Model Game, mas com nome, email e perfil.
04
Crie uma view de erro 404 e carregue-a quando a rota não existir.
DESAFIO
Crie app/views/errors/404.php e use http_response_code(404).
12
FIM·Resumo
Resumo da Aula 3
01O public/index.php é a entrada única do projeto.
02Rotas simples ligam URLs aos controllers e métodos.
03Controllers organizam o fluxo, Models fornecem dados e Views montam HTML.
04Dados mockados ajudam a testar a estrutura antes do banco.
05A rota 404 evita que o usuário veja erro bruto quando acessa uma URL inválida.
Próxima aula
Aula 4 — PDO e conexão com MySQL