Conversor de Moedas e Medidas

Nível: Básico
Conceitos: Formulários, variáveis, operadores matemáticos, condicionais

Estrutura de Arquivos

/conversor/
├── index.php
└── style.css

1.1 Arquivo index.php

<?php
// index.php - Conversor Universal (Moedas e Medidas)

// Inicializa variáveis
$valor = '';
$tipo_conversao = 'moeda';
$resultado = null;
$detalhes = '';
$erro = '';

// Taxas de câmbio (valores fixos para exemplo - em produção use API)
$taxas_moeda = [
    'brl_usd' => 0.20,  // 1 Real = 0.20 Dólar
    'brl_eur' => 0.18,  // 1 Real = 0.18 Euro
    'usd_brl' => 5.00,  // 1 Dólar = 5.00 Reais
    'usd_eur' => 0.92,  // 1 Dólar = 0.92 Euro
    'eur_brl' => 5.50,  // 1 Euro = 5.50 Reais
    'eur_usd' => 1.09,  // 1 Euro = 1.09 Dólar
];

// Processa o formulário
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $valor = str_replace(',', '.', trim($_POST['valor'] ?? ''));
    $tipo_conversao = $_POST['tipo_conversao'] ?? 'moeda';
    $conversao = $_POST['conversao'] ?? '';

    // Validação
    if (empty($valor)) {
        $erro = '⚠️ Por favor, insira um valor!';
    } elseif (!is_numeric($valor)) {
        $erro = '⚠️ Insira apenas números válidos!';
    } elseif ($valor <= 0) {
        $erro = '⚠️ O valor deve ser maior que zero!';
    } else {
        // Realiza a conversão conforme o tipo
        if ($tipo_conversao === 'moeda') {
            // Conversão de moedas
            if (isset($taxas_moeda[$conversao])) {
                $taxa = $taxas_moeda[$conversao];
                $resultado = $valor * $taxa;

                // Define os labels
                $labels = [
                    'brl_usd' => ['Real', 'Dólar', 'R$', 'US$'],
                    'brl_eur' => ['Real', 'Euro', 'R$', '€'],
                    'usd_brl' => ['Dólar', 'Real', 'US$', 'R$'],
                    'usd_eur' => ['Dólar', 'Euro', 'US$', '€'],
                    'eur_brl' => ['Euro', 'Real', '€', 'R$'],
                    'eur_usd' => ['Euro', 'Dólar', '€', 'US$'],
                ];

                $info = $labels[$conversao];
                $detalhes = "{$info[2]} " . number_format($valor, 2, ',', '.') .
                           " ({$info[0]}) = {$info[3]} " .
                           number_format($resultado, 2, ',', '.') .
                           " ({$info[1]})";
            }
        } elseif ($tipo_conversao === 'comprimento') {
            // Conversão de comprimento
            $fatores = [
                'm_cm' => 100,
                'cm_m' => 0.01,
                'm_km' => 0.001,
                'km_m' => 1000,
                'cm_km' => 0.00001,
                'km_cm' => 100000,
            ];
            if (isset($fatores[$conversao])) {
                $resultado = $valor * $fatores[$conversao];
                $labels = [
                    'm_cm' => ['Metros', 'Centímetros', 'm', 'cm'],
                    'cm_m' => ['Centímetros', 'Metros', 'cm', 'm'],
                    'm_km' => ['Metros', 'Quilômetros', 'm', 'km'],
                    'km_m' => ['Quilômetros', 'Metros', 'km', 'm'],
                    'cm_km' => ['Centímetros', 'Quilômetros', 'cm', 'km'],
                    'km_cm' => ['Quilômetros', 'Centímetros', 'km', 'cm'],
                ];
                $info = $labels[$conversao];
                $detalhes = number_format($valor, 2, ',', '.') . " {$info[2]} = " .
                           number_format($resultado, 4, ',', '.') . " {$info[3]}";
            }
        } elseif ($tipo_conversao === 'temperatura') {
            // Conversão de temperatura
            $labels = [
                'c_f' => ['Celsius', 'Fahrenheit', '°C', '°F'],
                'f_c' => ['Fahrenheit', 'Celsius', '°F', '°C'],
                'c_k' => ['Celsius', 'Kelvin', '°C', 'K'],
                'k_c' => ['Kelvin', 'Celsius', 'K', '°C'],
            ];
            if (isset($labels[$conversao])) {
                switch ($conversao) {
                    case 'c_f':
                        $resultado = ($valor * 9/5) + 32;
                        break;
                    case 'f_c':
                        $resultado = ($valor - 32) * 5/9;
                        break;
                    case 'c_k':
                        $resultado = $valor + 273.15;
                        break;
                    case 'k_c':
                        $resultado = $valor - 273.15;
                        break;
                }
                $info = $labels[$conversao];
                $detalhes = number_format($valor, 2, ',', '.') . " {$info[2]} = " .
                           number_format($resultado, 2, ',', '.') . " {$info[3]}";
            }
        }
    }
}
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Conversor Universal</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>🔄 Conversor Universal</h1>
        <p class="subtitle">Converta moedas, medidas e temperaturas</p>

        <form method="POST" action="" id="form-conversor">
            <!-- Tipo de conversão -->
            <div class="form-group">
                <label>📌 Tipo de Conversão:</label>
                <div class="tipo-selector">
                    <label class="radio-card">
                        <input type="radio" name="tipo_conversao" value="moeda"
                            <?php echo $tipo_conversao === 'moeda' ? 'checked' : ''; ?>
                            onchange="atualizarOpcoes()">
                        <span>💰 Moedas</span>
                    </label>
                    <label class="radio-card">
                        <input type="radio" name="tipo_conversao" value="comprimento"
                            <?php echo $tipo_conversao === 'comprimento' ? 'checked' : ''; ?>
                            onchange="atualizarOpcoes()">
                        <span>📏 Comprimento</span>
                    </label>
                    <label class="radio-card">
                        <input type="radio" name="tipo_conversao" value="temperatura"
                            <?php echo $tipo_conversao === 'temperatura' ? 'checked' : ''; ?>
                            onchange="atualizarOpcoes()">
                        <span>🌡️ Temperatura</span>
                    </label>
                </div>
            </div>

            <!-- Valor -->
            <div class="form-group">
                <label for="valor">🔢 Valor a converter:</label>
                <input type="text" id="valor" name="valor"
                       placeholder="Digite o valor"
                       value="<?php echo htmlspecialchars($valor); ?>" required>
            </div>

            <!-- Tipo específico de conversão -->
            <div class="form-group">
                <label for="conversao">🔄 Conversão:</label>
                <select name="conversao" id="conversao" required>
                    <!-- Opções carregadas via JavaScript -->
                </select>
            </div>

            <button type="submit" class="btn-calcular">✨ Converter</button>
        </form>

        <!-- Erro -->
        <?php if (!empty($erro)): ?>
            <div class="mensagem erro"><?php echo $erro; ?></div>
        <?php endif; ?>

        <!-- Resultado -->
        <?php if ($resultado !== null): ?>
            <div class="resultado">
                <div class="resultado-label">Resultado</div>
                <div class="resultado-valor">
                    <?php echo number_format($resultado, 2, ',', '.'); ?>
                </div>
                <div class="resultado-detalhes"><?php echo $detalhes; ?></div>
            </div>
        <?php endif; ?>
    </div>

    <script>
        // Opções de conversão por tipo
        const opcoes = {
            moeda: [
                { value: 'brl_usd', label: 'Real (R$) → Dólar (US$)' },
                { value: 'brl_eur', label: 'Real (R$) → Euro (€)' },
                { value: 'usd_brl', label: 'Dólar (US$) → Real (R$)' },
                { value: 'usd_eur', label: 'Dólar (US$) → Euro (€)' },
                { value: 'eur_brl', label: 'Euro (€) → Real (R$)' },
                { value: 'eur_usd', label: 'Euro (€) → Dólar (US$)' }
            ],
            comprimento: [
                { value: 'm_cm', label: 'Metros → Centímetros' },
                { value: 'cm_m', label: 'Centímetros → Metros' },
                { value: 'm_km', label: 'Metros → Quilômetros' },
                { value: 'km_m', label: 'Quilômetros → Metros' },
                { value: 'cm_km', label: 'Centímetros → Quilômetros' },
                { value: 'km_cm', label: 'Quilômetros → Centímetros' }
            ],
            temperatura: [
                { value: 'c_f', label: 'Celsius (°C) → Fahrenheit (°F)' },
                { value: 'f_c', label: 'Fahrenheit (°F) → Celsius (°C)' },
                { value: 'c_k', label: 'Celsius (°C) → Kelvin (K)' },
                { value: 'k_c', label: 'Kelvin (K) → Celsius (°C)' }
            ]
        };

        // Atualiza o select de conversões
        function atualizarOpcoes() {
            const tipo = document.querySelector('input[name="tipo_conversao"]:checked').value;
            const select = document.getElementById('conversao');
            select.innerHTML = '';

            opcoes[tipo].forEach(function(op) {
                const option = document.createElement('option');
                option.value = op.value;
                option.textContent = op.label;
                select.appendChild(option);
            });
        }

        // Inicializa ao carregar
        document.addEventListener('DOMContentLoaded', atualizarOpcoes);
    </script>
</body>
</html>

1.2 Arquivo style.css

/* style.css - Conversor Universal */

:root {
    --primary: #667eea;
    --primary-dark: #5568d3;
    --gradient: linear-gradient(135deg, #667eea, #764ba2);
    --success: #10b981;
    --danger: #ef4444;
    --dark: #1f2937;
    --gray: #6b7280;
    --light-gray: #e5e7eb;
    --bg: #f9fafb;
    --white: #ffffff;
    --radius: 14px;
    --transition: all 0.3s ease;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', system-ui, sans-serif;
    background: var(--bg);
    min-height: 100vh;
    padding: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-image: radial-gradient(circle at 20% 20%, rgba(102, 126, 234, 0.08), transparent 50%);
}

.container {
    max-width: 600px;
    width: 100%;
    background: var(--white);
    border-radius: var(--radius);
    padding: 40px;
    box-shadow: 0 15px 40px rgba(102, 126, 234, 0.15);
}

h1 {
    font-size: 1.8rem;
    color: var(--dark);
    text-align: center;
    margin-bottom: 8px;
}

.subtitle {
    text-align: center;
    color: var(--gray);
    margin-bottom: 30px;
    padding-bottom: 20px;
    border-bottom: 2px solid var(--light-gray);
}

.form-group {
    margin-bottom: 20px;
}

.form-group > label {
    display: block;
    font-weight: 600;
    color: var(--dark);
    margin-bottom: 10px;
}

.tipo-selector {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}

.radio-card {
    cursor: pointer;
    position: relative;
}

.radio-card input {
    position: absolute;
    opacity: 0;
}

.radio-card span {
    display: block;
    padding: 12px 8px;
    text-align: center;
    background: var(--bg);
    border: 2px solid var(--light-gray);
    border-radius: 10px;
    font-size: 0.85rem;
    font-weight: 500;
    transition: var(--transition);
}

.radio-card input:checked + span {
    background: var(--gradient);
    color: white;
    border-color: transparent;
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(102, 126, 234, 0.3);
}

.form-group input[type="text"],
.form-group select {
    width: 100%;
    padding: 14px 18px;
    border: 2px solid var(--light-gray);
    border-radius: 10px;
    font-size: 1rem;
    transition: var(--transition);
    background: var(--white);
    color: var(--dark);
    font-family: inherit;
}

.form-group input[type="text"]:focus,
.form-group select:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
}

.btn-calcular {
    width: 100%;
    padding: 16px;
    background: var(--gradient);
    color: white;
    border: none;
    border-radius: 12px;
    font-size: 1.05rem;
    font-weight: 600;
    cursor: pointer;
    transition: var(--transition);
}

.btn-calcular:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4);
}

.mensagem {
    padding: 15px 20px;
    border-radius: 10px;
    margin-top: 20px;
    font-weight: 500;
}

.mensagem.erro {
    background: #fee2e2;
    color: #991b1b;
    border-left: 4px solid var(--danger);
}

.resultado {
    margin-top: 25px;
    padding: 25px;
    background: var(--gradient);
    border-radius: var(--radius);
    color: white;
    text-align: center;
    animation: slideIn 0.4s ease;
}

.resultado-label {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 1px;
    opacity: 0.9;
    margin-bottom: 10px;
}

.resultado-valor {
    font-size: 2.5rem;
    font-weight: 800;
    margin-bottom: 10px;
}

.resultado-detalhes {
    font-size: 0.95rem;
    opacity: 0.95;
    padding-top: 15px;
    border-top: 1px solid rgba(255, 255, 255, 0.2);
}

@keyframes slideIn {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 500px) {
    .container { padding: 25px 20px; }
    h1 { font-size: 1.4rem; }
    .tipo-selector { grid-template-columns: 1fr; }
    .resultado-valor { font-size: 2rem; }
}