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 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.
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çã'
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
}
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;
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.
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()
?>
<?php
function teste($a) {
echo $a; // retorna 'Olá !!!'
}
$a = 'Olá !!!';
teste($a);
?>
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
?>
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).
10
Formulário de cadastro
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):
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.
<?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. */
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:
<?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
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.
O arquivo cadastro_post.php deixa de existir e agora temos apenas o arquivo cadastro.php, que fica
assim:
<?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:
<?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.
<?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';
}
?>
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();
}
?>
<?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>
<?php
echo "<p> Aprendendo a contar: </p> \n ";
include ("numeros.php");
?>
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é.
<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>
Agora que temos os arquivos de cabeçalho e rodapé montados, basta montar a estrutura das páginas de seu site.
<?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.
<?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:
<?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.
<?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.
<?php
$carro = 'Volkswagen';
// Retorna para o script que chamou o arquivo o valor da variável $carro
return $carro;
?>
<?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:
<?php
// Cria uma variável com o valor da query string 'pagina'
19
$pagina = $_GET['pagina'];
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.
<?php
// Atribui o valor de $_GET['pagina'] à variável $pagina
if (!isset($_GET['pagina']))
$pagina = 'primeira';
else
$pagina = $_GET['pagina'];
if ($pagina == 'primeira')
include ('primeirapagina.php');
elseif ($pagina == 'segunda')
include ('segundapagina.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:
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.
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 )
<?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';
<?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:
<?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();
?>
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().
<?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.
<?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.
<?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.
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.
<?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);
?>
<?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:
<?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 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:
<?php
$agora = getdate();
// formatação da saída
echo "<pre>";
print_r($agora);
echo "</pre>";
?>
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.
<?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.
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:
<?php
echo date("d/m/y G:i:s")
?>
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.
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.
<?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.
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.
<?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
?>
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:
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:
<?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) . ".";
?>
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.
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.
<?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;';
<?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);
30
}
// Testamos se o form foi submetido
if (array_key_exists('verifica_envio',$_POST)) {
envia_email('email@dominio.com.br');
}
else {
?>
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:
<?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'];
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');
?>
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().
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.
<?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.
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:
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.
Essa função retorna o número de bytes escritos ou então false em caso de erro.
<?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)) {
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.
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.
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.
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]])
<?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:
<?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;
}
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:
<?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.
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.
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.
INSERT INTO
nome_da_tabela
SET
nome_da_coluna='dado_a_ser_inserido',
outra_coluna='outro_dado', ...
INSERT INTO
nome_da_tabela (coluna1, coluna2,...)
VALUES
(valor_da_coluna1, valor_da_coluna_2,...)
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]
DELETE FROM
nome_da_tabela
[WHERE condição_para_apagamento]
[ORDER BY coluna]
[LIMIT número_máximo]
37
SELECT colunas_a_selecionar
FROM
nome_da_tabela
[WHERE condição_para_seleção]
[ORDER BY coluna]
[LIMIT número_máximo]
<?php
$servidor = 'localhost';
$usuario = 'jose';
$senha = 'banana';
$db = 'minhaDB';
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.
38
resource mysql_query ( string query [, resource link_identifier])
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.
<?php
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.
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á.
<?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'.
<?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.
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).
<?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.
<?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:
<?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';
}
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:
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.
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:
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.
<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().
<?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';
?>
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()
<?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.
</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:
<?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:
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.
<?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.";
}
?>
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.
<?php
session_start();
// Apagando as variáveis de sessão
unset($_SESSION['login']);
unset($_SESSION['senha']);
header ('Location: index.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'];
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.
<?php
function confirma_login () {
if ( (!isset($_SESSION['login'])) or (!isset($_SESSION['senha'])) )
return false;
else
return true;
}
?>
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