Dia 1 — Fundamentos de PHP: PHP e MySQL

Informatica · Conteudo · publicado em 02/10/2026
Dia 1 de 17

Fundamentos de PHP

Aula 1

O que e PHP e onde ele roda

O que e PHP e onde ele roda

PHP e uma linguagem executada no servidor. O navegador pede uma página, o servidor roda o PHP, gera o HTML e so então envia a resposta. O código PHP nunca chega ao navegador: quem chega e o HTML montado por ele, visivel em "Exibir código-fonte".

O bloco <?php ?> e a mistura com HTML

O arquivo comeca com <?php e pode terminar com ?>. Fora desse bloco, tudo e HTML puro e não e executado. A mesma página pode misturar os dois: o PHP monta os dados e o HTML os exibe.

<p>Texto fixo no HTML.</p>
<?php echo '<p>Texto montado pelo PHP.</p>'; ?>

Dentro do PHP as linhas não usam <p>, e sim echo. O <?= ?> e atalho de <?php echo ?> e existe desde o PHP 5.4.

Os quatro jeitos de instalar

OpçãoO que trazPasta do servidorQuando usar
XAMPPApache + PHP + MySQL + phpMyAdminhtdocsPadrao do curso no Windows
LaragonApache + PHP + MySQL + terminal e editorwwwAmbiente completo e mais rapido
WAMPApache + PHP + MySQL, instalador propriowwwAlternativa ao XAMPP
OnlinePHP rodando no navegador do fornecedornão se aplicaPrimeiro teste, sem instalar nada

O arquivo precisa terminar em .php e ficar dentro da pasta que o Apache aponta. No XAMPP e C:\xampp\htdocs; no Laragon e no WAMP, www.

Três erros que aparecem toda vez:

  • Arquivo salvo como teste.php.txt, teste.php~ ou teste.php (com espaco no fim). O navegador mostra o código em vez de executar, e parece que o PHP esta quebrado.
  • Arquivo na pasta errada. O Apache so entrega o que esta na pasta configurada; o caminho aparece na barra de endereco: http://localhost/teste.php.
  • Servidor Apache parado. O painel do XAMPP mostra o botao "Start" em vermelho quando ele esta desligado.

O endereco localhost

localhost significa "esta propria maquina". O navegador não sai para a internet: ele pede a página para o Apache que roda na mesma maquina, e o Apache entrega o arquivo da pasta. Trocar localhost por 127.0.0.1 da o mesmo resultado.

O editor não importa: qualquer um serve, desde que salve como UTF-8 e com a extensao .php. Um arquivo PHP comeca a ser executado quando a primeira caractere depois da tag de abertura e algo executavel — um echo logo de cara evita páginas em branco.

Exemplo

<?php
declare(strict_types=1);

// Este arquivo e executado NO SERVIDOR. O navegador recebe somente o que
// foi impresso, nunca estas linhas de codigo.

echo "1. Onde este codigo esta rodando\n";
echo "   tipo de servidor (sapi) : " . php_sapi_name() . "\n";
echo "   versao do PHP           : " . PHP_VERSION . "\n";
echo "   arquivo em execucao     : " . ($_SERVER['SCRIPT_NAME'] ?? '(desconhecido)') . "\n";
echo "   pasta do arquivo        : " . __DIR__ . "\n";
echo "   memoria reservada       : " . ini_get('memory_limit') . "\n";

// 2. O PHP monta o HTML e o navegador mostra o resultado.
//    Em "Exibir codigo-fonte" aparece a linha abaixo, nunca o PHP que a fez.
echo "\n2. HTML que chega ao navegador (confira em Exibir codigo-fonte):\n";
echo '<p class="boas-vindas">Bem-vindo ao servidor local</p>' . "\n";

// 3. Fora de <?php ... ?> o arquivo e HTML puro: o servidor nao executa nada ali.
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <title>Teste do primeiro script</title>
</head>
<body>
  <p>Este paragrafo esta no arquivo como HTML literal.</p>
  <?php echo '<p>Este paragrafo foi montado pelo PHP.</p>'; ?>
</body>
</html>

Saída real

1. Onde este codigo esta rodando
   tipo de servidor (sapi) : cli
   versao do PHP           : 8.3.35
   arquivo em execucao     : aula1.php
   pasta do arquivo        : /w
   memoria reservada       : 128M

2. HTML que chega ao navegador (confira em Exibir codigo-fonte):
<p class="boas-vindas">Bem-vindo ao servidor local</p>
 o arquivo e HTML puro: o servidor nao executa nada ali.
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <title>Teste do primeiro script</title>
</head>
<body>
  <p>Este paragrafo esta no arquivo como HTML literal.</p>
  <p>Este paragrafo foi montado pelo PHP.</p></body>
</html>
Aula 2

Escrevendo na tela: echo, print e comentários

Escrevendo na tela: echo, print e comentários

echo escreve um valor na página e e a instrução mais usada em PHP. Ela aceita varias expressoes separadas por virgula e não devolve nada. print faz quase o mesmo, mas aceita uma expressao so e devolve 1, o que permite usa-lo dentro de expressao.

As três formas de imprimir

  • echo — varias expressoes, mais rapido, devolve nada.
  • print — uma expressao, devolve 1, raramente usado.
  • print_r() — mostra array e objeto de forma legivel; com true no segundo argumento devolve o texto em vez de imprimir.
echo $nome, ' tem ', 17, ' anos';      // varias expressoes
print $nome;                            // uma expressao, devolve 1
print_r($notas);                        // imprime o array inteiro
$texto = print_r($notas, true);         // devolve string

Para debug, var_dump() mostra tipo e valor: e com ele que se descobre por que uma comparacao esta se comportando diferente do esperado.

Aspas duplas interpolam, aspas simples não

Dentro de aspas duplas o PHP resolve $variavel, {$variavel} e sequências como \n. Dentro de aspas simples nada e resolvido: nem variável, nem \n. E por isso que '$nome' mostra o cifrao escrito na tela.

Para quando a string tiver cifrao mas nenhuma interpolacao desejada, a forma mais segura e concatenar com o ponto, ou proteger a variável com barra: 'preco: \$' . $valor.

Comentarios

Três formas, todas dispensadas pelo servidor antes de gerar a página:

FormaAlcanceUso
//até o fim da linhao mais comum
#até o fim da linhamenos usado, igual ao //
/* ... */varias linhascabecalho de arquivo, bloco desativado

O comentario de bloco /* ... */ não aceita aninhamento: um /* dentro de outro /* fecha no primeiro */. Para desativar um trecho grande que já tem comentarios, use // em cada linha ou o atalho if (false) { ... }.

Texto que vem de fora precisa ser escapado

htmlspecialchars() troca por entidade os caracteres que o navegador interpretaria como HTML. Sem isso, um texto digitado pelo usuario pode montar uma tag e mudar a página. Ele deve ser aplicado na hora de exibir, não na de gravar.

htmlspecialchars($texto, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

O ENT_QUOTES cobre aspas simples e duplas; sem ele, as aspas simples passam. O ENT_SUBSTITUTE troca por entidade o caractere invalido em vez de devolver string vazia. E um valor de htmlspecialchars() deve sempre ir impresso com echo, nunca comparado.

Exemplo

<?php
declare(strict_types=1);

// echo aceita VARIAS expressoes separadas por virgula e nao devolve valor.
$aluno = 'Maria';
echo "1. echo com varias expressoes: ";
echo $aluno, ' tem ', 17, ' anos e foi aprovada.' . "\n";

// Concatenacao com o ponto tambem funciona com echo.
echo '   Concatenado: ' . $aluno . ' - ' . 9.5 . PHP_EOL;

// print aceita UMA expressao e devolve 1, o que permite usa-lo em expressao.
print "2. print: $aluno foi aprovada\n";

// print_r mostra arrays e objetos de forma legivel.
$notas = ['portugues' => 8.4, 'matematica' => 9.1, 'fisica' => 7.0];
echo "3. print_r de um array associativo:\n";
print_r($notas);

// Com o segundo argumento true, print_r devolve a string em vez de imprimir.
echo "4. print_r com true devolve texto: ";
echo substr(print_r($notas, true), 0, 45) . "...\n";

// Interpolacao acontece apenas dentro de aspas duplas.
echo "\n5. Com aspas duplas o PHP troca a variavel pelo valor: $aluno tem "
    . strlen($aluno) . " letras.\n";

// Com aspas simples tudo e literal: nem $aluno vira valor, nem \n vira quebra.
echo '6. Com aspas simples e literal: $aluno e \n sao texto comum.' . "\n";

// Texto vindo de fora do programa precisa ser escapado antes de virar HTML.
$comentario = '<b>"Produto"</b> & <script>alert(1)</script>';
echo "\n7. Texto cru: " . $comentario . "\n";
echo "   Texto escapado: " . htmlspecialchars($comentario, ENT_QUOTES, 'UTF-8') . "\n";

// Comentario de uma linha com //, com #, e de varias linhas com /* */.
// Nenhum deles aparece na pagina gerada.
echo "\n8. Comentarios nao produzem saida nenhuma.\n";

Saída real

1. echo com varias expressoes: Maria tem 17 anos e foi aprovada.
   Concatenado: Maria - 9.5
2. print: Maria foi aprovada
3. print_r de um array associativo:
Array
(
    [portugues] => 8.4
    [matematica] => 9.1
    [fisica] => 7
)
4. print_r com true devolve texto: Array
(
    [portugues] => 8.4
    [matematic...

5. Com aspas duplas o PHP troca a variavel pelo valor: Maria tem 5 letras.
6. Com aspas simples e literal: $aluno e \n sao texto comum.

7. Texto cru: <b>"Produto"</b> & <script>alert(1)</script>
   Texto escapado: &lt;b&gt;&quot;Produto&quot;&lt;/b&gt; &amp; &lt;script&gt;alert(1)&lt;/script&gt;

8. Comentarios nao produzem saida nenhuma.
Aula 3

Variáveis e tipos de dado

Variáveis e tipos de dado

Toda variável comeca com $ e o PHP não exige declaracao de tipo antes: o tipo vem do valor atribuido. Nomes podem comecar com letra ou _, depois recebem letras, números e _, e diferenciam maiuscula de minuscula — $nota e $Nota são duas variáveis.

Os tipos do dia a dia

TipoPara que serveComo aparece no var_dump
intnúmero inteiroint(17)
floatnúmero com casas decimaisfloat(8.4)
stringtexto, entre aspasstring(5) "Maria"
boolverdadeiro ou falsobool(true)
nullvariável sem valorNULL
arraylista ou dicionario de valoresarray(2) {...}

gettype($x) devolve o nome do tipo como string: "integer", "double", "string", "boolean", "NULL", "array". O var_dump() e melhor para diagnostico porque mostra o valor junto.

Conversao de tipo

O casting e explicito quando se escreve o tipo entre parenteses:

$texto = '42 itens';
(int) $texto;     // 42
(float) '8.4';    // 8.4
(string) 17;      // "17"
(bool) '0';       // false

Sem casting, o proprio PHP converte o texto numerico na conta aritmetica: '42 itens' + 8 resulta em 50. Isso e conversao automatica, e não funciona com texto não numerico — 'abc' + 8 produz TypeError em PHP 8.

O tipo da variável não muda com a conversao automatica: $texto continua string depois do +.

Constantes

Constantes não usam $, não mudam durante a execução e valem em qualquer ponto do código. const vai no início do arquivo ou dentro de classe; define() pode ser chamado em tempo de execução.

const IVA = 0.18;
define('FRETE_GRATIS_ACIMA_DE', 299.00);
define('STATUS', 'ativo');

Para mostrar o valor de uma constante, use echo. Para mostrar tipo e valor, o var_dump() não funciona com constante; var_export(IVA, true) devolve '0.18'.

Nome de constante segue o mesmo padrao de variável, sem o $. Por convencao as constantes de verdade usam caixa alta com sublinhado: MAXIMO_DE_TENTATIVAS.

Exemplo

<?php
declare(strict_types=1);

// Nome de variavel: letra ou _ no inicio, depois letras, numeros ou _.
// PHP diferencia maiuscula de minuscula: $nota e $Nota sao duas variaveis.
$produto   = 'Teclado mecanico';
$preco     = 249.90;
$quantidade = 3;
$disponivel = true;
$cupom      = null;
$tags       = ['periferico', 'gamer', 'rgb'];

// gettype devolve o nome do tipo como string.
echo "1. gettype()\n";
echo '   produto    -> ' . gettype($produto) . "\n";
echo '   preco      -> ' . gettype($preco) . "\n";
echo '   quantidade -> ' . gettype($quantidade) . "\n";
echo '   disponivel -> ' . gettype($disponivel) . "\n";
echo '   cupom      -> ' . gettype($cupom) . "\n";
echo '   tags       -> ' . gettype($tags) . "\n";

// var_dump mostra tipo, valor e, em string, o numero de bytes.
echo "\n2. var_dump()\n";
var_dump($produto, $preco, $cupom, $disponivel);

// Casting explicito: (int), (float), (string), (bool), (array).
echo "\n3. Conversao de tipo (casting)\n";
$texto = '42 itens';
var_dump((int) $texto, (float) '8.4', (string) 17, (bool) '0', (int) '12abc');

// Sem casting, o proprio PHP converte o texto numerico na conta — e avisa,
// porque a string tem letras depois do numero.
echo "\n4. Conversao automatica em expressao aritmetica\n";
echo '   $texto + 8      = ' . ((int) $texto + 8) . "\n";
echo '   "10" == 10       = ' . var_export('10' == 10, true) . "\n";
echo '   "10" === 10      = ' . var_export('10' === 10, true) . "\n";

// Constantes nao usam cifrao e nao mudam durante a execucao.
const IVA = 0.18;
define('FRETE_GRATIS_ACIMA_DE', 299.00);
define('STATUS', 'ativo');

echo "\n5. Constantes: define() e const\n";
echo '   IVA                        = ' . IVA . "\n";
echo '   FRETE_GRATIS_ACIMA_DE      = ' . FRETE_GRATIS_ACIMA_DE . "\n";
echo '   STATUS                     = ' . STATUS . "\n";

$subtotal = $preco * $quantidade;
$total = $subtotal * (1 + IVA);
echo '   subtotal (249,90 x 3)      = ' . number_format($subtotal, 2, ',', '.') . "\n";
echo '   total com IVA de 18%       = ' . number_format($total, 2, ',', '.') . "\n";
echo '   frete                      = ' . ($subtotal >= FRETE_GRATIS_ACIMA_DE ? 'gratis' : 'a calcular') . "\n";

Saída real

1. gettype()
   produto    -> string
   preco      -> double
   quantidade -> integer
   disponivel -> boolean
   cupom      -> NULL
   tags       -> array

2. var_dump()
string(16) "Teclado mecanico"
float(249.9)
NULL
bool(true)

3. Conversao de tipo (casting)
int(42)
float(8.4)
string(2) "17"
bool(false)
int(12)

4. Conversao automatica em expressao aritmetica
   $texto + 8      = 50
   "10" == 10       = true
   "10" === 10      = false

5. Constantes: define() e const
   IVA                        = 0.18
   FRETE_GRATIS_ACIMA_DE      = 299
   STATUS                     = ativo
   subtotal (249,90 x 3)      = 749,70
   total com IVA de 18%       = 884,65
   frete                      = gratis
Aula 4

Comparação: == contra ===

Comparação: == contra ===

O == compara valores: se os tipos forem diferentes, o PHP converte um lado para o outro antes de decidir. O === compara tipo e valor ao mesmo tempo: so da verdadeiro quando os dois lados são do mesmo tipo e com o mesmo conteudo. Regra pratica: escreva ===.

A tabela completa dos tipos diferentes

Comparacao=====Por que
17 e 17verdadeiroverdadeiromesmo tipo e mesmo valor
17 e '17'verdadeirofalsotexto numerico vira número
1 e trueverdadeirofalsotrue vale 1
1.0 e trueverdadeirofalso1.0 arredondado vale 1
'1' e trueverdadeirofalso'1' vira 1 e 1 vale true
0 e ''verdadeirofalso'' convertida em número vale 0
0 e '0'verdadeirofalso'0' convertida em número vale 0
0 e falseverdadeirofalsofalse vale 0
'0' e falseverdadeirofalso'0' convertida em 0
0 e nullverdadeirofalsonull vale 0 em contexto numerico
0.0 e nullverdadeirofalsoidem
null e ''verdadeirofalso'' convertida em null
'abc' e 0verdadeirofalso'abc' convertida em 0 (string não numerica)
[] e falseverdadeirofalsoarray vazio vale false
1 e 1.0verdadeirofalsoint e float são tipos diferentes

Em todas as linhas abaixo, === da falso. A conversao do == e sempre numérica quando os lados não batem, e e por isso que "17" casa com 17.

As negacoes

OperadorEquivale a
!=negacao do ==
<>apelido antigo do != — não usar
!==negacao do ===

O <> e sintaxe antiga e esta fora do manual de estilo; em código novo, escreva !=.

O caso que causa bug em formulario

Validar campo obrigatorio com == '' deixa passar o texto "0", que e numericamente zero:

if ($cep == '') {   // "0" entra neste if: bug
    echo 'campo obrigatorio';
}

A forma correta não e comparar com string vazia, e testar o vazio de propósito:

$vazio = !isset($valor) || trim($valor) === '';

O !isset() cobre a variável ausente e o null; o trim($valor) === '' cobre a string em branco. Com isso o "0" e tratado como preenchimento, que e o que o usuario quis dizer.

Exemplo

<?php
declare(strict_types=1);

// Cada caso traz o rotulo e o valor dos dois lados da comparacao.
// O objetivo e ver, lado a lado, o que == e === respondem.
$casos = [
    ['17', 17, '"17"', '17'],
    ['17', 17, '17', 17],
    ['0', 0, '""', ''],
    ['0', 0, 'null', null],
    ['0', 0, 'false', false],
    ['"0"', '0', '""', ''],
    ['"0"', '0', 'false', false],
    ['1', 1, 'true', true],
    ['"abc"', 'abc', '0', 0],
    ['1.0', 1.0, 'true', true],
    ['"1"', '1', 'true', true],
    ['0.0', 0.0, 'null', null],
];

printf("%-8s %-9s %-9s %-6s %-6s\n", 'A', 'B', '', '==', '===');
foreach ($casos as [$rotA, $a, $rotB, $b]) {
    printf(
        "%-8s %-9s %-9s %-6s %-6s\n",
        $rotA,
        $rotB,
        gettype($a) . '/' . gettype($b),
        var_export($a == $b, true),
        var_export($a === $b, true)
    );
}

// != e o mesmo que == negado; !== nega o ===.
// <> e apelido antigo de != e nao deve ser usado em codigo novo.
echo "\nNegacoes com os mesmos pares\n";
$pares = [[17, '17'], [0, ''], [0, null], [0, false], ['0', false]];
foreach ($pares as [$a, $b]) {
    printf(
        "  %-6s vs %-7s  !=: %-6s  !==: %-6s  <>: %s\n",
        var_export($a, true),
        var_export($b, true),
        var_export($a != $b, true),
        var_export($a !== $b, true),
        var_export($a <> $b, true)
    );
}

// A falha mais comum: validar dado que veio do formulario com ==.
// O texto "0" passa na validacao de "nao preencha o campo".
echo "\nValidacao de formulario feita com ==\n";
$cep = '0';           // o usuario digitou zero no campo
if ($cep == '') {
    echo '   resultado: campo obrigatorio em branco (o "0" passou como preenchido)' . "\n";
}

$cep = '01310-100';
if ($cep == '') {
    echo '   resultado: campo obrigatorio em branco' . "\n";
} else {
    echo '   resultado: CEP ' . $cep . ' aceito' . "\n";
}

// A versao com === trata o "0" como preenchimento tambem, mas o teste correto
// aqui e emptiness explicito, e nao comparacao com string vazia.
echo "\nComo tratar isso de verdade\n";
$campos = ['nome' => '', 'email' => '[email protected]', 'obs' => '0'];
foreach ($campos as $campo => $valor) {
    $vazio = !isset($valor) || trim($valor) === '';
    printf("   %-6s valor %-24s em branco: %s\n", $campo, var_export($valor, true), var_export($vazio, true));
}

// Comparacao estrita entre tipos diferentes e sempre falsa, sem excecao.
echo "\nTipos diferentes nunca passam no ===\n";
$misturados = [[1, 1.0], [1, '1'], [0, false], [0, null], [null, ''], [[], false]];
foreach ($misturados as [$a, $b]) {
    printf(
        "   %-8s vs %-8s  ==: %-6s  ===: %s\n",
        var_export($a, true),
        var_export($b, true),
        var_export($a == $b, true),
        var_export($a === $b, true)
    );
}

Saída real

A        B                   ==     ===   
17       "17"      integer/string true   false 
17       17        integer/integer true   true  
0        ""        integer/string false  false 
0        null      integer/NULL true   false 
0        false     integer/boolean true   false 
"0"      ""        string/string false  false 
"0"      false     string/boolean true   false 
1        true      integer/boolean true   false 
"abc"    0         string/integer false  false 
1.0      true      double/boolean true   false 
"1"      true      string/boolean true   false 
0.0      null      double/NULL true   false 

Negacoes com os mesmos pares
  17     vs '17'     !=: false   !==: true    <>: false
  0      vs ''       !=: true    !==: true    <>: true
  0      vs NULL     !=: false   !==: true    <>: false
  0      vs false    !=: false   !==: true    <>: false
  '0'    vs false    !=: false   !==: true    <>: false

Validacao de formulario feita com ==
   resultado: CEP 01310-100 aceito

Como tratar isso de verdade
   nome   valor ''                       em branco: true
   email  valor '[email protected]'    em branco: false
   obs    valor '0'                      em branco: false

Tipos diferentes nunca passam no ===
   1        vs 1.0       ==: true    ===: false
   1        vs '1'       ==: true    ===: false
   0        vs false     ==: true    ===: false
   0        vs NULL      ==: true    ===: false
   NULL     vs ''        ==: true    ===: false
   array (
) vs false     ==: true    ===: false