Você está na página 1de 52

Capítulo 1. Criando sites com PHP e MySQL.................................................................................

2
Cliente e servidor..............................................................................................................................2
Antes de começar..............................................................................................................................2
Capítulo 2. Sintaxe do PHP..............................................................................................................2
Apóstrofes e aspas............................................................................................................................3
Operadores........................................................................................................................................3
Variáveis...........................................................................................................................................4
Arrays...............................................................................................................................................5
Estruturas de controle.......................................................................................................................5
Funções.............................................................................................................................................9
Capítulo 3. Avançando um pouco...................................................................................................10
Usando forms..................................................................................................................................10
Includes...........................................................................................................................................16
Query String...................................................................................................................................19
Seções e cookies.............................................................................................................................21
Funções de data e hora...................................................................................................................25
Mandando E-mails..........................................................................................................................29
Manipulando Arquivos e Diretórios...............................................................................................32
Capítulo 4. Introdução ao MySQL.................................................................................................36
Breve resumo das funções SQL.....................................................................................................36
Alterando dados do banco de dados...............................................................................................38
Exibindo Dados..............................................................................................................................41
Criando queries flexíveis................................................................................................................43
Capítulo 5. Tutorial Final...............................................................................................................44
Construindo um mural de recados..................................................................................................44

1
Capítulo 1. Criando sites com PHP e MySQL
Resumo

Como o PHP e o MySQL são programas de servidor, você precisará de um servidor que os rode. Caso você não
tenha acesso a tal recurso, você pode instalar um servidor web em seu computador e depois instalar o PHP e o
MySQL. Para saber como fazer isso, siga até o apêndice para maiores informações.

Cliente e servidor
Para que você possa acessar qualquer site da internet, é necessário que esse site esteja armazenado em um
servidor; como o nome já diz, o servidor é responsável por servir qualquer um que peça uma cópia do site
desejado. Esse um que pede a cópia é chamado cliente e, no caso mais comum, é uma pessoa usando um
navegador de internet (browser).

Antes de começar...
Site Dinâmico?
Um site dinâmico é aquele que tem suas páginas geradas na hora em que o cliente o visita. O HTML que o
usuário final vê não existe em nenhum lugar no servidor e foi criado apenas para ele, de acordo com os
comandos de um script, que funciona exatamente como um programa de computador. Essa geração "ao vivo"
abre caminho para possibilidades muito grandes e interessantes na construção de sites, pois agora um site não é
mais um arquivo HTML estático e passa a funcionar como um programa comum de computador, seguindo
comandos, estruturas de controle, valores de variáveis, cálculos e tudo mais.

E onde o PHP entra nessa história?


O PHP (sigla recursiva para 'PHP: Hypertext Preprocessor') é uma ferramenta de código aberto e gratuita que
tem como objetivo principal a criação dos sites dinâmicos citados acima. Ele interpreta um script e gera em tempo
real (e apenas para o usuário que está visitando a página) um HTML normal, que pode ser aberto e visitado por
qualquer navegador. Dessa maneira, quando uma pessoa está visitando uma página em PHP, aquele HTML que
está sendo mostrado não existe no servidor e foi gerado pelo interpretador do PHP, de acordo com o conteúdo do
script. Portanto, temos que o PHP interpreta um script e gera um arquivo HTML; o navegador recebe esse arquivo
HTML (e somente esse arquivo HTML), o interpreta e gera algo "bonitinho" para o usuário final. Note que nesse
processo o código de seu script nunca fica acessível ao usuário visitante.

O PHP não é o único


Além do PHP, existem outras ferramentas para a criação de sites dinâmicos, como o ASP (Active Server Pages)
da Microsoft e o JSP (JavaServer Pages) da Sun. Apesar da concorrência, o PHP é o mais usado atualmente na
internet, principalmente pelo fato de ser robusto, flexível, rápido, ter código aberto e ser gratuito.

E o MySQL?
O MySQL é a ferramenta mais usada na internet para gerenciar bancos de dados. Como o PHP, ele também
possui código aberto e é gratuito. Existem vários outros bancos de dados disponíveis no mercado, como o
Microsoft Access, o Microsoft SQL Server, o PostgreSQL, e muitos outros.

Capítulo 2. Sintaxe do PHP


Resumo

A sintaxe do PHP é uma miscelânea de várias linguagens de programação consagradas, como C e Java. Para
quem já tem conhecimentos em alguma dessas linguagens, o entendimento desse capítulo torna-se mais fácil.

2
Abaixo segue uma pequena introdução sobre o básico da sintaxe do PHP.

Apóstrofes e aspas
No PHP, um valor pode ser atribuído à uma string usando-se aspas ("string") ou apóstrofes ('string'). Caso só
existam caracteres normais dentro da string, o efeito será o exatamente o mesmo, independentemente do uso de
aspas ou apóstrofes. Porém, quando se usa variáveis dentro de strings, o efeito é completamente diferente. As
aspas permitem que você insira o valor de variáveis dentro de strings sem precisar fazer concatenação, já as
apóstrofes não. Perceba:

<?php
$nome = 'João';
echo "Olá, meu nome é $nome !"; // O resultado é 'Olá, meu nome é João !'
echo 'Olá, meu nome é $nome !'; // O resultado é 'Olá, meu nome é $nome !'
echo 'Olá, meu nome é '. $nome . ' !'; // O resultado é 'Olá, meu nome é
João !'
?>

Dica
echo: é a principal função para exibir dados no arquivo de saída (o HTML, no caso).

Operadores
Operadores Aritméticos
Exemplo Nome Resultado
$a + b Adição Soma de $a e $b
$a - $b Subtração Diferença entre $a e $b
$a * $b Multiplicação Produto de $a e $b
$a / $b Divisão Quociente de $a e $b
$a % $b Módulo Resto da divisão de $a e $b

Operadores de Atribuição
O operador básico de atribuição é o "=", que significa "recebe" e não "igual", como pode parecer.

<?php
$a = '3';
echo $a // retorna 3
?>

É importante mencionar que existem também os operadores combinados, que são o operador de atribuição mais
um operador aritmético.

<?php
$a =+ 5; // é a mesma coisa que $a = $a + 5;
?>

Operadores de comparação
Exemplo Nome Resultado
$a == $b Igual Verdadeiro se $a é igual a $b
$a === $b Idêntico Verdadeiro se $a é igual a $b e eles são do mesmo tipo (PHP4)
$a != $b Diferente Verdadeiro se $a é diferente de $b
$a <> $b Diferente Verdadeiro se $a é diferente de $b

3
Exemplo Nome Resultado
$a !== $b Não idêntico Verdadeiro se $a é diferente de $b, ou se eles não são do mesmo tipo (PHP4)
$a < $b Menor Verdadeiro se $a é menor que $b
$a > $b Maior Verdadeiro se $a é maior que $b
$a <= $b Menor ou igual Verdadeiro se $a é menor ou igual a $b
$a >= $b Maior ou igual Verdadeiro se $a é maior ou igual a $b

Operadores Lógicos
Exemplo Nome Resultado
$a and $b e Verdadeiro quando $a e $b são verdadeiros
$a or $b ou Verdadeiro se $a ou $b são verdadeiros
$a xor $b xor Verdadeiro se $a ou $b são verdadeiros, mas não ambos
!$a não Verdadeiro se $a é falso
$a && $b e Verdadeiro quando $a e $b são verdadeiros
$a || $b ou Verdadeiro se $a ou $b são verdadeiros

Operadores de string
Existem apenas 2 operadores de string. O de concatenação (".") e o de atribuição de concatenação (".="). Eles
funcionam assim:

<?php
$a = 'Meu nome é ';
$a .= 'José'; // a mesma coisa que $a = $a . 'José';
?>

Operadores de Arrays
Exemplo Nome Resultado
$a + $b União União de $a e $b
$a == $b Igualdade Verdadeiro se $a e $b tem os mesmos elementos
$a === $b Identidade Verdadeiro se $a e $b tem os mesmos elementos e eles estão na mesma ordem
$a != $b Desigualdade Verdadeiro se $a e $b não tiverem os mesmos elementos
$a <> $b Desigualdade Verdadeiro se $a e $b não tiverem os mesmos elementos
$a !== $b Não idêntico Verdadeiro se $a e $b não possuem os mesmos elementos na mesma ordem

Variáveis
Como a maioria das linguagens de scripts de servidor, o PHP não é fortemente tipado; ou seja, as variáveis não
possuem tipos definidos e restritos, como ocorre em Pascal, Java, Delphi etc. Também não é preciso fazer a
declaração das variáveis; assim que atribuímos algum valor a uma variável, ela passa a existir automaticamente.
Por um lado isso é bom, pois você não precisa ficar se preocupando com declarar variáveis e atribuir tipos a elas.
Por outro lado é ruim pois você pode "perder o controle" das variáveis dentro de seu script (caso elas sejam
muitas); além disso, perde-se bastante performance com linguagens não tipadas, pois o parser (ou interpretador)
precisa perder tempo para "descobrir" qual o tipo da variável.

Também é importante lembar que o PHP é case-sensitive, ou seja, ele distingüe letras maiúsculas de letras
minúsculas. Poranto, $nome é diferente de $Nome

<?php
$carro = 'Fiat Stilo';
$Carro = 'VW Golf';
echo $carro; // retorna 'Fiat Stilo'
echo $Carro; // retorna 'VW Golf'
?>

4
Arrays
Arrays são os conhecidos vetores. Eles guardam várias informações em apenas uma variável. Para indexar um
array no PHP, usamos as chaves [ ]. Como em C, os arrays númericos tem o zero como o primeiro íncice. Dessa
maneira, temos algo assim:

<?php
$frutas = array('maçã','banana','abacate');
echo $frutas[1]; // retorna 'banana'
?>

No PHP existem dois tipos de arrays, os numéricos e os associativos. Os numéricos possuem números inteiros
como chaves (índice); já os associativos possuem strings como chaves.

<?php
// Array numérico
$frutas = array('maçã','banana','abacate');
echo $frutas[2]; // retorna 'abacate'

// Array associativo
$frutas = array("a" =>; 'maça', "b" => 'banana', "c" => 'abacate');
echo $frutas['a']; // retorna 'maçã'

// Nada nos impede de misturar os dois tipos


$ frutas = array('maçã', "preferida" => 'banana');
echo $frutas['preferida']; // retorna 'banana'

// Array dentro de array


$frutas = array("vermelhas" => array('morango','cereja',framboesa));
echo $frutas['vermelhas'][0]; // retorna 'morango'
?>

Estruturas de controle
Resumo

Em um programa de computador, existe o fluxo do código fonte, que é o modo como o computador executa
determinadas cadeias de comandos, de acordo com teste binários e coisas do tipo. Estruturas de controle servem
para controlar esse fluxo, porém, no nosso caso, não exatamente em um programa e sim em seu site PHP.
Abaixo segue uma breve explicação sobre a sintaxe das estruturas de controle que encontramos no PHP:

if
if ($expressao) {
comandos
}

O fluxo do programa somente executa os comandos que estão dentro do if caso o resultado da $expressao
seja verdadeiro (true).

<?php
if ($a == $b) {
echo 'A é igual a B';
}
?>

else

5
if ($expressao) {
comandos
}
else {
outros comandos
}

Caso o resultado de $expressao seja falso, então o fluxo entra no else e executa os "outros comandos".

<?php
if ($a == $b) {
echo 'A é igual a B';
}
else {
echo 'A é diferente de B';
}
?>

elseif
if ($expressao) {
comandos
}
elseif ($outros_expressao) {
outros comandos
}

Caso uma expressão de um if seja falsa, você pode fazer outra comparação antes de entrar nos comandos do
else.

<?php
if ($a > $b) {
echo "A é maior que B";
}
elseif ($a == $b) {
echo "A é igual a B";
}
else {
echo "A é menor que B";
}
?>

while
while ($expressao) {
comandos
}

While, do inglês, significa "enquanto". A estrutura de controle while executa os comandos nela aninhados
enquanto uma expressão for veradeira.

<?php
$a = 1;
while ($a <= 10) {
echo $a;
$a++; // mesma coisa que $a = $a + 1
// Os camandos que estão dentro do while serão executados
// enquanto a variável $a for menor ou igual a 10.
// No exemplo acima, serão exibidos todos os números inteiros
// até o número 10. Assim que $a for maior que 10, o fluxo

6
// de execução sai do while.
}
?>

do...while
do {
comandos
} while ($expressao)

A estrutura do...while faz a mesma coisa que o while, porém a verificação da $expressao é feita após os
comandos e não antes, garantindo que o fluxo de execução entre no while ao menos uma vez, mesmo se na
primeira repetição o resultado da $expressao seja falso.

<?php
$a = 5;
do {
echo $a;
} while ($a > 5);
?>

for
for ($expr1; $expr2; expr3) {
comandos
}

As estruturas de for são um pouco mais complicadas que as outras (funcionam da mesma maneira que na
linguagem C). A $expr1 é executada apenas na primeira vez da repetição, por isso contém o primeiro valor da
chave de comparação, normalmente. A $expr2 é executada em toda repetição e caso o resultado seja false, o
fluxo sai do for. A $expr3 é executada ao final de toda repetição.

<?php
for ($a = 1;$a < 10; $a++) {
echo $a;
}
// Quando o fluxo de execução entra no for acima, a variável
// $a recebe o valor 1. Enquanto $a for menor que 10, o
// fluxo continua dentro do for (essa verificação é executada
// sempre no começo da repetição). Quando os comandos aninhados
// ao for acabam, a variável $a recebe $a + 1, devido a
// terceira expressão da estrutura for ($a++).
?>

foreach
foreach ($array as $valor) {
comandos
}
foreach ($array as $chave => $valor) {
comandos
}

O foreach é uma maneira fácil de andar dentro de um array. O que ele faz é repetir comandos enquanto
existirem elementos dentro de um array. Existem duas sintaxes para usar o foreach, cada uma gerando um
resultado diferente.

<?php
$frutas = array('banana','maça','mamão','manga');

7
// O fluxo de execução executará repetirá os comandos aninhados ao
// foreach até acabarem os valores do array $frutas. A cada
// repetição o valor atual é atribuído a variável $valor
foreach($frutas as $valor) {
echo $valor; // é exibida um dos valores de $frutas a cada repetição
}

// Essa sintaxe do foreach faz a mesma coisa que a sintaxe acima,


// porém ela atribui o valor da chava atual à variavel $chave
// (além do valor atual à variável $valor).
foreach($frutas as $chave => $valor) {
echo $chave . '-' . $valor; // retorna algo como '2 - mamão' a cada
repetição
}
?>

switch
switch ($expressao) {
case x :
comandos;
break;
case y :
comandos;
break;
...
}

Um switch testa vários valores para uma mesma $expressao e executa comandos de acordo com esses
valores. Substitui o uso de vários ifs.

<?php
// Note que o break faz parte da sintaxe e é necessário para que o
// switch funcione como deve.
switch ($a) {
case 0 :
echo 'a é igual a zero';
break;
case 1 :
echo 'a é igual a um';
break;
case 2 :
echo 'a é igual a dois'
break;
}
// O switch acima é equivalente a essa cadeia de ifs
if ($a == 0)
echo 'a é igual a zero';
elseif($a == 1)
echo 'a é igual a um';
elseif($a == 2)
echo 'a é igual a dois'
?>

Dica
Nota: switchs são mais rápidos que vários ifs aninhados.

break

8
O comando break pára a execução do for,foreach,while,do...while ou switch atual.

<?php
while ($a < 10) {
$a = $a * $b;

if ($a <= -1)


break;
}
?>

Funções
Resumo

Como em qualquer outra linguagem de programação, o PHP possibilita a criação de funções (e procedimentos,
caso você esteja familiarizado com Pascal). As funções são muito úteis para a vida do programador, pois ajudam
a diminuir a repetição desnecessária de código e também a tornar o código mais fácil de entender.

Criando funções
A sintaxe de uma função no PHP é muito simples.

function nome_da_função (parâmetros da função) { }

Escopo
Vale lembrar que uma função só tem acesso às variáveis criadas dentro dela, às variáveis passadas por
parâmetro e às variáveis superglobais. Caso você queira usar uma variável global que foi criada dentro de seu
script, basta usar a palavra global antes do nome da variável.

<?php
function teste() {
global $a; // chama a global $a, criada fora da função
echo $a; // retorna 'Olá !!!'

$a = 'Olá !!!';
teste(); // Executa a função teste()
?>

Passando por parâmetro


Para evitar o uso de variáveis globais, podemos passar por parâmetro aquelas variáveis que precisaremos usar
dentro da função. Assim:

<?php
function teste($a) {
echo $a; // retorna 'Olá !!!'

}
$a = 'Olá !!!';
teste($a);
?>

Passagem de parâmetro por referência

9
Para passar um parâmetro por referência, usamos o caracter & antes do recebimento do mesmo. Quando a
passagem de parâmetro é feita por referência, qualquer alteração que seja feita dentro da função é refletida fora
da função, na variável original.

<?php
function teste(&$b) {
$b = 'Tchau... :-(';
}
$a = 'Olá !!!';
echo $a; // Retorna 'Olá !!!'
teste($a);
echo $a; // Retorna 'Tchau... :-('
?>

Retornando valores
Assim como uma variável qualquer não pode ser acessada por uma função (a não ser pelas exceções citadas
acima), o contrário também acontece; variáveis de dentro da função só podem ser acessadas pela função. Caso
queiramos utilizar valores de uma variável que foi criada dentro de uma função, preicsamos usar a função
return.

<?php
function teste() {
$a = 7;
}
teste();
echo $a; // Não retorna nada
?>

<?php
function teste() {
$a = 7;
return $a;
}
$a = teste();
echo $a; // Retorna 7
?>

Capítulo 3. Avançando um pouco


Resumo

Agora que você já sabe o básico do funcionamento do PHP, resta aprender como tudo funciona na prática e, por
fim, aprender como construir sites dinâmicos. Nesse capítulo iremos passar por algumas técnicas muito comuns
para manipular dados pelo PHP.

Usando forms
Caso você tenha usado HTML antes, provavelmente nunca tenha chegado a usar a tag <form>; sem uma
aplicação de server-side scripting, apenas com HTML puro, ela não serve para muita coisa. Um form, como o
nome já diz, é um desses formulários que estamos já cansados de preencher na internet. A função dele é deixar
que o usuário entre com dados, para que esses dados sejam então processados e passados para um banco de
dados, onde são guardados e usados em aplicações futuras (caso seja um formulário de cadastro).

Figura 1.1. Formulário de cadastro

10
Formulário de cadastro

O formulário acima foi criado com o seguinte código HTML:

Exemplo 1.1. cadastro.html

<form method="post" action="cadastro_post.php">


<p>Nome do usuário: <br />
<input type="text" name="usuario" /></p>
<p>Senha do usuário: <br />
<input type="password" name="senha" /></p>
<p>Confirmação de senha: <br />
<input type="password" name="conf_senha" /></p>
<p><input type="submit" value="Enviar" />
<input type="reset" value="Resetar" /></p>
</form>

A tag form contém informações básicas do formulário. O campo action especifica para onde passar os dados
coletados no formulário. No campo method, especificamos o tipo do envio das informações para a página
especificada em action; o método post envia as informações apenas pelo cabeçalho do protoclo HTTP,
enquanto que o método get passa as informações diretamente pelo endereço do arquivo indicado em action.
Esse segundo tipo de método será muito útil quando fizermos query string, funcionalidade que estudaremos um
pouco mais adiante no curso.

A tag input é filha da tag form (ou seja, só pode existir dentro de form) e funciona para fazer a entrada de
dados. Ela precisa de um atributo type, para especificar o tipo de dado que é esperado. No exemplo acima,
temos:

• type="text": indica a entrada de texto comum. Opcionalmente, pode ter o atributo maxlenght para
indicar o tamanho máximo permitido e também o atributo width, especificando o tamanho mostrado na
tela do browser.
• type="password": indica a entrada de uma senha; o texto entrado nessa caixa é escondido com
asteriscos ou outros caracteres (dependendo do sistema operacional).
• type="submit": Cria um botão que submete os dados do form para a página que está indicada no
parâmetro action da tag-pai form.
• type="reset": Cria um botão que apaga o conteúdo de todos os campos do formulário, voltando-os
para o valor padrão.

Um form funciona basicamente da seguinte maneira: após preencher as informações do formulário e pressionar
Enviar, o browser será redirecionado para a página indicada em action; junto com esse redirecionamento,
serão envidos também as informações preenchidas pelo usuário em cadastro.html (seja essa passagem feita por
"post" ou por "get"). Feito isso, só falta tratar os dados dentro de cadastro_post.php de acordo com o desejado.
Nesse exemplo, faremos algo básico, simplesmente escrevendo na tela as informações preenchidas. Abaixo
segue uma breve explicação sobre duas superglobais do PHP ($_POST e $_GET):

Superglobias $_GET e $_POST


O PHP usa essas duas variáveis como superglobais, ou seja, sempre existem em qualquer parte dos scripts

11
(mesmo que contenham nada) e são reservadas. Quando um form é enviado com o método POST, os valores
são armazenados na superglobal $_POST. Quando vindo de um form, $_POST torna-se um array associativo, ou
seja, seus índices são strings; esses índices são o nome dos inputs contidos no form. Acessamos o valor da input
de nome "usuario", por exemplo, através do array $_POST de índice "usuario": $_POST['usuario']. A mesma
coisa acontece com a variável $_GET.

Sabendo isso, podemos passar para o código do arquivo cadastro_post.php:

Exemplo 1.2. cadastro_post.php

<?php
$usuario = $_POST['usuario'];
$senha = $_POST['senha'];
$conf_senha = $_POST['conf_senha'];
/* O que fizemos acima foi passar os valores da superglobal $_POST para uma
variável local. Isso não precisa necessariamente acontecer, porém torna sua
vida muito mais simples e é extremamente recomendado. */

// Agora tratamos os valores preenchidos no form


echo 'Olá ' . $usuario . '! Sua senha é: ' . $senha;
?>

Teste e perceba como os valores preenchidos no form são passados para o script definido em action e como
podemos acessar esses dados. Apesar de funcionar, esse script não faz nada de realmente interessante, nem
mesmo confirmar a senha. Abaixo, segue uma versão melhorada dele, com a confirmação de senha:

Exemplo 1.3. cadastro_post.php

<?php
$usuario = $_POST['usuario'];
$senha = $_POST['senha'];
$conf_senha = $_POST['conf_senha'];
if ($senha == $conf_senha) {
echo 'Olá ' . $usuario . '! Sua senha é: ' . $senha . ' e foi confirmada!';
}
else {
echo 'Sua senha não confere com a confirmação, favor tentar de novo';
}
?>

No script acima, caso o usuário digite a mesma senha no campo "senha" e no campo "confirmação de senha",
uma mensagem de sucesso é mostrada, dizendo o nome do usuário e a sua senha. Caso as senhas forem
diferentes, a mensagem de fracasso "Sua senha não confere com a confirmação, favor tentar
de novo" é mostrada.

Um jeito melhor
Apesar do exemplo acima funcionar, não devemos tratar forms exatamente desse jeito. Da maneira como esse
exemplo foi disposto, precisamos de dois arquivos para obter o resultado desejado: um para mostrar o formulário
(cadastro.php) e outro para processar os dados (cadastro_post.php). Com a ajuda da superglobal
$_SERVER do PHP poderemos consertar esse pequeno incômodo e deixar tudo muito mais limpo em apenas um
arquivo. Esse array existe em todo script automaticamente e contém informações do servidor e do cliente, como
endereço IP do cliente, caminhos, nome do servidor, entre muitas outras informações. O que usaremos em nosso
form é o índice 'PHP_SELF'; ele contém o nome do arquivo PHP do script atual, com relação a raiz do servidor.
Ou seja, $_SERVER['PHP_SELF'], se rodado no arquivo cadastro.php, de endereço
www.servidor.com/diretorio/cadastro.php, contém o valor /diretorio/cadastro.php.

Para fazer isso, precisaremos fazer duas pequenas alterações no arquivo cadastro.php . Abaixo segue o
novo código:

12
Exemplo 1.4. cadastro.php

<form method="post" action=<?php echo $_SERVER['PHP_SELF']; ?>">


<p>Nome do usuário: <br />
<input type="text" name="usuario" /></p>
<p>Senha do usuário: <br />
<input type="password" name="senha" /></p>
<p>Confirmação de senha: <br />
<input type="password" name="conf_senha" /></p>
<p><input type="hidden" name="verifica_envio" value="1" />
<input type="submit" value="Enviar" />
<input type="reset" value="Resetar" /></p>
</form>

Perceba que a action do form que antes indicava outro arquivo agora aponta para a o próprio script que está
sendo rodado, através da função $_SERVER['PHP_SELF']. A outra alteração no código foi a inserção da tag
<input type="hidden" name="verifica_envio" value="1" /> . Um input de tipo hidden
serve para passar informações ao arquivo indicado em action sem que o usuário as veja; essa tag é totalmente
invisível ao usuário que está preenchendo o formulário, porém ela existe e vai ser incorporada ao array $_POST
com o valor indicado em value.

O propósito dessa hidden é testar se o formulário foi submetido (ou seja, verificar se o botão Enviar foi clicado).
Faremos isso através da função array_key_exists() do PHP, que serve para testar se uma determinada
chave existe em um array.

bool array_key_exists ( mixed chave, array busca)

O arquivo cadastro_post.php deixa de existir e agora temos apenas o arquivo cadastro.php, que fica
assim:

Exemplo 1.5. cadastro.php

<?php
// Testa a existência da chave "verifica_envio" em $_POST
// Caso ela não exista, o formulário é mostrado ao usuário.
if (!array_key_exists("verifica_envio",$_POST)) {
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] . '">' . "\n";
echo '<p>Nome do usuário: <br />' . "\n";
echo '<input type="text" name="usuario" /></p>' . "\n";
echo '<p>Senha do usuário: <br />' . "\n";
echo '<input type="password" name="senha" /></p>' . "\n";
echo '<p>Confirmação de senha: <br />' . "\n";
echo '<input type="password" name="conf_senha" /></p>' . "\n";
echo '<p><input type="hidden" name="verifica_envio" value="1" />' . "\n";
echo '<input type="submit" value="Enviar" />' . "\n";
echo '<input type="reset" value="Resetar" /></p>' . "\n";
echo '</form>' . "\n";
}
// Caso a chave exista, os dados de $_POST são processados
else {
$usuario = $_POST['usuario'];
$senha = $_POST['senha'];
$conf_senha = $_POST['conf_senha'];

if ($senha == $conf_senha)
echo 'Olá ' . $usuario . '! Sua senha é: ' . $senha . ' e foi
confirmada!';
else
echo 'Sua senha não confere com a confirmação, favor tentar de novo';
}
?>

13
O script acima primeiro testa se a chave NÃO existe no array $_POST pelo comando if
(!array_key_exists("verifica_envio",$_POST)). Note que o ! funciona como negação no PHP.
Com isso, se a chave "verifica_envio" não existir no array, o formulário é mostrado ao usuário. No script acima o
formulário foi construído dentro do PHP, porém nada impede você de fechar o script com ?> e escrever as tags
direto no HTML; o resultado é exatamente o mesmo. O \n que está no final de todas as linhas serve apenas para
o PHP pular uma linha no arquivo de saída gerado, para deixar o código fonte um pouco mais bonito e legível.

Caso a chave exista dentro do array, então os dados do form são processados exatamente da mesma maneira
como tínhamos feito no arquivo cadastro_post.php.

Modularizando tudo
Existe uma maneira de melhorar esse código ainda mais, que é a modulaziração do código, usando functions que
você aprendeu anteriormente nesse curso. A idéia é acabar com todas essas linhas do if e do else, atribuindo
uma função para cada ocasião. Algo assim:

Exemplo 1.6. cadastro.php [ principal ]

<?php
if (!array_key_exists("verifica_envio",$_POST)) {
exibe_form();
}
else {
processa_form();
}
?>

Percebeu como tudo fica muito mais simples e estruturado? É muito mais fácil de entender e manter o código
quando se modulariza.

Exemplo 1.7. cadastro.php [ functions ]

<?php
function exibe_form() {
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] . '">' . "\n";
echo '<p>Nome do usuário: <br />' . "\n";
echo '<input type="text" name="usuario" /></p>' . "\n";
echo '<p>Senha do usuário: <br />' . "\n";
echo '<input type="password" name="senha" /></p>' . "\n";
echo '<p>Confirmação de senha: <br />' . "\n";
echo '<input type="password" name="conf_senha" /></p>' . "\n";
echo '<p><input type="hidden" name="verifica_envio" value="1" />' . "\n";
echo '<input type="submit" value="Enviar" />' . "\n";
echo '<input type="reset" value="Resetar" /></p>' . "\n";
echo '</form>' . "\n";
}
function processa_form () {
$usuario = $_POST['usuario'];
$senha = $_POST['senha'];
$conf_senha = $_POST['conf_senha'];

if ($senha == $conf_senha)
echo 'Olá ' . $usuario . '! Sua senha é: ' . $senha . ' e foi
confirmada!';
else
echo 'Sua senha não confere com a confirmação, favor tentar de novo';
}
?>

Como resultado final, temos o script:

14
Exemplo 1.8. cadastro.php [ quase lá ]

<?php
function exibe_form() {
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] . '">' . "\n";
echo '<p>Nome do usuário: <br />' . "\n";
echo '<input type="text" name="usuario" /></p>' . "\n";
echo '<p>Senha do usuário: <br />' . "\n";
echo '<input type="password" name="senha" /></p>' . "\n";
echo '<p>Confirmação de senha: <br />' . "\n";
echo '<input type="password" name="conf_senha" /></p>' . "\n";
echo '<p><input type="hidden" name="verifica_envio" value="1" />' . "\n";
echo '<input type="submit" value="Enviar" />' . "\n";
echo '<input type="reset" value="Resetar" /></p>' . "\n";
echo '</form>' . "\n";
}
function processa_form () {
$usuario = $_POST['usuario'];
$senha = $_POST['senha'];
$conf_senha = $_POST['conf_senha'];

if ($senha == $conf_senha)
echo 'Olá ' . $usuario . '! Sua senha é: ' . $senha . ' e foi
confirmada!';
else
echo 'Sua senha não confere com a confirmação, favor tentar de novo';

}
// Comandos principais
if (!array_key_exists("verifica_envio",$_POST)) {
exibe_form();
}
else {
processa_form();
}
?>

Verificando o preenchimento dos campos


Uma outra funcionalidade que seria interessante colocarmos em nosso form é a verificação de preenchimento dos
campos. Através da função empty(), podemos fazer isso facilmente e avisar o usuário caso ele tenha se
esquecido de preencher alguma coisa.

Exemplo 1.9. cadastro.php [ final ]

<?php
function exibe_form() {
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] . '">' . "\n";
echo '<p>Nome do usuário: <br />' . "\n";
echo '<input type="text" name="usuario" /></p>' . "\n";
echo '<p>Senha do usuário: <br />' . "\n";
echo '<input type="password" name="senha" /></p>' . "\n";
echo '<p>Confirmação de senha: <br />' . "\n";
echo '<input type="password" name="conf_senha" /></p>' . "\n";
echo '<p><input type="hidden" name="verifica_envio" value="1" />' . "\n";
echo '<input type="submit" value="Enviar" />' . "\n";
echo '<input type="reset" value="Resetar" /></p>' . "\n";
echo '</form>' . "\n";
}
function processa_form () {
$usuario = $_POST['usuario'];
$senha = $_POST['senha'];

15
$conf_senha = $_POST['conf_senha'];
// Verificação do preenchimento
if ( (!empty($usuario)) and (!empty($senha)) and (!empty($conf_senha)) ) {
if ($senha == $conf_senha)
echo 'Olá ' . $usuario . '! Sua senha é: ' . $senha . ' e foi
confirmada!';
else
echo 'Sua senha não confere com a confirmação, favor tentar de novo';
}
else
echo 'Você não preencheu todos os campos do formulário';

}
// Comandos principais
if (!array_key_exists("verifica_envio",$_POST)) {
exibe_form();
}
else {
processa_form();
}
?>

Includes
Instruções de include facilitam muito a vida do programador, pois elas servem (basicamente) para centralizar
scripts comuns em arquivos diferentes, ajudando a manter a fluidez, diminuindo o espaço em disco ocupado pelo
site e melhorando bastante a facilidade de manutenção do mesmo. Na prática, o que elas fazem é copiar o
conteúdo de um arquivo especificado para dentro do script atual. Esse arquivo pode ser tanto um arquivo texto
simples quanto um arquivo de outro script PHP.

Existem quatro instruções de include e nesse capítulo vamos estudar todas. A diferença básica entre elas é a
maneira como os erros são manipulados.

Na prática
Exemplo 1.10. numeros.php

<p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 </p>

Exemplo 1.11. outroarquivo.php

<?php
echo "<p> Aprendendo a contar: </p> \n ";
include ("numeros.php");
?>

A operação contida em outroarquivo.php copia o conteúdo do arquivo numeros.php, e o resultado é o


mesmo que teríamos se o conteúdo de numeros.php fosse explicitamente copiado dentro do arquivo
outroarquivo.php. Como você já pode imaginar, o resultado no browser, é um HTML assim:

Exemplo 1.12. Resultado

<p> Aprendendo a contar: </p>


<p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 </p>

Note que no exemplo acima o arquivo que especificamos era um arquivo de texto comum e o PHP não encontrou
problemas em incluí-lo. A mesma coisa acontece com arquivos PHP; caso o arquivo de inclusão possua um script
(o interpretador sabe disso simplesmente pela tag (<?php), todas as variáveis, funções e comandos serão
executados da mesma maneira.

16
A vantagem de usar include só é percebida quando o conteúdo de um arquivo é usado mais de uma vez no
decorrer do seu site. Suponhamos que seu site tenha 20 páginas e que cada uma dessas páginas possua um
cabeçalho e um rodapé. As informações contidas no cabeçalho e no rodapé, apesar de serem totalmente
idênticas, terão de ser copiadas em todas as suas 20 páginas. Além de gastar tempo e espaço, essa abordagem
torna muito difícil a atualização dos dados do rodapé e do cabeçalho; sempre que você fizer uma mudança, por
menor que seja, em seu rodapé (ou cabeçalho), 20 arquivos precisarão ser alterados. Você pode até pensar que
20 arquivos não são muito coisa para atualiar manualmente, mas imagine um site de grande porte, com milhares
de páginas; alterar página por página torna-se totalmente inviável e um tanto quanto irracional.

Montando um site com includes você não tem esse tipo de problema, afinal o rodapé fica centralizado em apenas
um arquivo (assim como o cabeçalho), portanto basta alterar um arquivo para que todo seu site seja alterado.

Primeiramente vamos montar dois arquivos simples, um com as informações do cabeçalho e outro arquivo com
as informações do rodapé.

Exemplo 1.13. cabecalho.php

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1" />
<link rel="stylesheet" type="text/css" media="all" href="estilo.css" />
<title> Meu Site </title>
</head>
<body>
<h1>Esse é meu site!</h1>

Exemplo 1.14. rodape.php

<div id="rodape"> Site feito por João da Silva </div>


</body>
</html>

Agora que temos os arquivos de cabeçalho e rodapé montados, basta montar a estrutura das páginas de seu site.

Exemplo 1.15. minha_pagina.php

<?php
include ("cabecalho.php");
?>
<p>
Conteúdo de cada página do site.
</p>
<?php
include ("rodape.php");
?>

Com essa estrutura, além da manutenção de seu site ficar muito mais simplificada, seu site ocupa menos espaço
no servidor, afinal não existe repetição inútil de dados em vários arquivos.

A função require
Quando um arquivo indicado na instrução include não é encontrado, uma Warning é disparada e o resto do script
continua a ser lido e processado, podendo causar mais erros ao longo do script, em operações que dependiam do
conteúdo do arquivo que deu erro anteriormente. Para evitar isso, usamos a função require, que, em caso de
erro, dispara um Fatal Error, parando a execução do script. O uso do require é idêntico ao do include.

Exemplo 1.16. minha_pagina.php

<?php
require ("cabecalho.php");
?>

17
<p>
Conteúdo de cada página do site.
</p>
<?php
require ("rodape.php");
?>

No exemplo acima, caso o arquivo cabecalho.php não for encontrado, a execução do script pára, impedindo
assim a exibição do conteúdo da página e do rodapé. Com o arquivo rodape.php, o script também pára em
caso de erro, porém pouca coisa é afetada nesse aqui.

require_once e include_once
Os operadores require_once e include_once funcionam exatemente como seus "pais", porém impedem que o
mesmo arquivo seja incluído mais de uma vez durante um script.

Mergulhando em includes
Outra ótima função para as instruções include é a centralização de funções comuns à várias páginas de seu site
em arquivos separados. Imagine que você tenha uma função em seu site que possui um pequeno número de
frases famosas que você gosta; quando chamada, essa mesma função retorna uma dessas frases, escolhida
aleatoriamente. Por algum motivo, você precisa dessa função em várias páginas de seu site, portanto, decide
usar include. Pois sua escolha foi a certa e seus arquivos devem ser construídos, no geral, assim:

Exemplo 1.17. funcoes.inc.php

<?php
function frase() {
// Cria vetor com as frases
$frases = array("'A ciência poderá ter achado a cura para a maioria dos
males,
mas não achou ainda remédio para o pior de todos: a apatia dos seres
humanos',
Helen Keller",
"'O mundo é um lugar perigoso de se viver, não por causa daqueles que
fazem o mal,
mas sim por causa daqueles que observam e deixam o mal acontecer',
Albert Einstein");
// Sorteia uma chave do vetor
$escolhida = array_rand($frases,1);
// Retorna a frase escolhida
return $frases[$escolhida];
}
?>

Dica
Observação: É interessante marcar os arquivos de include com um nome diferente dos
outros, como foi feito no exemplo acima; isso ajuda você a se situar melhor caso seu
projeto fique com uma grande quantidade de arquivos.

Exemplo 1.18. principal.php

<?php
// Inclui o arquivo que contém a função
require ("funcoes.inc.php");
echo frase();
?>

Note que após a inclusão do arquivo funcoes.inc.php que contém a função frase(), utilizamos essa

18
função da mesma maneira como a utilizaríamos se ela estivesse realmente no arquivo principal.php.

Retornando valores de arquivos incluídos


Você também pode usar a instrução return para retornar algum valor de um arquivo incluído da mesma maneira
como faz em funções. Veja no exemplo:

Exemplo 1.19. carro.inc.php

<?php
$carro = 'Volkswagen';
// Retorna para o script que chamou o arquivo o valor da variável $carro
return $carro;
?>

Exemplo 1.20. meu_carro.php

<?php
$meucarro = include 'carro.inc.php';
echo 'Meu carro é um ' . $meucarro;
?>

Resumindo tudo
Abaixo segue uma pequena tabela para referência das funções de include

Instrução Descrição
include Inclui o arquivo especificado; em caso de erro, o script continua a ser executado.
require Inclui o arquivo especificado; em caso de erro, a execução do script é cancelada.
Inclui o arquivo especificado e verifica se esse arquivo já não foi incluído em algum outro comando
include_once
do script. Em caso de erro, o script continua a ser executado.
Inclui o arquivo especificado e verifica se esse arquivo já não foi incluído em algum outro comando
require_once
do script. Em caso de erro, a execução do script é cancelada.

Query String
Com certeza você já deve ter passado por sites que usam query string; pode ser que você não tenha notado, mas
aconteceu. Um site que usa query string tem, normalmente, um endereço como:

http://www.nomedosite.com/nomedoarquivo.php?pag=produto&id=123

Esse tipo de construção é muito usado em lojas virtuais, pelo fato dos produtos conterem informações repetidas e
um layout completamente comum entre as várias páginas do site. O que uma query string faz é montar uma
página de acordo com os dados passados pelo endereço (URL). Esses dados, como você pode perceber, são
passados pelo mesmo método GET que podemos usar também com forms. Como você é astuto, já deve estar
imaginando como acessar variáveis de query strings; sim, da mesma maneira como acessávamos variáveis GET
de forms, usando a variável superglobal $_GET.

Um começo
No capítulo anterior você aprendeu a mexer com funções de inclusão. Elas ajudam muito a diminuir (se não
acabar) com a repetição inútil de dados redundantes, porém quando aliadas às query strings, ajudam mais ainda.
Perceba como:

Exemplo 1.21. Exemplo simples de query string

<?php
// Cria uma variável com o valor da query string 'pagina'

19
$pagina = $_GET['pagina'];

// Se $pagina é igual a 'primeira', inclui o arquivo primeirapagina.php


if ($pagina == 'primeira')
include('primeirapagina.php');

// Se $pagina é diferente de 'primeira', testa se $pagina é igual a


'segunda'
elseif($pagina == 'segunda')
include('segundapagina.php');

// Se $pagina é diferente de 'primeira' e 'segunda', inclui a primeira


página
else
include('primeirapagina.php');
?>

O que fizemos no exemplo acima foi testar o valor de $_GET['pagina'] e tratar a página de acordo com o
resultado. Perceba que para $pagina ter uma valor, é preciso passar a query string pelo endereço da página.
Por exemplo:

nomedoarquivo.php?pagina=primeira

Esse recurso, aliado a modularização que aprendemos no capitulo sobre includes, além de separar o cabeçalho e
o rodapé do resto do conteúdo, podemos também separar o conteúdo da página, mantendo seu site bastante
modularizado, facilitando a manutenção.

Exemplo 1.22. principal.php

<?php
// Atribui o valor de $_GET['pagina'] à variável $pagina
if (!isset($_GET['pagina']))
$pagina = 'primeira';
else
$pagina = $_GET['pagina'];

// Inclui arquivo com o cabeçalho


include ("cabecalho.php");

if ($pagina == 'primeira')
include ('primeirapagina.php');
elseif ($pagina == 'segunda')
include ('segundapagina.php');

// Caso uma 'pagina' inválida é recebida, inclui primeirapagina.php


else
include ('primeirapagina.php');

// Inclui arquivo com o rodapé


include ("rodape.php");
?>

Note que o começo de nosso código ficou um pouco diferente da versão anterior; aqui estamos fazendo um teste
para ver se uma query string com um valor para $pagina foi passado à página atual. Caso nada tenha sido
passado (!isset()), a variável recebe primeira e, conseqüentemente o arquivo primeirapagina.php é
incluído como conteúdo da página. Esse pedaço de código ainda pode ficar mais sofisticado e muito mais simples
se substituído pela simples linha:

<?php $page = !isset($_GET['pagina']) ? 'primeira' : $_GET['pagina']; ?>

Se você não entendeu nada do operador acima, veja a função de tradução de datas criada no capítulo que trata
datas e horas; lá existe uma explicação mais detalhada.

20
Dica
Nota: Você pode usar quantas variáveis quiser dentro de sua query string usando o
operador & para serapá-las. Como em
arquivo.php?pagina=primeira&nome=joao&idade=23. Não que esse exemplo sirva para
algo, mas você pode (e deve) usar quantas variáveis necessárias em sua query string
para manipular sua página.

E tem mais...
Esse modo como aprendemos a usar query-strings é bem útil, pois poupa seu trabalho e ainda modulariza seus
arquivos de uma maneira bem consistente. Apesar disso, as query-strings serão bastante úteis quando
aprendermos a construir queries dinâmicas em SQL, um pouco mais a frente em nosso curso.

Seções e cookies
Resumo

Seções e cookies são usados para manter informações através dos vários scripts de seu site. Com eles,
podemos salvar uma informação no arquivo um e ter acesso a essa mesma informação no arquivo dois.
Carrinhos de compra de lojas virtuais funcionam dessa maneira. A diferença básica que podemos apontar entre
um cookie e uma seção, é a durabilidade; uma seção dura até o browser ser fechado pelo usuário ou então até
que seu tempo de "vida" se esgote (esse tempo de vida não passa de alguns minutos). Já os cookies "vivem"
depois do browser ser fechado e seu tempo de vida é, geralmente, muito maior.

Seções
Por agora, você não precisa se preocupar em usar cookies; esqueça que eles existem. O que nos importa agora
são as seções. Como foi dito acima, elas existem até que o browser seja fechado pelo usuário ou então até que
seu tempo limite se esgote. Apesar das seções serem um pouco mais complicadas do que isso, esse é seu
funcionamento básico e tudo que você precisa saber.

Para serem propagadas entre as páginas de seu site, as seções podem ser armazenadas de duas maneiras
diferentes: por cookies ou então como um parâmetro na URL (pela query-string). Você pode até achar estranho
passar seções por cookie, mas essa informação precisa ser guardada de alguma maneira, e cookies são bem
úteis para esse propósito. Note que os cookies nem sempre estão disponíveis no computador do usuário (eles
são armazenados no cliente, portanto dependem da configuração do navegador), por isso existe a possibilidade
de propagar pelo endereço (URL). Na verdade, seja propagando a seção por cookie ou pela URL, o que fazemos
é propagar a Session ID que é um código único gerado a cada vez que seu browser é aberto. Quando salvamos
informações em uma variável de sessão, ela é guardada em uma pasta do servidor, contendo, além da
informação armazenada, esse ID. Com isso, temos a Session ID no servidor e no cliente e podemos cruzar essas
informações e obter os dados que desejamos.

As seções e os cookies têm um pequeno problema de implementação (que talvez não seja tanto um problema
como apenas uma característica); eles precisam ser a primeira coisa a ser passada para o browser. Ou seja,
nenhum tipo de dado pode ter sido enviado ao browser; nenhuma tag HTML, nenhum echo e nem mesmo uma
mensagem de erro do próprio PHP. Isso acontece porque as informações de cookie e seção são enviadas no
cabeçalho do protocolo HTTP (HTTP Header); quando você escreve algo no browser (como um <head>, por
exemplo), esse cabeçalho é enviado automaticamente, tornando impossível a chamada de uma seção ou um
cookie, exatamente pelo fato da alteração do HTTP Header. Muita teoria, mas o que você precisa saber é que
seções e cookies tem de ser enviados antes de qualquer coisa em seu script.

Criando Variáveis de Sessão

Bom, já falamos demais e o jeito mais fácil de você entender como as seções funcionam e como usá-las é vendo
exemplos práticos. Para iniciar uma seção, usamos a função session_start(). Você precisa executar essa
função seja para escrever em uma variável de sessão ou então para ler alguma variável já escrita e ela precisa
ser chamada antes de qualquer saída no navegador. Para escrever ou acessar dados, usamos a variável
superglobal $_SESSION.

21
bool session_start ( void )

Exemplo 1.23. escrevendo_session.php

<?php
// Primeiramente precisamos iniciar a session
session_start();
// Agora que a seção já foi iniciada, podemos escrever alguns
// dados na variável $_SESSION
$_SESSION['nome'] = 'João';
$_SESSION['idade'] = '27';
$_SESSION['time'] = 'Vasco';

// Caso os cookies funcionem, esse link poderá acessar


// os dados salvados no script atual
echo '<a href="lendo_session.php">Próxima página!</a> <br />';

// Se eles não funcionarem, o link abaixo passa a seção pela


// URL, tornando os dados acessíveis no próximo script
echo '<a href="lendo_session.php?' . SID . '">Próxima página!</a>';
?>

Exemplo 1.24. lendo_session.php

<?php
// De novo, a primeira coisa a fazer é iniciar uma seção
session_start();
// Agora a variável $_SESSION está acessível nesse script
echo 'Olá, meu nome é ' . $_SESSION['nome'] .
', eu tenho ' . $_SESSION['idade'] .
' anos e torço para o ' . $_SESSION['time'];
?>

A constante SID contém o ID da sessão atual e é ela que usamos para propagar o valor da Session ID atual para
o próximo script usando query-string. Esse tipo de abordagem evita que um browser que não aceita cookies seja
"barrado" de usar as seções de seu site; porém, esse método torna muito difícil a vida do programador, pois a SID
precisa ser passada em todos os links de seu site e os endereços tornam-se gigantescos e pouco atraentes.

Tempo de existência

O tempo padrão de existência de uma seção é de 180 minutos, porém é possível mudar esse tempo através de
algumas funções que estão descritas abaixo:

Exemplo 1.25. Alterando o tempo de expiração

<?php
// Uma alteração necessária
session_cache_limiter('private');
// Aqui é setado o tempo de expiração. No caso, 30 minutos.
session_cache_expire(30);
session_start();
?>

string session_cache_limiter ( [string cache_limiter])


int session_cache_expire ( [int new_cache_expire])

Para que esse método funcione, você precisa rodar esses dois comandos ( session_cache_limiter() e
session_cache_expire()) em todas as páginas de seu site que usem seção e sempre antes da função
session_start().

22
Dica
Nota: Caso você tenha acesso ao arquivo php.ini em seu servidor, você pode alterar
as configurações de tempo de existência das seções por lá e evitar a necessidade de
ficar fazendo isso em vários scripts. Para isso, basta alterar os campos
session.cache_limiter e session.cache_expire para os valores desejados (como os do
exemplo acima).

Destruindo seções

Se por algum motivo você queira apagar sua seção antes do browser ser fechado ou então antes do tempo limite,
basta usar as funções session_unset() e session_destroy().

void session_unset ( void )


bool session_destroy ( void )

Exemplo 1.26. Destruindo seções

<?php
// Como sempre, é preciso iniciar a sessão
session_start();
// Apaga os valores da seção
session_unset();
// Destrói a seção
session_destroy();
?>

Cookies
Agora que você já sabe seções, vamos aprender como usar cookies. Eles são relativamente mais fáceis, pois
usam apenas uma função de controle, a setcookie. Através dela podemos criar, configurar e apagar cookies.

bool setcookie ( string name [, string value [, int expire [, string path [,
string do [, bool secure]]]]])
Parâmetro Descrição
name Nome do cookie
value Valor do cookie.
O tempo que um cookie leva para expirar. Essa dado é guardado na Unix Time Stamp, portanto em
expire
segundos a partir da Unix Epoch.
Indica o caminho (diretório) do servidor em que ficará disponível. Por exemplo: se você tem uma pasta
path em seu site chamada '/minhapasta' e quiser que apenas essa pasta tenha direito de acessar
determinado cookie, basta setar o parâmetro 'path' para '/minhapasta'.
Indica o domínio em que o cookie estará disponível. Funciona da mesma maneira como o 'path'. Para
domain disponibilizar todos os subdomínios de um domínio principal, use a sintaxe '.dominio.com'. Isso torna o
cookie 'visível' a todos os sub-domínios de 'dominio.com' ('subdominio.dominio.com')
Indica se o cookie só deve ser transmitido em uma conexão segura HTTPS. O padrão é 0, porém se
secure
setado a 1, o cookie não sera transmitido em uma conexão HTTP não segura.

Talvez pareça complicado esse monte de parâmetros, mas na verdade usar a função setcookie() é muito
simples.

Exemplo 1.27. Criando um cookie

<?php
// Criamos os cookies, passando nome do cookie, o valor do cookie
// e o tempo máximo de existência
setcookie('nome','João',time()+86400);
setcookie('idade','24',time()+86400);
setcookie('time','Vasco',time()+86400);

23
?>

No exemplo acima, criamos três cookies, cada um com um valor diferente e todos expirando em 24 horas (tempo
em segundos). Para mostrar o conteúdo de seus cookies, basta acessar a superglobal $_COOKIE indexada do
nome de seu cookie.

Exemplo 1.28. Exibindo o conteúdo de um cookie

<?php
echo 'Olá, meu nome é ' . $_COOKIE['nome'] .
', eu tenho ' . $_COOKIE['idade'] .
' anos e torço para o ' . $_COOKIE['time'];
?>

Perceba que não existe um cookie_start() como existe nas seções; podemos acessar o valor dos cookies a
qualquer momento dentro do script.

Dica
Lembre-se: Você pode acessar cookies de qualquer parte do seu script sem ter que
iniciar nada, porém para escrever em e criar novos cookies, é preciso faze-lo antes do
servidor enviar o HTTP Header, ou seja, antes que qualquer dado seja enviado ao
navegador.

Cookies com arrays

O exemplo acima cria três cookies diferentes para armazenar dados que são semelhantes. Para agrupar esses
dados em apenas uma variável, podemos usar arrays e centralizar as informações.

Exemplo 1.29. Cookies com arrays

<?php
// Criamos um cookie chamado 'dados', que agrega
// os valores antes fragmentados em três cookies
setcookie('dados[nome]','João',time()+86400);
setcookie('dados[idade]','24',time()+86400);
setcookie('dados[time]','Vasco',time()+86400);
?>

Exemplo 1.30. Exibindo arrays em cookies

<?php
// Agora fazemos o acesso aos dados com
// um array dentro de outr array
echo 'Olá, meu nome é ' . $_COOKIE['dados']['nome'] .
', eu tenho ' . $_COOKIE['dados']['idade'] .
' anos e torço para o ' . $_COOKIE['dados']['time'];
?>

Apagando Cookies

Para apagar cookies, por incrível que pareça, usamos a função setcookie() também. O que faremos é setar o
tempo de expiração para um valor absolutamente negativo ao atribuído em sua criação. Considere que criamos o
cookie dados exemplificado acima. Para apagá-lo, teríamos que fazer o seguinte:

Exemplo 1.31. Apagando Cookies

<?php
// Valores negativos para apagar os cookies.

24
setcookie('dados[nome]','João',time()-86400);
setcookie('dados[idade]','24',time()-86400);
setcookie('dados[time]','Vasco',time()-86400);
?>

Notas finais
Para terminar esse capítulo, lembre se que:

• O browser de um usuário visitante de seu site pode não aceitar cookies.


• A página atual precisa ser recarregada para poder ler os dados de um cookie que acabou de ser escrito.

Funções de data e hora


Resumo

O PHP nos dá uma variedade muito boa de funções para trabalharmos com datas e horas; digamos que você
queira mostrar em seu site o horário atual. Muito simples usando a função getdate().

getdate()
array getdate ( [int timestamp])

Essa função retorna um array associativo contendo as informações da data atual (isso se nenhuma timestamp for
passada como parâmetro). Como resultado, portanto, teremos um array com informações do dia do mês, do
segundo atual, do dia da semana, etc. Mais ou menos assim:

Array
(
[seconds] => 44
[minutes] => 24
[hours] => 11
[mday] => 26
[wday] => 2
[mon] => 10
[year] => 2004
[yday] => 299
[weekday] => Tuesday
[month] => October
[0] => 1098800684
)

Perceba que o dia da semana e o mês estão em inglês; faremos um pouco mais adiante no capítulo uma função
para traduzir essas informações. Antes disso, vejamos o código que mostrou as informações acima:

Exemplo 1.32. getdate()

<?php
$agora = getdate();
// formatação da saída
echo "<pre>";
print_r($agora);
echo "</pre>";
?>

Sobre as chaves do array, temos:

25
Chave Descrição
"seconds" Representação numérica dos segundos
"minutes" Representação numérica dos minutos
"hours" Representação numérica das horas
"mday" Representação numérica do dia do mês
"wday" Representação numérica do dia da semana
"mon" Representação numérica do mês
"year" Representação numérica do ano, com 4 dígitos
"yday" Representação numérica do dia do ano
"weekday" Representação textual do dia da semana
"month" Representação textual do mês
"0" Representação numérica do Unix Time Stamp (Unix Epoch)

Com as informações do array $agora, podemos exibir os dados da hora atual para o usuário muito facilmente.

Hoje é dia 26, do mês 10 de 2004. Agora são 11:24:44

Esse exemplo foi criado a partir do código:

Exemplo 1.33. Exibindo dados do getdate()

<?php
echo 'Hoje é dia ' . $agora['mday'] .
', do mês ' . $agora['mon'] .
' de ' . $agora['year'] .
'. Agora são ' . $agora['hours'] .
':' . $agora['minutes'] .
':' . $agora['seconds'];
?>

Apesar de ser simples, exibir dados de data e hora dessa maneira é bem chato e cansativo, afinal, concatenação
de strings e indexação de arrays é uma tarefa muito maçante. Alegre-se, pois o PHP oferece funções de data e
hora que fazem todo esse trabalho de formatação para a gente, usando uma sintaxe simples.

Tudo fica mais simples com date()


string date ( string format [, int timestamp])

Para evitar o uso da sintaxe comprida que vimos acima com o uso de getdate(), usaremos a função date(),
que formata automaticamente uma determinada data de acordo com o formato especificado. A função date()
recebe uma string com o formato desejado e retorna uma string com a data já formatada. Algo assim:

Exemplo 1.34. date()

<?php
echo date("d/m/y G:i:s")
?>

A saída é algo como:

26/10/04 11:24:44

As letras que usamos para especificar o formato da string de saída seguem um padrão; sempre que o
interpretador do PHP encontra uma das letras especificadas nesse padrão, ele as transforma em data/hora.
Abaixo segue uma versão simplificada dos formatos utilizados; a versão completa pode ser vista no manual do
PHP.

Format Descrição Exemplo de retorno


D Dia do mês, 2 dígitos (com zero inicial) 01 até 31

26
Format Descrição Exemplo de retorno
J Dia do mês, sem zero inicial 1 até 31
W Dia da semana, numérico 0(sun) até 6(sat)
M Mês numérico, 2 dígitos (com zero inicial) 01 até 12
N Mês numérico, sem zero inicial 1 até 12
Y Ano, 4 dígitos 1984, 1995, 2004
Y Ano, 2 dígitos 84, 95, 04
H Hora no formato de 24 horas, com zero inicial 00 até 23
G Hora no formato de 24 horas, sem zero inicial 0 até 23
G Hora no formato de 12 horas, sem zero inicial 1 até 12
H Hora no formato de 12 horas, com zero inicial 01 até 12
I Minutos, 2 dígitos (com zero inicial) 01 até 59
S Segundo, 2 dígitos (com zero inicial) 01 até 59
l ("L" minúsculo) Representação textual do dia da semana Sunday até Saturday
F Representação textual do mês Junuary até December

Agora, criar algo do mesmo jeito que fizemos com a função getdate() torna-se uma tarefa um pouco mais
simples e menor.

Exemplo 1.35. Formatando datas com date()

<?php
echo date("\H\o\j\e \é \d\i\a j, \d\o \m\ê\s n \d\e Y. \A\g\o\\r\a \s\ã\o
G:i:s");
?>

Esse monte de barras invertidas que você pode observar servem para dizer para o interpretador do PHP que ele
não deve ler essas letras como letras de formatação de data. Note que a letra \\r possui 2 barras invertidas; isso
acontece pelo fato dela funcionar como quebra de linha, assim como o caracter \n. A segunda barra diz para o
PHP que a barra não deve ser interpretada... um pouco estranho, mas é exatamente isso que acontece.

Criando datas com mktime()


int mktime ( [int hora [, int minuto [, int segundo [, int mês [, int dia [, int
ano [, int is_dst]]]]]]])

A função mktime() retorna o timestamp de qualquer data especificada em sua sintaxe; com essa timestamp,
podemos usar a função date() para formatá-la em algo textual.

Exemplo 1.36. Exemplos de date() + mktime()

<?php
echo date("d/m/Y", mktime(0, 0, 0, 3, 9, 1986)); // Retorna 09/03/1986
echo date("d/m/Y", mktime(0, 0, 0, 10, 21, 2010)); // Retorna 21/10/2010
// Quando uma data especificada está fora dos limites (como por exemplo
// dia 30 de fevereiro), a função mktime() trata de transformar essa data
// em uma data existente, somando "o que sobra". Assim:
echo date("d/m/Y", mktime(0, 0, 0, 2, 30, 2003)); // Retorna 02/03/2003
echo date("d/m/Y", mktime(0, 0, 0, 24, 1, 2004)); // Retorna 01/12/2005
?>

Traduzindo datas do inglês


Existem inúmeras maneiras de fazer uma função que traduza do inglês para o portguês datas existentes no PHP.
Na verdade, usando as funções setlocale() e strftime() do PHP, podemos trabalhar com datas em
português (e várias outras línguas). Porém, o uso dessa função é um tanto quanto chato e o trabalho fica bem
mais simples com uma função que traduz os dados da função date().

Exemplo 1.37. Funções de data em português

27
<?php
// dia() retorna o dia da semana atual em português. Se um timestamp
// é passado (mktime(), por exemplo), dia() retorna o dia da semana do timestamp
function dia ($timestamp = NULL) {
// Cria um array com os dias da semana
$dia = array("Domingo", "Segunda-feira", "Terça-feira",
"Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado");
// Verifica se $timestamp existe (se foi passado por parâmetro)
$timestamp = is_null($timestamp) ? time() : $timestamp;
return $dia[date("w", $timestamp)];
}
// mes() retorna o mês atual em português caso nenhum timestamp
// é passado. Se um timestamp for passado, retorna os dados dessa timestamp
function mes ($timestamp = NULL) {
// Cria um array com os meses do ano
$mes = array("Janeiro", "Fevereiro", "Março", "Abril",
"Maio", "Junho", "Julho", "Agosto", "Setembro",
"Outubro", "Novembro", "Dezembro");
$timestamp = is_null($timestamp) ? time() : $timestamp;
return $mes[date("n", $timestamp)-1];
}
?>

As duas funções funcionam sobre a mesma idéia; temos um array com as palavras traduzidas e acessando esse
array indexado do dia da semana numérico (ou o mês do ano), obtemos o dia pedido. Para o índice do array,
usamos a função date() que nos devolve o dia da semana numérico e o mês do ano.

As funções podem ser chamadas tanto passando um parâmetro como sem passar nada; quando nada é passado,
o valor devolvido é o equivalente a data atual. A linha que faz esse teste é a seguinte:

$timestamp = is_null($timestamp) ? time() : $timestamp;

Ela tem uma forma estranha, mas esse é o melhor jeito de fazer esse teste. is_null($timestamp) retorna se
$timestamp é nulo (que é seu valor default). Os operadores ? e : testam se is_null($timestamp) é
verdadeiro; se o resultado é verdadeiro, $timestamp recebe time(). Se o resultado é falso, $timestamp
recebe $timestamp, ou seja, continua com o valor já existente. Essa única linha de código é equivalente aos
seguinte comandos:

<?php
if (is_null($timestamp))
$timestamp = time();
else
$timestamp = $timestamp;
?>

Perceba que o else é totalmente descartável e está aí apenas para ilustrar exatamente o que acontece com a
interrogação e os dois pontos. No tipo de operando usado nas funções dia() e mes(), os dois pontos são
necessários, apesar de, na prática, não servirem para nada (afinal, $timestamp = $timestamp é praticamente
o mesmo que 1 = 1).

Dica
Nota: A função time() retorna o timestamp atual.

Agora que entendemos como as funções funcionam, vejamos exemplos de como usá-las:

Exemplo 1.38. Usando as funções dia() e mes()

<?php
echo dia() . ", " . date("d") . " de " . mes() . " de " . date("Y");

28
echo "<br />";
$data = mktime(0,0,0,4,7,1980); // Evita repetição do mktime()
echo "Dia " . date("d",$data) . " de " . mes($data) .
" de " . date("Y",$data) . " foi uma " . dia($data) . ".";
?>

Os exemplos acima retornam os seguintes valores:

Terça-feira, 26 de Outubro de 2004 Dia 07 de Abril de 1980 foi uma Segunda-


feira.

Mandando E-mails
Resumo

Com certeza você já se deparou pela internet com sites que possuem formulários de envio de mensagens para os
administradores (ou talvez para um serviço de suporte). É muito interessante fazer uso desse tipo de formulário,
pois a informação do endereço de e-mail para onde a mensagem será entregada é totalmente secreta, impedindo
assim o ataque de spammers e outros usuários maliciosos. Além disso, esse tipo de abordagem também permite
uma orientação ao usuário à determindas informações necessárias. Suponha que você precise saber a cidade em
que o usuário mora, por algum motivo; basta você colocar um campo no formulário que peça essa informação ao
usuário.

A função mail()
Para enviarmos e-mails através do PHP, e criarmos um desses formulários de contatos, usaremos a função
mail(). O que essa função faz é enviar um e-mail para o endereço indicado e retornar true em caso de
sucesso no envio ou false no caso de falha.

bool mail ( string to, string subject, string message [, string additional_s [,
string additional_parameters]])

Perceba que a sintaxe da função é simples e seu uso também. Primeiro construíremos um formulário em HTML
para depois construir o script em PHP, que fará o envio da mensagem.

Exemplo 1.39. Formulário para envio de mensagem

<form method="post" action="<?php $_SERVER['PHP_SELF']; ?>">


<p>Seu nome<br /> <input type="text" name="nome" /></p>
<p>Seu e-mail <br /> <input type="text" name="email" /></p>
<p>Assunto do email <br /> <input type="text" name="assunto" /></p>
<p>Sua mensagem <br /> <textarea name="mensagem" cols="20"
rows="7"></textarea></p>
<p>
<input type="hidden" name="verifica_envio" value="1" />
<input type="submit" value="Enviar" />
<input type="reset" value="Recomeçar" />
</p>
</form>

Até agora, nenhuma novidade, apenas um formulário simples que você já aprendeu a fazer antes nesse curso.
Pois bem, agora falta só fazer o script em PHP que também não possui nada de muito diferente do que já vimos
até aqui.

Exemplo 1.40. O script de envio de mensagem

<?php
// Primeiramente testamos se todos os campos foram preenchidos
if ((!empty($_POST['nome'])) and (!empty($_POST['email']))
and (!empty($_POST['assunto'])) and (!empty($_POST['mensagem']))) {

29
// Atribuímos variáveis com os valores preenchidos no form
$nome = $_POST['nome'];
$email = $_POST['email'];
$assunto = $_POST['assunto'];
$mensagem = 'Nome: ' . $nome . "\n";
$mensagem .= 'Mensagem: ' . $_POST['mensagem'];
// Criamos uma variável com o e-mail que receberá as mensagens
$destinatario = 'email@dominio.com.br;';

// Para que o endereço do remetente seja enviado, precisaremos


// alterar uma configuração no arquivo php.ini em tempo de
// execução através da função ini_set()
ini_set("sendmail_from",$email);

// Opcionalmente, configuramos um servidor de SMTP, que


// enviará nossas mensagens (veja abaixo)
ini_set("SMTP",'smtp.dominio.com.br');

// Agora enviamos o e-mail, tratando eventuais erros


if (mail($destinatario, $assunto, $mensagem)) {
echo 'Email enviado com sucesso!';
}
else {
echo 'Falha no envio do e-mail';
}
}
?>

Juntando o formulário e o script num mesmo arquivo, temos o arquivo definitivo

Exemplo 1.41. contato.php

<?php
// Função envia_email recebe como parâmetro o endereço de email
// que receberá as mensagens do formulário
function envia_email($destinatario) {
// Primeiramente testamos se todos os campos foram preenchidos
if ((!empty($_POST['nome'])) and (!empty($_POST['email']))
and (!empty($_POST['assunto'])) and (!empty($_POST['mensagem']))) {
// Atribuímos variáveis com os valores preenchidos no form
$nome = $_POST['nome'];
$email = $_POST['email'];
$assunto = $_POST['assunto'];
$mensagem = 'Nome: ' . $nome . "\n";
$mensagem .= 'Mensagem: ' . $_POST['mensagem'];
// Para que o endereço do remetente seja enviado, precisaremos
// alterar uma configuração no arquivo php.ini em tempo de
// execução através da função ini_set()
ini_set("sendmail_from",$email);

// Opcionalmente, configuramos um servidor de SMTP, que


// enviará nossas mensagens (veja abaixo)
ini_set("SMTP",'smtp.dominio.com.br');

// Agora enviamos o e-mail, tratando eventuais erros


if (mail($destinatario, $assunto, $mensagem)) {
echo 'Email enviado com sucesso!';
}
else {
echo 'Falha no envio do e-mail';
}
}

30
}
// Testamos se o form foi submetido
if (array_key_exists('verifica_envio',$_POST)) {
envia_email('email@dominio.com.br');
}
else {
?>

<form method="post" action="<?php $_SERVER['php_self']; ?>">


<p>Seu nome<br /> <input type="text" name="nome" /></p>
<p>Seu e-mail <br /> <input type="text" name="email" /></p>
<p>Assunto do email <br /> <input type="text" name="assunto" /></p>
<p>Sua mensagem <br /> <textarea name="mensagem" cols="20"
rows="7"></textarea></p>
<p>
<input type="hidden" name="verifica_envio" value="1" />
<input type="submit" value="Enviar" />
<input type="reset" value="Recomeçar" />
</p>
</form>
<?php
} // Fim do else (!array_key_exists)
?>

Dica
Sobre o servidor de SMTP: O servidor de SMTP não precisa necessariamente ser
setado, tudo depende do servidor em que seu script está rodando. Normalmente, em
servidores Linux não é necessário fazer essa configuração, pois ele roda nativamente
um servidor de SMTP. Caso esse não seja o caso, você pode utilizar o servidor SMTP
de seu provedor de acesso a internet para habilitar o envio de e-mails pelo PHP. De
qualquer forma, se possível, certifique-se da disponibilidade de tal servidor com seu
administrador de rede.

O script acima, contato.php, é simples e auto-explicativo. Talvez a coisa mais estranha que temos, é o else
do teste array_key_exists. Note que o código PHP é fechado ( ?> ) logo após o início do else; um código
HTML é inserido e o PHP é aberto de novo, exclusivamente para fechar o else. É importante notar que as
estruturas de controle (if, else, for, etc) continuam válidas mesmo quando o PHP é fechado e só terminam
quando são fechadas ( } ). Podemos usar esse recurso para evitar ter que passar todo o HTML para strings em
PHP, evitando o trabalho de tomar cuidado com aspas e apóstrofes.

E-mails em HTML
O PHP também possibilita o envio de e-mails em HTML. O processo é muito simples e praticamente idêntico ao
descrito acima; precisaremos colocar um cabeçalho indicando um Contenty-type e alterar a variável mensagem,
com o código em HTML. Veja:

Exemplo 1.42. Mensagem em HTML

<?php
function envia_email($destinatario) {
if ((!empty($_POST['nome'])) and (!empty($_POST['email']))
and (!empty($_POST['assunto'])) and (!empty($_POST['mensagem']))) {
$nome = $_POST['nome'];
$email = $_POST['email'];
$assunto = $_POST['assunto'];

// A variável $mensagem agora contém o código em HTML,


// além da mensagem em si
$mensagem = '<html><body>';
$mensagem .= '<h1>Formulário de cadastro em HTML</h1>';

31
$mensagem .= '<h2>Enviado por: ' . $nome . '</h2>';
$mensagem .= $_POST['mensagem'];
$mensagem .= '</body></html>';

ini_set("sendmail_from",$email);
ini_set("SMTP",'smtp.dominio.com.br');

// Agora setamos o cabeçalho do e-mail,


// dizendo que o conteúdo é em HTML
$header = "Content-type: text/html; charset=iso-8859-1\r\n ";

// A última alteração fica na função mail(),


// que precisa receber a variável $header, para
// passá-la como o cabeçalho do e-mail
if (mail($destinatario, $assunto, $mensagem,$header)) {
echo 'Email enviado com sucesso!';
}
else {
echo 'Falha no envio do e-mail';
}
}

?>

Manipulando Arquivos e Diretórios


Resumo

Além de tudo isso que já vimos, o PHP também permite a manipulação de arquivos contidos no servidor;
podemos criar, alterar, apagar, abrir e fazer (praticamente) qualquer outra coisa que podemos fazer em um
sistema de arquivos.

Abrindo arquivos
Abrir arquivos no PHP torna-se uma tarefa muito simples usando a função file().

array file ( string filename [, int use_include_path [, resource context]])

O que essa função faz é ler o arquivo especificado e colocá-lo dentro de um array. Cada linha é considerada um
índice novo, portanto um arquivo com 30 linhas virará um array com índice máximo de 29, caso seja usada a
função file(). Note que podemos abrir não só arquivos do servidor atual, mas também endereços da internet.

Exemplo 1.43. teste.txt

Batatinha quando nasce


se esparrama pelo chão.
Menininha quando dorme
põe a mão no coração

Exemplo 1.44. arquivo.php

<?php
$arquivo = file('teste.txt');
echo '<pre>';
print_r($arquivo);
echo '</pre>';
?>

32
O exemplo acima é muito simples; o que ele faz é criar um array $arquivo com o conteúdo do arquivo
teste.txt. As outras três linhas servem apenas para mostrar o conteúdo desse array de uma forma legível. A
saída gerada é:

Array
(
[0] => Batatinha quando nasce
[1] => se esparrama pelo chão.
[2] => Menininha quando dorme
[3] => põe a mão no coração
)

Escrevendo em arquivos
Obviamente que além de ler um arquivo, você também tem a possibilidade de escrever para esse arquivo (ou
qualquer outro). Para fazer isso, você precisará criar um handle de arquivo através da função fopen(). Na
prática, um handle é uma ligação (conexão) entre uma variável e o arquivo especificado.

resource fopen ( string filename, string mode [, bool use_include_path [,


resource zcontext]])

Uma das necessidades de se criar um handle é especificar o modo de abertura desse arquivo. Existem,
simplificadamente três modos de se abrir um arquivo:

• Leitura: Permite apenas a leitura do arquivo.


• Escrita: Permite a gravação no arquivo.
• Adição: Permite a gravação, mantendo o conteúdo já existente desse arquivo.

Abaixo segue uma tabela com os modos suportados pelo PHP:

Modo Descrição
r Abre para leitura apenas. Ponteiro do arquivo no começo do arquivo.
r+ Abre para leitura e escrita. Coloca o ponteiro do arquivo no começo do arquivo.
Abre para escrita apenas. Coloca o ponteiro do arquivo no começo do arquivo e 'zera' o arquivo (apaga o
w
conteúdo existente). Caso o arquivo especificado não exista, tenta criá-lo.
Abre para escrita e leitura. Coloca o ponteiro do arquivo no começo do arquivo e 'zera' o arquivo. Caso o
w+
arquivo não exista, tenta criá-lo.
Abre para escrita apenas. Coloca o ponteiro do arquivo no final do arquivo. Tenta criá-lo, se esse for
a
inexistente.
Abre para escrita e leitura. Coloca o ponteiro do arquivo no final do arquivo. Tenta criá-lo, se esse for
a+
inexistente.
Abre para escrita apenas. Coloca o ponteiro no começo do arquivo. Se o arquivo já existe, ele não é aberto
x e a função retorna false. Se o arquivo não existe, tanta criá-lo. Essa opção é suportada apenas pelo PHP
4.3.2 ou superior e apenas para arquivo locais.
Abre para escrita e leitura. Coloca o ponteiro do arquivo no começo do arquivo. Se o arquivo já existe, ele
x+ não é aberto e a função retorna false. Se o arquivo não existe, tenta criá-lo. Essa opção é suportada
apenas pelo PHP 4.3.2 ou superior e apenas para arquivo locais.

Bom, agora que você sabe um pouco sobre a função fopen(), veremos como fazer a parte da escrita do
arquivo, propriamente dita, usando a função fwrite(), que escreve uma string dentro de um arquivo.

int fwrite ( resource handle, string string [, int length])

Essa função retorna o número de bytes escritos ou então false em caso de erro.

Exemplo 1.45. Re-escrevendo a batatinha

<?php
$arquivo = 'batatinha.txt';

33
$novoconteudo = 'Esse arquivo ficou bem mais limpo!';
// Função is_writable testa se um arquivo pode ser escrito.
// Nesse exemplo, isso é interessante para termos certeza
// de que podemos mexer com esse arquivo.
if (is_writable($arquivo)) {

// Verifica erro na abertura do arquivo


if(!$handle = fopen($arquivo,'w')) {
echo "Erro ao abrir o arquivo $arquivo";
}
// Caso o arquivo foi aberto com sucesso, tenta escrever.
// Em caso de erro, retorna mensagem ao usuário.
elseif(fwrite($novoconteudo,$arquivo) == false) {
echo "Erro ao escrever no arquivo $arquivo";
}
else {
echo "Arquivo escrito com sucesso!";
}
// Não se esqueça de fechar o arquivo com a função fclose()
fclose($arquivo);
}
// else referente ao teste is_writable($arquivo);
else {
echo "O arquivo não pode ser alterado";
}
?>

Apesar de extenso e com várias funções novas, o exemplo acima é bem simples e fácil de entender. O que ele
faz é abrir o arquivo batatinha.txt, apagar tudo o que existe nele e escrever o conteúdo de
$novoconteudo. Para fazer isso, primeiramente testamos se o arquivo pode ser escrito (caso você não seja o
dono do arquivo, é bem provável que você não possa alterá-lo). Depois, testamos se conseguimos abrir o
arquivo. Só depois é que escrevos dentro desse arquivo; em caso de erro nos passos acima, tratamos esse erro.
Usamos duas funções novas no exemplo acima: is_writable() e fclose(). Abaixo segue a definição da
sintaxe das duas, porém elas são muito simples; a primeira testa se um arquivo pode ser alterado e a segunda
fecha o arquivo. Nada mais que isso; simples assim.

bool is_writable ( string filename)


bool fclose ( resource handle)

Trabalhando com diretórios


Além de trabalhar com arquivos, você também pode trabalhar com diretórios no PHP. É possível fazer as mesmas
coisas que fizemos com arquivo.

Criar diretórios é uma tarefa muito simples com a função mkdir(). Basta especificar o nome do diretório e
opcionalmente, as permissões desejadas. A permissão padrão é a 0777, que permite tudo a todos; dependendo
do caso, pode ser bem perigoso criar diretórios com essa permissão e pode ser interessante restringir um pouco
o acesso. Você pode ler mais sobre permissões no capítulo chmod() do manual do PHP. A função retorna
false se algum erro ocorrer e true se a operação for concluída com sucesso.

bool mkdir ( string pathname [, int mode [, bool recursive [, resource


context]]])

Apagar diretórios é ainda mais fácil, pois você não tem que se preocupar em gerenciar permissões, basta
especificar o nome do diretório através da função rmdir(). A função retorna false se algum erro ocorrer e
true se a operação for concluída com sucesso.

bool rmdir ( string dirname [, resource context])

Listar o conteúdo de diretórios é uma tarefa muito simples caso você esteja rodando PHP 5. Essa versão já vem
com uma função chamada scandir(), que retorna um array com a listagem do diretório especificado.

34
array scandir ( string directory [, int sorting_order [, resource context]])

Exemplo 1.46. scandir()

<?php
$diretorio = '/meu/diretorio';
// Por padrão, a função scandir() retorna um array com o nome dos
// arquivos em ordem alfabética crescente
$arquivos = scandir($diretorio);
// Colocando o número 1 na opção sorting_order da função scandir(),
// o array é criado com os arquivos em ordem alfabética descresente
$arquivos_dec = scandir($diretorio,1);

echo '<pre>';
print_r($arquivos);
print_r($arquivos_dec);
echo '<pre>';
?>

Caso o seu servidor ainda não suporte a versão 5 do PHP, o trabalho será um pouco mais para listar o conteúdo
de um diretório. Algumas funções diferentes terão que ser usadas, e elas estão explicadas nos comentários do
código abaixo:

Exemplo 1.47. Listando diretórios no PHP 4

<?php
$diretorio = '/meu/diretorio';
// Cria um handle de diretórios, da mesma forma
// como fizemos com a função fopen()
$dirhandle = opendir($diretorio);
// A função readdir() lê o próximo arquivo do diretório especificado.
// Enquanto existirem arquivos, o array $arquivos é incrementado
// com o nome do arquivo atual.
while ($nome_do_arquivo = readdir($dirhandle)) {
$arquivos[] = $nome_do_arquivo;
}

// Ordena o vetor de arquivos. Para ordená-lo ao contrário,


// basta usar a função rsort().
sort($arquivos);

echo '<pre>';
print_r($arquivo);
echo '</pre>';

?>
resource opendir ( string path)
string readdir ( resource dir_handle)
bool sort ( array & array [, int sort_flags])

Apesar de ser um pouco mais complicado, listar o conteúdo de diretórios no PHP 4 não é nenhum bicho de sete
cabeças. Os exemplos acima fazem nada mais que criar um array contendo os arquivos do diretório determinado,
porém nada o impede manipular esses dados de forma diferente, como no exemplo abaixo:

Exemplo 1.48. Links para os arquivos do diretório

<?php
$diretorio = '/meu/diretorio';
$dirhandle = opendir($diretorio);
while ($nome_do_arquivo = readdir($dirhandle)) {
$arquivos[] = $nome_do_arquivo;
}

35
sort($arquivos);
// Percorre o array de arquivos e cria links para cada um dos índices
foreach($arquivos as $arquivoatual) {
echo "<a href='" . $diretorio . $arquivoatual . "'>" . $arquivoatual .
"</a><br />";
}
?>

O que o código acima faz, como você provavelmente percebeu, é criar links para os arquivos do diretório
especificado. Nada muito útil, porém serve para você ter uma idéia do que é possível.

Capítulo 4. Introdução ao MySQL


Resumo

O MySQL é um gerenciador de banco de dados que, assim como o PHP, é gratuito e de código aberto. Ele utiliza
a linguagem de programação SQL (Structured Query Language), que é um padrão e a linguagem mais usada em
bancos de dados. Existem vários bancos de dados que suportam e seguem o padrão SQL, porém cada um deles
possui extensões proprietárias que possibilitam novas funcionalidades ao padrão. Como exemplo, podemos citar
o PostgreSQL, que também tem código aberto e é gratuito, além de funcionar igualmente bem com o PHP.
Também existe o Microsoft SQL Server, que não é gratuito, não possui código aberto e é bastante usado em
corporações.

Na internet atual, praticamente todos os servidores de hospedagem suportam MySQL, exatamente pelo fato dele
ser gratuito como o PHP e os dois trabalharem muito bem em conjunto.

Esse curso não tem como objetivo ensinar MySQL e nem conceitos avançados de banco de dados. O objetivo é
ensinar PHP e como usá-lo junto do MySQL na construção de sites dinâmicos. Portanto, caso você não entenda
nada que diga respeito ao banco de dados, faça alguma pesquisa sobre os conceitos básicos desse assunto; não
é nada complicado. Apesar disso, esse capítulo explica alguns conceitos muito básicos da linguagem SQL e nada
muito além disso. Nos capítulos seguintes, exemplos mais detalhados virão sobre as funções do MySQL.

Breve resumo das funções SQL


Abaixo segue um breve resumo das funções que manipulam tabelas em SQL.

Exemplo 1.1. Criando tabelas

CREATE TABLE nome_da_tabela (


nome_do_campo tipo_do_campo,
outro_campo tipo_do_campo,
...
)

Tipos de campo
Existem vários tipos de campos nas tabelas SQL; os tipos de campos funcionam da mesma maneira como
funcionam os tipos de variáveis em linguagens de programação fortemente tipada (que não é o caso do PHP).
Abaixo segue uma lista com os tipos mais usados:

Tipo Descrição
tinyint Números inteiros de -128 a 127 (signed) ou de 0 a 255 (unsigned).
Números inteiros de -2147483648 a 2147483647 (signed) ou então de 0 a 4294967295
integer / int
(unsigned).
Números inteiros de -9223372036854775808 a 9223372036854775807 (signed) ou de 0 a
bigint
18446744073709551615 (unsigned).
Bool / boolean / bit Indica falso (zero) ou verdadeiro (qualquer número diferente de zero).
Float(m,d) Números reais de -3.402823466E+38 a -1.175494351E-38 e de 1.175494351E-38 a
3.402823466E+38. m representa o tamanho do número de d representa o número de

36
Tipo Descrição
decimais.
Uma string de tamanho fixo. m representa o tamanho da coluna. Caso o dado guardado
Char(m) nessa coluna seja menor que m, a diferença é preenchida com espaços vazios. Caso m não
seja declarado, o tamanho considerado é 1. O tamanho vai de 0 a 255.
Funciona da mesma maneira que o char, porém o tamanho da string não é fixo (não existe o
varchar(m)
preenchimento com espaços).
text / blob Strings com máximo de 65,535 caracteres.
tinytext / tinyblob Strings com máximo de 255 caracteres.
mediumtext /
Strings com máximo de 16,777,215 caracteres.
mediumblob
longtext / longblob Strings com máximo de 4,294,967,295 caracteres ou 4GB.
enum Guarda uma string que precisa ser igual a algum item da lista valor1, valor2,.... A lista pode
('valor1','valor2',...) ter no máximo 65,535 itens.
Datas com valor entre '1000-01-01' e '9999-12-31'. Perceba que o formato suporta é 'AAAA-
Date
MM-DD'.
Time Horas com valor entre '-838:59:59' e '838:59:59'. O formato é 'HH:MM:SS'.
Combinação entre date e time. O formato é 'AAAA-MM-DD HH:MM:SS'. Suporta valores
datetime
entre '1000-01-01 00:00:00' e '9999-12-31 23:59:59'.
Year Guarda somente o ano de uma data, em quatro dígitos.

Exemplo 1.2. Apagando tabelas

DROP TABLE nome_da_tabela

Exemplo 1.3. Inserindo dados na tabela ( Primeiro Modo )

INSERT INTO
nome_da_tabela
SET
nome_da_coluna='dado_a_ser_inserido',
outra_coluna='outro_dado', ...

Exemplo 1.4. Inserindo dados na tabela ( Segundo Modo )

INSERT INTO
nome_da_tabela (coluna1, coluna2,...)
VALUES
(valor_da_coluna1, valor_da_coluna_2,...)

Exemplo 1.5. Alterando dados da tabela

UPDATE
nome_da_tabela
SET
coluna1='valor_da_coluna1',
coluna2='valor_da_coluna2', ...
[WHERE condição_para_alteração]
[ORDER BY coluna]
[LIMIT número_máximo]

Exemplo 1.6. Apagando dados da tabela

DELETE FROM
nome_da_tabela
[WHERE condição_para_apagamento]
[ORDER BY coluna]
[LIMIT número_máximo]

Exemplo 1.7. Selecionando dados da tabela

37
SELECT colunas_a_selecionar
FROM
nome_da_tabela
[WHERE condição_para_seleção]
[ORDER BY coluna]
[LIMIT número_máximo]

Facilitando a sua vida


Sabendo ou não sabendo MySQL, existem ferramentas que ajudam bastante a construção e manutenção de
bancos de dados; uma delas (a mais usada na internet) é o phpMyAdmin. Com ele você pode criar tabelas,
apagar tabelas, inserir dados e fazer muitos outras coisas sem saber muito de SQL, apenas usando formulários.
Caso você use um servidor pago, é muito provável que ele já tenha o phpMyAdmin instalado; em dúvida, contate
o administrador de rede.

Alterando dados do banco de dados


Conectando-se ao servidor de banco de dados
Antes de poder fazer qualquer coisa relacionada ao bando de dados, precisamos conecetar o script atual ao
servidor MySQL e selecionar a tabela que desejamos usar. Faremos isso através das funções
mysql_connect() e mysql_select_db().

resource mysql_connect ( [string server [, string username [, string password [,


bool new_link [, int client_flags]]]]])
bool mysql_select_db ( string database_name [, resource link_identifier])

Exemplo 1.8. Conectando-se ao servidor de banco de dados

<?php
$servidor = 'localhost';
$usuario = 'jose';
$senha = 'banana';
$db = 'minhaDB';

// Criamos uma variável $conexao que contém o resource do


// mysql_connect. Teste para tratar erros.
if ($conexao = mysql_connect($servidor,$usuario,$senha)) {

// Agora selecionamos a base de dados


if (!mysql_select_db($conexao) {
echo 'Não foi possível selecionar a base de dados';
}
}
else {
echo 'Não foi possível conectar-se ao servidor de bando de dados';
}
?>

Note que no exemplo acima o servidor MySQL está no mesmo computador que o servidor web (localhost),
porém isso nem sempre acontece. Caso você esteja rodando um servidor em sua casa, esse com certeza é o
caminho, porém se você está usando algum outro servidor, contate o administrador para obter informações sobre
o endereço de seu servidor de banco de dados.

Inserindo dados na tabela


Agora que já nos conectamos ao servidor de banco de dados, resta saber como executar queries a partir do PHP.
A função mysql_query() faz isso e retorna false em caso de erro e um resource em caso de sucesso.

38
resource mysql_query ( string query [, resource link_identifier])

Para fazer os exemplos dessa capítulo, usaremos a seguinte tabela:

Exemplo 1.9. Tabela 'carro'

CREATE TABLE carro (


codigo integer auto_increment not null primary key,
nome varchar(20) not null,
marca varchar(20) not null,
cor varchar(10) not null,
ano year not null
)

Perceba que esse tabela usa algumas funções que ainda não foram mencionadas nos capítulos anteriores.

• not null : colunas not null não podem ser deixadas vazias, quando uma nova linha é inserida.
• auto_increment : quando uma coluna tem a propriedade auto_increment, ela funciona como um índice.
A cada inserção na tabela, o número dessa coluna é aumentado. As colunas auto_increment precisam
ser not null e precisam ser número inteiros (int, longint, mediumint ou tinyint). Por serem automáticos, os
dados dessa coluna não podem ser alterados.
• primary key : indica que a coluna é chave primária. Ela é única e precisa ser not null.

Exemplo 1.10. Executando a query de inserção

<?php

// Primeiramente criamos uma string contendo a


// query que executaremos no MySQL
$sql = "INSERT INTO carro
SET
nome='Golf GTI',
marca='Volswagen',
cor='Preto',
ano='2002'";

// Agora é só executá-la através da função mysql_query().


// Como sempre, é bom testar o comando
if (!$resultado = mysql_query($sql))
die (mysql_error());
?>

Dica
O exemplo acima leva em conta que os comandos de conexão com o banco de dados já
foram executados.

No exemplo acima, criamos um variável $sql e colocamos a query dentro dela (string); feito isso, a única coisa
que restava fazer, era executá-la e fizemos isso através da função mysql_query(). Para tratar um possível
erro, usamos as funções die() e mysql_error(). A primeira exibe uma mensagem e pára a execução do
script. Já a segunda retorna uma string contendo a mensagem de erro da última operação MySQL executada.

string mysql_error ( [resource link_identifier])

Note que tanto na função mysql_query() quanto na função mysql_error(), poderíamos ter passado como
parâmetro a variável que contém o resource de conexão com o MySQL, ou seja, a variável $conexao. Porém,
isso não foi necessário, pois quando esse parâmetro não é passado para essas funções, elas usam a última
conexão feita com sucesso dentro do script. Se por um acaso você esteja usando mais de uma conexão em seu
script, daí sim seria preciso indicar a variável de conexão.

39
Dica
Aspas e apóstrofes: não se esqueça de colocar apóstrofes quando for inserir algo em
uma tabela do banco de dados. Caso você esqueça, o MySQL não saberá que aquilo é
uma string e não um nome de tabela ou um nome de coluna; conseqüentemente, a
query não funcionará.

Alterando dados já existentes


Para alterar dados já existentes em uma tabela, usaremos a função UPDATE do MySQL porém o código em PHP
ficará idêntico ao código acima (afinal, a única coisa que realmente muda é a query). Portanto, temos:

Exemplo 1.11. Executando a query de alteração

<?php
$sql = "UPDATE carro
SET
cor='Verde',
ano='2004'
WHERE
nome='Golf GTI'
AND
cor='Preto'
AND
ano='2002'
LIMIT 1";

if (!$resultado = mysql_query($sql))
die (mysql_error());
?>

A query do exemplo acima altera na tabela carro os valores cor('Verde') e ano('2004') onde o nome do carro
for 'Golf GTI', a cor for 'Preto' e o ano for '2002'. O comando LIMIT 1 serve para, caso existam mais
de um Golf GTI preto e ano 2002 na tabela, apenas um deles seja alterado. Se todos os comando após o WHERE
fossem retirados, os campos cor e ano de todas as linhas da tabela receberiam os valores 'Verde' e '2004'.

Apagando uma linha


Através da função DELETE do SQL, podemos apagar linhas de nossa tabela.

Exemplo 1.12. Executando a query de alteração

<?php
$sql = "DELETE FROM carro
WHERE
nome='Golf GTI'
AND
cor='Verde'
AND
ano='2004'
LIMIT 1";

if (!$resultado = mysql_query($sql))
die (mysql_error());
?>

Essa query apaga a linha onde o carro for Golf GTI, a cor for verde e o ano for 2004. Novamente, o LIMIT 1
existe para apagar apenas uma das ocorrências da condição (caso existam mais que uma).

40
Exibindo Dados
Resumo

As queries de INSERT e UPDATE não solicitam nenhuma informação do banco de dados, elas apenas alteram a
tabela. Mas e quando quisermos pegar informações da tabela do MySQL?

Trazendo os dados
Como você já deve estar imaginando, para buscar informações do banco de dados, precisaremos escrever uma
query em SQL, que vai fazer todo o trabalho para a gente. Feita a query, precisaremos executá-la, através da
função mysql_query(), como vimos há pouco. Porém, agora não pararemos por aqui, pois essa função ainda
não nos retorna os dados, como queremos. Teremos de usar mais uma função nova, chamada
mysql_fetch_array.

array mysql_fetch_array ( resource result [, int result_type])

Dica
"fetch", do inglês, significa: "buscar, trazer, extrair".

Essa função recebe uma variável contendo um resultado de um query (mysql_query) e retorna um array
associativo e numérico contendo os dados recebidos do SQL. Ela faz isso uma linha por vez, por isso será
necessário usar um while para ter acesso a todas as linhas da tabela. Veja no exemplo abaixo (ainda usando a
tabela 'carro', do capítulo anterior).

Exemplo 1.13. Retornando e tratando dados

<?php
$servidor = 'localhost';
$usuario = 'jose';
$senha = 'banana';
$db = 'minhaDB';
// Primeiramente nos conectamos ao servidor
if ($conexao = mysql_connect($servidor,$usuario,$senha)) {
// E selecionamos uma base de dados
if (!mysql_select_db($conexao) {
echo 'Não foi possível selecionar a base de dados';
}
}
else {
echo 'Não foi possível conectar-se ao servidor de bando de dados';
}
// Criamos a query. O asterisco significa todos, portanto
// a query abaixo pega todas as colunas da tabela carro
$sql = "SELECT * FROM carro";
// Executamos a query
$resultado = mysql_query($sql);
// Agora precisaremos passar todas as informações retornadas
// pelo MySQL para um array.
while ($linha = mysql_fetch_array($resultado)) {
echo 'Código: ' . $linha['codigo'] . "<br />\n";
echo 'Carro: ' . $linha['nome'] . "<br />\n";
echo 'Marca: ' . $linha['marca'] . "<br />\n";
echo 'Cor: ' . $linha['cor'] . "<br />\n";
echo 'Ano: ' . $linha['ano'] . "<br />\n";
}
?>

41
A cada ciclo do while($linha = mysql_fetch_array($resultado)), a variável $linha recebe os
dados da linha atual do resultado da query; quando um ciclo termina, automaticamente o apontador da linha vai
para a próxima e $linha recebe as informações dessa linha. Quando não existir mais linhas para trazer, a
variável $linha não recebe mysql_fetch_array($resultado) e o while pára.

Como foi dito acima, a função mysql_fetch_array retorna uma array associativo e númerico, portanto
podemos acessar os valores de $linha através do nome das colunas ou então do número das colunas. Um
pouco confuso, mas fica mais fácil de entender pelo exemplo abaixo, que simula o resultado do script acima.

Array
(
[cod] => 1
[0] => 1
[nome] => Golf GTI
[1] => Golf GTI
[marca] => Volkswagen
[2] => Volkswagen
[cor] => Preto
[3] => Preto
[ano] => 2002
[4] => 2002
)

Perceba que usar $linha['nome'] é exatamente a mesma coisa que usar $linha[1]; apesar do resultado
ser o mesmo, o primeiro exemplo é relativamente mais fácil, pois você não precisa ficar pensando em qual será o
número da coluna que você deseja obter o valor, basta saber o nome dessa coluna.

Outro exemplo

Caso você não entenda muito de SQL, abaixo segue alguns exemplos de queries de SELECT diferentes dos
exemplo já mostrados aqui.

Exemplo 1.14. Retornando e tratando dados

<?php
// Seleciona apenas os dados das colunas 'nome' e 'marca' da tablea 'carro'
$sql = "SELECT nome, marca FROM carro";
// Seleciona todas as colunas da tabela 'carro' onde o 'ano' é igual a
'2004'
$sql = "SELECT * FROM carro WHERE ano='2004' ";
// Seleciona todas as colunas da tabela 'carro' onde o 'ano' é menor que
'2000'
$sql = "SELECT * FROM carro WHERE ano < '2000' ";
// Seleciona todas as colunas da tabela 'carro' e retorna os dados em
// ordem crescente com relação a coluna 'nome'
$sql = "SELECT * FROM carro ORDER BY nome ";
// Seleciona todas as colunas da tabela 'carro' e retorna os dados em
// ordem decrescente com relação a coluna 'marca'
$sql = "SELECT * FROM carro ORDER BY marca DESC";
// Seleciona todas as colunas da tabela 'carro' onde o 'nome'
// começar com a letra 'g'. Você pode usar essa função
// para fazer pesquisas na tabela
$sql = "SELECT * FROM carro WHERE nome LIKE "g%"";
// Seleciona todas as colunas da tabela 'carro' onde o 'nome'
// tiver a letra 'g'. Você pode usar essa função para fazer
// pesquisas na tabela
$sql = "SELECT * FROM carro WHERE nome LIKE "%g%"";

?>

42
Criando queries flexíveis
Resumo

Se juntarmos uma query string com um sistema parecido com o que acabamos de aprender, poderemos ter
queries flexiveis, que variam de acordo com uma variável do PHP (no caso, da query string). Praticamente todo
site dinâmico atual usa esse sistema para trabalhar com resultados de uma base de dados, pois ele proporciona
uma automatização muito grande de tarefas, evitando a criação de páginas com dados repetidos.

Na prática
Na prática, o que faremos é deixar que a query que buscará os dados no MySQL variável de acordo com a query
string. Veja:

Exemplo 1.15. Query variável

<?php
// Pegamos o valor do código do carro da query string
$cod = $_GET['cod'];
$servidor = 'localhost';
$usuario = 'jose';
$senha = 'banana';
$db = 'minhaDB';
if ($conexao = mysql_connect($servidor,$usuario,$senha)) {
if (!mysql_select_db($conexao) {
echo 'Não foi possível selecionar a base de dados';
}
}
else {
echo 'Não foi possível conectar-se ao servidor de bando de dados';
}

// Essa query selecionará apenas o carro que tiver


// o código igual ao indicado pela query string
$sql = "SELECT * FROM carro WHERE cod='$cod'" . ;
$resultado = mysql_query($sql);
$linha = mysql_fetch_array($resultado);
echo 'Código: ' . $linha['codigo'] . "<br />\n";
echo 'Carro: ' . $linha['nome'] . "<br />\n";
echo 'Marca: ' . $linha['marca'] . "<br />\n";
echo 'Cor: ' . $linha['cor'] . "<br />\n";
echo 'Ano: ' . $linha['ano'] . "<br />\n";
}
?>

Note que a query SQL acima varia de acordo com o código passado pelo endereço do script. Se tivermos um
endereço nome_do_arquivo.php?cod=1 apenas os dados do carro com código 1 serão mostrados. Caso o
endereço for nome_do_arquivo.php?cod=47, apenas os dados do carro com código 47 serão mostrados. Como o
campo 'codigo' da tabela 'carro' é auto_increment, nunca existirão carros com códigos iguais, por isso não
precisamos usar um while para trazer os dados.

No mundo real
Agora que você sabe disso, de uma olhada em alguma loja virtual da internet. Entre na descrição de algum
produto e você perceberá que o código do produto está no endereço (muito provavelmente), na query-string. Isso
ocorre exatamente porque essas lojas são construídas com o conceito acima, obviamente que com um pouco
mais de complexidade, mas com a mesma idéia.

E não são só lojas virtuais que usam esse recurso; qualquer site que tenha divisão de categorias e de itens pode
(e normalmente faz) uso desse conceito. É só prestar atenção que você percebe.

43
Capítulo 5. Tutorial Final
Construindo um mural de recados
Resumo

Nesse capítulo de nosso curso, aprenderemos como construir um sistema de mural de recados multi-usuários. O
sistema terá os seguintes recursos:

• Cadastro de novos usuários;


• Login de usuários cadastrados;
• Inclusão de novas mensagens;
• Exibição de mensagens já incluidas.

A esse ponto do curso, você já deve ter uma boa idéia de como um sistema construído em PHP funciona,
portanto esse tutorial não explicará coisas que já foram abordadas em capítulos anteriores.

A base de dados
Para construir nosso sistema de mensagens, precisaremos de duas tabelas. Uma contendo dados dos usuário e
outra contendo dados das mensagens.

Exemplo 1.1. As tabelas

CREATE TABLE usuario (


cod INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR( 20 ) NOT NULL ,
sobrenome VARCHAR( 40 ) NOT NULL ,
email VARCHAR( 200 ) NOT NULL ,
login VARCHAR( 30 ) NOT NULL ,
senha VARCHAR( 50 ) NOT NULL ,
data DATETIME NOT NULL ,
);
CREATE TABLE mensagem (
cod INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
cod_usuario INT NOT NULL,
titulo VARCHAR(30) NOT NULL,
texto TEXT NOT NULL,
data DATETIME NOT NULL,
);

Na tabela de mensagens, colocamos uma chave estrangeira que aponta para o código do usuário que postou a
mensagem. Toda essa coisa de separar tabelas e criar chaves estrangeiras chama-se normalização e fazemos
isso para evitar a repetição dos dados do usuário. Através dessa chave estrangeira, podemos procurar na tabela
de usuário seus dados.

Construindo o index.php
Primeiramente, construiremos o arquivo principal de nosso sistema, que será o index.php. Nele colocaremos
os includes principais do site, que são o cabeçalho, o rodapé e a query string. A estrutura dele é basicamente
assim:

Exemplo 1.2. index.php

<?php require_once 'header.inc.php'; ?>


<?php require_once 'menu.inc.php'; ?>
<div id="principal">
<?php

44
switch ($pagina) {
case 'home' :
include 'home.inc.php';
break;
case 'cadastro' :
include 'cadastro.inc.php';
break;
case 'login' :
include 'login.inc.php';
break;
case 'nova' :
include 'nova.inc.php';
break;
}
?>
</div>
<?php require_once 'footer.inc.php'; ?>

Aqui já estão todas as query strings que serão utilizadas no site, porém você pode ir adcionando-as comandos
conforme vai criando as respectivas páginas. O arquivo menu.inc.php, como o nome já diz, possui o menu que
usaremos para fazer a navegação pelo site.

Menu
Para evitar ter que ficar repetindo o código que constrói o nosso menu de navegação em todas as páginas do
site, criamos um arquivo especial só para ele, que contém somente HTML com os devidos links.

Exemplo 1.3. menu.inc.php

<div id="menu">
<ul>
<li><a href="?pagina=cadastro" title="Cadastrar novo
usuário">Cadastrar</a></li>
<li><a href="?pagina=login" title="Fazer Login">Login</a></li>
<li><a href="logout.php" title="Fazer Logout">Logout</a></li>
<li><a href="?pagina=nova" title="Nova Mensagem">Nova mensagem</a></li>
</ul>
</div>

Cabeçalho
No arquivo de cabeçalho, além de colocarmos o código HTML que será repetido entre todas as páginas, também
incluímos e criamos as variáveis e arquivos comuns que serão usadas por todos os scripts. O arquivo
conecta.inc.php contém os comandos necessários para conectar nosso script ao MySQL; ele retorna a
variável de conexão resultante da função mysql_connect().

Exemplo 1.4. header.inc.php

<?php
// Inicia a sessão
session_start();
// Criamos uma variável $pagina com o valor da query string 'pagina'
$pagina = !empty($_GET['pagina']) ? $_GET['pagina'] : 'home';
// Conectamos ao servidor. A variável $conexão agora contém
// o resource de conexão, retornado pelo mysql_connect
$conexao = require_once 'conecta.inc.php';
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

45
<head>
<title>Mural de recados</title>
<link rel="stylesheet" type="text/css" media="all" href="mural.css" />
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<div id="container">
<div id="cabecalho"><h1><a href="index.php" title="Principal">Mural de
Recados</a></h1></div>

Arquivo de conexão
O arquivo conecta.inc.php se encarrega de fazer a conexão com o MySQL. Ele retorna a variável de
conexão resultante da função mysql_connect()

Exemplo 1.5. conecta.inc.php

<?php
$bdhost = 'host';
$bdusuario = 'usuario';
$bdsenha = 'senha';
$basededados = 'basededados';
if (!$conexao = mysql_connect($bdhost,$bdusuario,$bdsenha))
echo 'Erro ao conectar-se ao MySQL';
elseif (!mysql_select_db($basededados,$conexao))
echo 'Erro ao selecionar a base de dados';
else
return $conexao;
?>

Rodapé
Bom, o rodapé não possui nada de diferente, apenas um HTML que será repetido entre as páginas.

Exemplo 1.6. footer.inc.php

</div>
<div id="footer">Sistema de mensagens - PHP & MySQL</div>
</body>
</html>

Cadastro de usuário
A primeira coisa que precisamos fazer para desenvolver o nosso mural de recados é o sistema de cadastro de
novos usuários. Ele consiste em receber as informações do usário (nome, email, senha, etc) através de um
formulário e passá-las para o banco de dados. Com essas informações guardadas, temos acesso a todos os
dados do usuário, seja para fazer autenticação deste ou simplesmente para exibir dados.

A senha do usuário não será armazenada exatamente como uma string, mas sim como um MD5 hash gerado a
partir da verdadeira senha. Um hash é o resultado da criptografia de uma string; criptografar alguma coisa é
codificá-la de modo a torná-la ilegível a quem não possua conhecimento sobre sua chave de decodificação. MD5
é o algorítimo específico que receberá a senha e a retornará na forma de um número hexadecimal com 32
caracteres. Em nosso caso, não existe chave de decodificação, portanto não pode-se pegar um hash e
transformá-lo de volta em string. Apesar da complexidade do algorítmo MD5, pelo PHP a única coisa que
precisaremos fazer é usar a função md5(), que recebe uma string e retorna o hash, sem maiores dificuldades.
Abaixo segue o código necessário para o cadastro de usuários:

Exemplo 1.7. cadastro.inc.php

<?php

46
$nome = $_POST['nome'];
$sobrenome = $_POST['sobrenome'];
$login = $_POST['login'];
$email = $_POST['email'];
$senha = $_POST['senha'];
$confsenha = $_POST['confsenha'];
function exibe_form () {
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] .
'?pagina=cadastro' . '">' . "\n";;
echo ' <p>Nome: <br /> <input type="text" name="nome" /></p>' . "\n";
echo ' <p>Sobrenome: <br /> <input type="text" name="sobrenome" /></p>' .
"\n";
echo ' <p>Login (apelido): <br /> <input type="text" name="login" /></p>'
. "\n";
echo ' <p>E-mail: <br /> <input type="text" name="email" /></p>' . "\n";
echo ' <p>Senha: <br /> <input type="password" name="senha" /></p>' .
"\n";
echo ' <p>Confirmação de Senha: <br /> <input type="password"
name="confsenha" /></p>' . "\n";
echo ' <p><input type="hidden" name="verifica_envio" value="1" /></p>' .
"\n";
echo ' <p><input type="reset" value="Recomeçar" /> <br /> <input
type="submit" value="Cadastrar" />' . "\n";
echo '</form>' . "\n";
}
// Função que faz o cadastro do usuário no banco de dados
function cadastra_usuario($nome,$sobrenome,$login,$email,$senha) {
// Usaremos a variável de conexão com o MySQL, criada no header.inc.php
global $conexao;
// Por segurança, guardamos o hash da senha
$senha = md5($senha);
$sql = "INSERT INTO
usuario
SET
nome ='$nome',
sobrenome ='$sobrenome',
email ='$email',
login ='$login',
senha ='$senha',
data = NOW()";
if ($resultado = mysql_query($sql,$conexao)) {
echo "Usuário cadastrado com sucesso! Você pode logar-se agora.\n";
}
else {
echo "Erro no cadastro, por favor tente de novo\n";
}

}
// Função que verifica se tudo está preenchido corretamente
function
processa_cadastro($nome,$sobrenome,$login,$email,$senha,$confsenha) {
if ( (empty($nome)) or (empty($sobrenome)) or (empty($login)) or
(empty($email)) or (empty($senha)) or (empty($confsenha)) or
($senha != $confsenha) )
echo "Por favor, preencha todos os campos do formulário\n";
else
cadastra_usuario($nome,$sobrenome,$login,$email,$senha);
}
?>
<h2>Cadastro de novo usuário</h2>
<?php
if (!array_key_exists('verifica_envio', $_POST))
exibe_form();
else

47
processa_cadastro($nome,$sobrenome,$login,$email,$senha,$confsenha);
?>

Como aprendemos nos capítulos anteriores, usamos apenas um arquivo tanto para exibir o formulário de
cadastro, quanto para incluir o cadastro no banco de dados. Esse arquivo possui três funções:

• processa_cadastro() : verifica se o formulário foi corretamente preenchido (inxestência de campos


vazios e confirmação da senha). Como parâmetro, ela recebe os dados preenchidos no formulário.
• exibe_form() : Como o nome já diz, essa função exibe o formulário de cadastro na tela do usuário,
caso ele ainda não o tenha preenchido.
• cadastra_usuario() : essa é a função que faz o cadastro do usuário dentro do banco de dados. Ela
recebe os dados preenchidos no formulário e os insere na devida tabela do MySQL, tomando o cuidado
de criptografar a senha antes. É bom lembrar que essa função só é chamada caso o formulário tenha
sido preechido.

Login de usuários
Para fazer o login de usuários, precisaremos de um arquivo com o formulário de login e outro para confirmar esse
login. Nesse caso não podemos fazer tudo num mesmo arquivo pois quando um usuário é logado, uma sessão é
escrita e o navegador é redirecionado; funções de redirecionamento precisam ir no HTTP Header, assim como as
sessões, o que nos obriga a executá-las antes de qualquer saída para o navegador.

Exemplo 1.8. login.inc.php

<form method="post" action="login.post.php">


<p>Login: <br /> <input type="text" name="login" /></p>
<p>Senha: <br /> <input type="password" name="senha" /></p>
<p><input type="submit" value="Entrar" />
</form>

Exemplo 1.9. login.post.php

<?php
// Iniciamos a sessão
session_start();
// Função que valida o usuário no banco de dados
function valida_usuario($usuario,$senha) {
$conexao = require_once 'conecta.inc.php';
// Criptografa a senha
$senha = md5($senha);
$sql = "SELECT * FROM usuario WHERE login='$usuario' AND senha='$senha'";
if (!$resultado = mysql_query($sql,$conexao)) {
return false;
}
elseif(mysql_num_rows($resultado) != 1) {
return false;
}
else {
return true;
}
}
// Passamos as variáveis de $_POST para a
// função de verificação do usuário
$login = $_POST['login'];
$senha = $_POST['senha'];
if (valida_usuario($login,$senha)) {
// Escreve na session
$_SESSION['login'] = $login;
$_SESSION['senha'] = $senha;
// Redireciona o usuário
header ("Location: index.php");

48
}
else {
// Caso o usuário não for validado,
// apaga as variáveis de sessão e
// mostra mensgagem de erro
unset($_SESSION['login']);
unset($_SESSION['senha']);
echo "Senha ou usuário inválidos. Tente outra vez.";
}
?>

A função valida_usuario() recebe os valores preenchidos no formulário do arquivo anterior e os verifica no


banco de dados. Retorna true ou false de acordo com o resultado da query no MySQL.

Logout de usuário
Caso um usuário queira sair do site ou logar-se como outro usuário, ele pode fazê-lo através do arquivo
logout.php. O que ele faz é simplesmente apagar as variáveis de sessão e redirecionar o usuário para a
página principal.

Exemplo 1.10. login.post.php

<?php
session_start();
// Apagando as variáveis de sessão
unset($_SESSION['login']);
unset($_SESSION['senha']);
header ('Location: index.php');
?>

Criando novas mensagens


Com nossos usuários podendo fazer login no site, agora precisamos criar a funcionalidade de envio e exibição de
mensagens. Quanto ao envio, nada diferente do que você já viu. Um formulário para a entrada dos dados e
depois uma função que insere esses dados no banco de dados.

Exemplo 1.11. nova.inc.php

<h2>Nova mensagem</h2>
<?php
function exibe_form() {
echo '<form method="post" action="' . $_SERVER['PHP_SELF'] .
'?pagina=nova">' . "\n";
echo ' <p>Título: <br /> <input type="text" name="titulo" /> </p>' . "\n";
echo ' <p>Mensagem: <br /> <textarea name="mensagem" cols="40"
rows="8"></textarea>' . "\n";
echo ' <p><input type="hidden" name="verifica_envio" value="1" />' . "\n";
echo ' <input type="reset" value="Recomeçar" />' . "\n";
echo ' <input type="submit" value="Enviar" />' . "\n";
echo ' </p>' . "\n";
echo '</form>' . "\n";
}
function insere_bd($titulo, $mensagem) {
global $conexao;
$login = $_SESSION['login'];

// Seleciona o código do usuário, de acordo com


// a variável $login, que está na sessão
$sql = "SELECT cod FROM usuario WHERE login='$login'";
$resultado = mysql_query($sql,$conexao);

49
// Como o select retornará apenas um usuário,
// não existe a necessidade de fazer um while
$cod_usuario = mysql_fetch_array($resultado);
$cod_usuario = $cod_usuario[0];
$insertsql = "INSERT INTO
mensagem
SET
cod_usuario='$cod_usuario',
titulo='$titulo',
texto='$mensagem',
data=NOW()";
if (!$resultado = mysql_query($insertsql,$conexao)) {
echo 'Erro ao criar nova mensagem';
}
else {
echo 'Mensagem criada com sucesso!';
}
}
?>
<?php
require_once 'pagina_fechada.inc.php';
if (!confirma_login()) {
echo "Você precisa estar logado para acessar esssa página";
}
else {

if ( !array_key_exists('verifica_envio',$_POST) ) {
exibe_form();
}
else {
$titulo = $_POST['titulo'];
$mensagem = $_POST['mensagem'];
if ( (!empty($titulo)) and (!empty($mensagem)) and (confirma_login())
)
insere_bd($titulo,$mensagem);
else
echo 'Você não preencheu todos os campos';
}
}
?>

Perceba que esse script chama o arquivo pagina_fechada.inc.php; ele contém a função
confirma_login(), que certifica-se de que o usuáiro está logado. Isso serve para impedir que usuários não
logados criem mensagens.

Exemplo 1.12. pagina_fechada.inc.php

<?php
function confirma_login () {
if ( (!isset($_SESSION['login'])) or (!isset($_SESSION['senha'])) )
return false;
else
return true;
}
?>

Página principal e exibição das mensagens


Precisamos agora construir a página principal do site, que exibirá as mensagens contidas no banco de dados.

Exemplo 1.13. home.inc.php

50
<?php
// Função que retorna se o usuário está logado ou não.
// Caso esteja, retorna também o nome do usuário
function status_usuario () {
if ( (!isset($_SESSION['login'])) or (!isset($_SESSION['senha'])) )
return 'Usuário não está logado';
else
return 'Usuário ' . $_SESSION['login'] . ' logado';
}
// Função que exibe as mensagens do mural de recados
function exibe_mural() {
// Usa a variável global da conexão com o MySQL
global $conexao;
$sql = "SELECT
u.login, u.email, m.titulo, m.texto, u.nome, u.sobrenome, m.data
FROM
usuario u, mensagem m
WHERE
u.cod=m.cod_usuario
ORDER BY
data DESC";
$resultado = mysql_query($sql,$conexao);
while ($linha = mysql_fetch_array($resultado)) {
$data = strtotime($linha['data']);
$dia = date("d/m/Y",$data);
$hora = date("H:i:s",$data);
echo '<div class="mensagem">';
echo '<h4>' . $linha['titulo']. "</h4>\n";
echo '<p>' . $linha['texto'] . "</p>\n";
echo '<h5>Criada dia ' . $dia . ' às ' . $hora . ',
por <a href=mailto:' . $linha['email'] . '>' .
$linha['login'] . '</a> ( ' . $linha['nome'] . ' ' .
$linha['sobrenome'] . ' ) ' . '</h5>' . "\n";
echo "</div>";
}
}
?>
<h2>Principal</h2>
<?php
echo status_usuario();
?>
<div id="mural">
<h3>Mensagens</h3>
<?php
exibe_mural();
?>
</div>

Caso você não conheça bem SQL, a query do script acima pode parecer bem estranha. Como estamos
guardando os dados do usuário em uma tabela diferente dos dados da mensagem, precisamos unir os dados
dessas duas tabelas para podermos saber quais mensagens são de cada autor. Ela usa apelidos para indentificar
as duas tabelas e seleciona os dados onde o código do usuário da tabela usuário [u.cod] é igual ao código do
usuário da tabela mensagem [m.cod_usuario] (que indica o autor da mensagem).

O resto do script é detalhe, nada de novidade. Usamos o bom e velho mysql_fetch_array() para obter os
dados retornados pelo MySQL. Existe uma função simples chamada status_usuario() que retorna se o
usuário está logado ou não (de acordo com as variáveis de sessão).

Conclusão
Apesar do código do nosso sistema de mural de recados ser um pouco grande, ele não tem nada muito
complicado. Tudo que ele utiliza você aprendeu aqui nesse curso e, como poder ver, PHP não é nenhum bicho de
sete cabeças. Não se esqueça que o manual do PHP (http://www.php.net/manual/pt_BR/) e o manual do MySQL

51
(http://dev.mysql.com/doc/mysql/pt/) são ótimas fontes de pesquisas para aprender coisas novas (e tirar dúvidas
das antigas). Não deixe de acessá-los.

52