PHP UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA GRUPO PET - COMPUTAÇÃO PHP UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA GRUPO PET - COMPUTAÇÃO Autores: André Luis de Paula Arthur Kalsing Diego Macedo Outubro 2011 Adaptação do original de: Ismael Stangherlini PET Computação - sala 202 Prédio 43424 (prédio dos laboratórios) Instituto de Informática - UFRGS email: [email protected] http://inf.ufrgs.br/pet/ Av. Bento Gonçalves, 9500 bloco IV Bairro Agronomia - 91501-970 - Porto Alegre/RS Índice 1 - Introdução 1.1 - O que é PHP? 1.2 - O que pode ser feito com PHP? 2 - Sintaxe Básica 2.1 - Separador de Instruções 2.2 - Nomes de Variáveis 2.3 - Comentários 3 - Tipos 3.1 - Inteiros e Pontos Flutuantes 3.2 - Strings 3.3 - Arrays 3.3.1 - Listas 3.4 - Objetos 3.5 - Booleanos 3.6 - Transformações de Tipos 3.6.1 - Coerções 3.6.2 - Transformações explícitas de tipos 3.6.3 - Com a função settype 4 - Constantes 4.1 - Constantes pré-definidas 4.2 - Definindo constantes 5 - Operadores 5.1 - Aritméticos 5.2 - De Strings 5.3 - De Atribuição 5.4 - Bit a Bit 5.5 - Comparação 5.6 - Lógicos 5.7 - Ternário 5.8 - Incremento e Decremento 6 - Estruturas de Controle 6.1 - Blocos 6.2 - Comandos de Seleção 6.2.1 - If 6.2.2 - Switch 6.3 - Comandos de Repetição 6.3.1 - While 6.3.2 - Do...While 6.3.3 - For 6.3.4 - Foreach 6.4 - Quebra de Fluxo 6.4.1 - Break 6.4.2 - Continue 7 - Funções 7.1 - Definindo Funções 7.2 - Valor de Retorno 7.3 - Argumentos 7.4 - Passagem de Parâmetros por Referência 7.5 - Argumentos com Valores Pré-Definidos (Default) 7.6 - Contexto 7.7 - Escopo 7.8 - Funções Recursivas 8 - Variáveis 8.1 - O modificador Static 8.2 - Variáveis Variáveis 8.3 - URLencode 8.4 - Variáveis Enviadas pelo Navegador 8.5 - Variáveis de Ambiente 8.6 - Verificando o Tipo de uma Variável 8.6.1 - Função que Retorna o Tipo da Variável 8.6.2 - Funções que Testam o Tipo da Variável 8.7 - Destruindo uma Variável 8.8 - Verificando se uma Variável Possui um Valor 8.8.1 - A Função Isset 8.8.2 - A Função Empty 8.9 - Arrays Multidimensionais 9 - Includes 9.1 - Include x Require 10 - Formulários 10.1 - A Opção Action 10.2 - Envio de Informações ao Programa PHP 10.2.1 - O Método GET 10.2.2 - O Método POST 10.3 - Tratamento das Informações Recebidas 10.4 - Funções para Formatação de Dados 10.4.1 - HTMLspecialchars 10.4.2 - Stripslashes 10.5 - Selecionando Código HTML 11 - Manipulação de Arquivos Remotos 11.1 - Fopen 11.2 - Fclose 11.3 Fread 11.4 - Fgets 11.5 - Fwrite 12 - Programação Orientada a Objetos 12.1 - Classes 12.2 - Objetos 12.3 - A Variável $this 12.4 - Construtores 13 - Tratamento de Erros 14 - Bancos de Dados 14.1 - Conceitos Básicos 14.2 - SQL 14.2.1 - INSERT 14.2.2 - UPDATE 14.2.3 - DELETE 14.2.4 - SELECT 14.3 - PHP e Bancos de Dados 14.3.1 - mysql_connect 14.3.2 - mysql_close 14.3.3 - mysql_select_db 14.3.4 - mysql_query 14.3.5 - Manipulando Resultados dos Comandos SQL 15 – Cookies e Sessions 15.1 - Cookies 15.2 - Acesso aos Cookies pelo PHP 15.3 - Exemplo de Utilização de Cookies 15.4 - Sessions 16 - Bibliotecas Interessantes 17 - Conclusões 1. Introdução 1.1 - O que é PHP? PHP significa: PHP Hyperswitchtext Preprocessor. Realmente, o produto foi originalmente chamado de "Personal Home Page Tools"; mas como se expandiu em escopo, um nome novo e mais apropriado foi escolhido por votação da comunidade. A extensão ".php" é a recomendada para designar um arquivo PHP. PHP é uma linguagem de criação de scripts embutida em HTML no servidor. Pode-se pensar no PHP como uma coleção de supertags de HTML que permitem adicionar funções do servidor às suas páginas da Web. Por exemplo, é possível utilizar PHP para montar instantaneamente uma complexa página da Web. Diferente de certas linguagens de script como JavaScript, onde o código da página acessada utiliza recursos de processamento do computador em que o usuário se encontra, o PHP possui a vantagem de seu código ser executado diretamente no servidor, sendo os resultados enviados para o navegador. Portanto, o navegador exibe a página já processada, sem consumir recursos do processador. O PHP tem pouca relação com layout, eventos ou qualquer coisa relacionada à aparência de uma página da Web. De fato, a maior parte do que o PHP realiza é invisível para o usuário final. Alguém visualizando uma página de PHP não será capaz de dizer que não foi escrita em HTML, porque o resultado final do PHP é HTML. 1.2 - O que pode ser feito com PHP? Alguns exemplos do que pode ser feito em PHP é: coletar dados de um formulário, gerar páginas dinamicamente ou enviar e receber cookies. PHP também tem como uma das características mais importantes, o suporte a um grande número de bancos de dados, como dBase, Interbase, mSQL, mySQL, Oracle, Sybase, PostgreSQL e vários outros. Construir uma página baseada em um banco de dados torna-se uma tarefa extremamente simples com PHP. Imagine, por exemplo, que um site possui cerca de 200 páginas e em cada uma das páginas existe, no lado esquerdo, um menu com links para diversas seções do site. Caso as páginas fossem criadas através de HTML puro e fosse desejado alterar o menu com a inclusão ou exclusão de alguma seção, seria necessário modificar uma a uma todas as páginas do site, tornando o processo de alteração ineficiente e cansativo. Com o uso de PHP, pode-se criar um arquivo único com o menu e todas as páginas do site, então, podem acessar este arquivo. Isso permite que as alterações, quando necessárias, sejam apenas realizadas no arquivo que contém o menu, economizando tempo para a produção de páginas dinâmicas. 2. Sintaxe Básica O código PHP fica embutido no próprio HTML. O interpretador identifica quando um código é PHP para que seja processado pelo servidor através das seguintes tags: <?php comandos ?> ou <script language="php"> comandos </script> ou <? comandos ?> O tipo de tags mais utilizado é o terceiro, que consiste em uma "abreviação" do primeiro. Dentro dessas tags podem ser escritos apenas códigos em PHP. Caso se deseje colocar algum código HTML dentro das tags é necessária a utilização do comando echo. É importante observar, também, que podem existir 'diversos códigos PHP' num mesmo arquivo HTML. Tudo isso é exemplificado abaixo: <html> <body> <b>Meu primeiro programa em PHP</b><br> <? echo "Posso escrever qualquer coisa, até mesmo códigos HTML<br>"; ?> <b> Volta o código HTML </b><br> <? echo "Outro código em PHP"; ?> </body> </html> 2.1 - Separador de instruções Para cada fim de linha de código deve existir um ponto e vírgula, indicando ao sistema fim de instrução. Exemplo: <? echo 'com ponto e vírgula' ; ?> Linhas de comando de controle não precisam de ponto e vírgula. Exemplo: <? if ($x == $x){ //aqui não precisa de ponto e vírgula echo 'com ponto e vírgula' ; //aqui precisa de ponto e vírgula } ?> 2.2 - Nomes de variáveis Toda variável em PHP tem seu nome composto pelo caracter $ e uma string, que deve iniciar por uma letra ou o caracter "_". PHP é case sensitive, ou seja, as variáveis $php e $PHP são diferentes. Por isso é preciso ter muito cuidado ao definir os nomes das variáveis. É bom evitar os nomes em maiúsculas, pois como veremos mais adiante, o PHP já possui algumas variáveis pré-definidas cujos nomes são formados por letras maiúsculas. 2.3 - Comentários Comentários são extremamente importantes para futuras análises do código ou reutilização do mesmo. Dessa forma, documentando seu código de forma simples e direta pode ser considerada uma boa prática de programação. * Comentários de uma linha: Possui como delimitadores os caracteres "//" ou "#". Exemplo: <? echo "teste"; #isto é um teste echo "teste"; //este teste é similar ao anterior ?> * Comentários de mais de uma linha: Tem como delimitadores os caracteres "/*" para o início do bloco de comentário e "*/" para o final do bloco. Se o delimitador de final de código PHP ( ?> ) estiver dentro de um comentário, não será reconhecido pelo interpretador. Exemplo: <? echo "teste"; /* Isto é um comentário com mais de uma linha que funciona corretamente */ ?> 3. Tipos PHP suporta os seguintes tipos de dados: • • • • • Inteiro Ponto flutuante String Array Objeto PHP utiliza checagem de tipos dinâmica, ou seja, uma variável pode conter valores de diferentes tipos em diferentes momentos da execução do script. Por este motivo não é necessário declarar o tipo de uma variável para usá-la. O interpretador PHP decidirá qual o tipo daquela variável, verificando o conteúdo em tempo de execução. Ainda assim, é permitido converter os valores de um tipo para outro desejado, utilizando o typecasting ou a função settype (ver adiante). 3.1 - Inteiros (integer ou long) e Pontos Flutuantes Uma variável pode conter um valor inteiro com atribuições que sigam as seguintes sintaxes: $php = 1234; $php = -234; $php = 0234; $php = 0x34; # inteiro positivo na base decimal # inteiro negativo na base decimal # inteiro na base octal-simbolizado pelo 0 # equivale a 156 decimal # inteiro na base hexadecimal(simbolizado # pelo 0x) - equivale a 52 decimal. Uma variável pode conter um valor em ponto flutuante de forma similar: $php = 3.1415 $php = 2.7E+5 # valor real # valor real equivalente a 270000 A diferença entre inteiros simples e long está no número de bytes utilizados para armazenar a variável. Como a escolha é feita pelo interpretador PHP de maneira transparente para o usuário, podemos afirmar que os tipos são iguais. 3.2 - Strings Strings podem ser atribuídos de duas maneiras: a) utilizando aspas simples ( ' ) - Desta maneira, o valor da variável será exatamente o texto contido entre as aspas (com exceção de \\ e \' - ver tabela abaixo) b) utilizando aspas duplas ( " ) - Desta maneira, qualquer variável ou caracter de escape será expandido antes de ser atribuído. Exemplo: <? $teste = "Brasil"; $php = '---$teste--\n'; echo "$php"; ?> A saída desse script será "---$teste--\n". <? $teste = "Brasil"; $php = "---$teste---\n"; echo "$php"; ?> A saída desse script será "---Brasil--" (com uma quebra de linha no final). A tabela seguinte lista os caracteres de escape: Sintaxe \n \r \t \\ \$ \' \" Significado Nova linha Enter Tabulação horizontal A própria barra ( \ ) O símbolo $ Aspa simples Aspa dupla 3.3 - Arrays Arrays em PHP podem ser observados como mapeamentos ou como vetores indexados. Mais precisamente, um valor do tipo array é um dicionário onde os índices são as chaves de acesso. Dessa forma, diferente das variáveis comuns que podem armazenar um único valor por vez, arrays podem armazenar diversos valores ao mesmo tempo. Vale ressaltar que os índices podem ser valores de qualquer tipo e não somente inteiros. Inclusive, se os índices forem todos inteiros, estes não precisam formar um intervalo contínuo. Como a checagem de tipos em PHP é dinâmica, valores de tipos diferentes podem ser usados como índices de array, assim como os valores mapeados também podem ser de diversos tipos. Exemplo: <? $cor[1] = "vermelho"; $cor[2] = "verde"; $cor[3] = "azul"; $cor["teste"] = 1; ?> Equivalentemente, pode-se escrever: <? $cor = array(1 => "vermelho", 2 => "verde", 3 => "azul", "teste" => 1); ?> Se não colocarmos o índice do vetor entre colchetes, o PHP irá procurar o último índice utilizado e irá incrementá-lo, armazenando assim o valor na posição seguinte do array, conforme mostra o exemplo a seguir: $vet[] = "Isso é armazenado na posição 0 do array"; $vet[] = "Isso é armazenado na posição 1 do array"; Mais adiante será vista a definição de arrays multidimensionais. 3.3.1 - Listas As listas são utilizadas em PHP para realizar atribuições múltiplas. Através de listas é possível atribuir valores que estão num array para variáveis. Vejamos o exemplo: Exemplo: list($a, $b, $c) = array("a", "b", "c"); O comando acima atribui valores às três variáveis simultaneamente. É bom notar que só são atribuídos às variáveis da lista os elementos do array que possuem índices inteiros e não negativos. No exemplo acima as três atribuições foram bem sucedidas porque ao inicializar um array sem especificar os índices eles passam a ser inteiros, a partir do zero. Um fator importante é que cada variável da lista possui um índice inteiro e ordinal, iniciando com zero, que serve para determinar qual valor será atribuído. No exemplo anterior temos $a com índice 0, $b com índice 1 e $c com índice 2. Vejamos um outro exemplo: $arr = array(1=>"um",3=>"tres","a"=>"letraA",2=>"dois); list($a,$b,$c,$d) = $arr; Após a execução do código acima temos os seguintes valores: $a == null $b == "um" $c == "dois" $d == "tres" Devemos observar que à variável $a não foi atribuído valor, pois no array não existe elemento com índice 0 (zero). Outro detalhe importante é que o valor "tres" foi atribuído à variável $d, e não a $b, pois seu índice é 3, o mesmo que $d na lista. Por fim, vemos que o valor "letraA" não foi atribuído a elemento algum da lista, pois seu índice não é inteiro. Os índices da lista servem apenas como referência ao interpretador PHP para realizar as atribuições, não podendo ser acessados de maneira alguma pelo programador. De maneira diferente do array, uma lista não pode ser atribuída a uma variável, servindo apenas para fazer múltiplas atribuições através de um array. 3.4 - Objetos Um objeto é uma instância de uma classe. Dessa forma, um objeto caracteriza-se por ser uma estrutura associada a uma variável que possui certas propriedades provenientes da classe em que foi instanciada. Um objeto pode ser inicializado utilizando o comando new para instanciar uma classe para uma variável. Exemplo: class teste { function nada() { echo "nada"; } } $php = new teste; $php -> nada(); O código acima resultará na saída "nada" na tela. Uma vez que a classe teste foi instanciada no objeto $php através do comando new, pôde-se utilizar a função nada criada dentro dessa classe, emitindo, por fim, a saída desejada. A utilização de objetos será mais detalhada posteriormente. 3.5 - Booleanos Introduzido no PHP 4, os valores false e true são ambos case insensitive (True, true, TRUE e truE significam todos o mesmo valor "true"). Os equivalentes a false e true, respectivamente, referentes aos demais tipos primitivos são os seguintes: Integers: 0 ; qualquer número não nulo Floats: 0.0 ; qualquer número não nulo Strings: o string vazio ; qualquer string não vazio Array: o array vazio ; qualquer array não vazio 3.6 - Transformação de tipos A transformação de tipos em PHP pode ser feita das seguintes maneiras: 3.6.1 - Coerções Quando ocorrem determinadas operações ("+", por exemplo) entre dois valores de tipos diferentes, o PHP converte o valor de um deles automaticamente (coerção). É interessante notar que se o operando for uma variável, seu valor não será alterado. O tipo para o qual os valores dos operandos serão convertidos é determinado da seguinte forma: Se um dos operandos for float, o outro será convertido para float, senão, se um deles for integer, o outro será convertido para integer. Exemplo: $php = "1"; // $php é a string "1" $php = $php + 1; // $php é o integer 2 $php = $php + 3.7; // $php é o double 5.7 $php = 1 + 1.5 // $php é o double 2.5 Como podemos notar, o PHP converte string para integer ou double mantendo o valor. O sistema utilizado pelo PHP para converter de strings para números é o seguinte: • É analisado o início da string. Se contiver um número, ele será avaliado. Senão, o valor será 0 (zero); • • O número pode conter um sinal no início ("+" ou "-"); Se a string contiver um ponto em sua parte numérica a ser analisada, ele será considerado, e o valor obtido será double; • Se a string contiver um "e" ou "E" em sua parte numérica a ser analisada, o valor seguinte será considerado como expoente da base 10 e o valor obtido será double; Exemplos: $php $php $php $php $php $php = = = = = = 1 1 1 1 1 1 + + + + + + "10.5"; "-1.3e3"; "teste10.5"; "10testes"; " 10testes"; "+ 10testes"; // $php == 11.5 // $php == -1299 // $php == 1 // $php == 11 // $php == 11 // $php == 1 3.6.2 - Transformação explícita de tipos A sintaxe do typecast de PHP é semelhante ao C: basta escrever o tipo entre parênteses antes do valor. Exemplo: $php = 15; $php = (double) $php $php = 3.9 $php = (int) $php // // // // // $php é $php é $php é $php é o valor integer (15) double (15.0) double (3.9) integer (3) decimal é truncado Os tipos de cast permitidos são: (int), (integer) // muda para integer; (real), (double), (float) // muda para float; (string) // muda para string; (array) //muda para array; (object) //muda para objeto. 3.6.3 - Com a função settype A função settype converte uma variável para o tipo especificado, que pode ser "integer", "double", "string", "array" ou "object". Exemplo: $php = 15; settype($php,double) // $php é integer // $php é double // $php possui valor 15.0 4. Constantes 4.1 - Constantes pré-definidas O PHP possui algumas constantes pré-definidas, indicando a versão do PHP, o Sistema Operacional do servidor, o arquivo em execução, e diversas outras informações. Para ter acesso a todas as constantes pré-definidas, pode-se utilizar a função phpinfo(), que exibe uma tabela contendo todas as constantes pré-definidas, assim como configurações da máquina, sistema operacional, servidor http e versão do PHP instalada. 4.2 - Definindo constantes Para definir constantes utiliza-se a função define. Uma vez definido, o valor de uma constante não poderá mais ser alterado. Uma constante só pode conter valores escalares, ou seja, não pode conter nem um array nem um objeto. A assinatura da função define é a seguinte: int define(string nome_da_constante, mixed valor); A função retorna true se for bem-sucedida. Veja um exemplo de sua utilização a seguir: define ("pi", 3.1415926536); $raio = 3; $circunf = 2*pi*$raio; O código acima terá na variável $circunf o resultado 18.8495559216. 5. Operadores 5.1 - Aritméticos Só podem ser utilizados quando os operandos são números (integer ou float). Se forem de outro tipo, terão seus valores convertidos antes da realização da operação. + * / % adição subtração multiplicação divisão módulo ou resto da divisão Exemplo: <? $a = 5; $b = 3; $c = (2 * $a) + $b; $d = $a % $b; ?> // $c = (2 * 5) + 3 = 13 // $d = 5 % 3 = 2 (resto da divisão) Observa-se que a colocação dos parêntes quando da atribuição do valor a variável $c não é necessária, uma vez que a precedência dos operadores satisfaz a propriedade. Porém, colocar parênteses é uma boa prática de programação e deve ser utilizada para facilitar o entendimento do programador e evitar erros. 5.2 - De strings Só há um operador exclusivo para strings: . concatenação Exemplo: <? $palavra1 = "Isto é um"; $palavra2 = " teste"; $palavra3 = $palavra1 . $palavra2; echo $palavra3; // resultado esperado: "Isto é um teste" ?> 5.3 - De atribuição Existe um operador básico de atribuição e diversos derivados. Sempre retornam o valor atribuído. No caso dos operadores derivados de atribuição, a operação é feita entre os dois operandos, sendo atribuído o resultado para o primeiro. A atribuição é sempre por valor, e não por referência. = += -= *= /= %= .= atribuição atribuição atribuição atribuição atribuição atribuição atribuição simples com adição com subtração com multiplicação com divisão com módulo com concatenação Exemplo: $a $a $b $b = 7; += 2; = 3; *= $a; // $a passa a conter o valor 9 // $b passa a conter o valor 27 5.4 - Bit a Bit Esses operadores atuam em um nível de abstração mais baixo, comparando dois números bit a bit. & | ^ ~ << >> "e" lógico "ou" lógico ou exclusivo não (inversão) shift left shift right Exemplo: $a = 36; $a = $a >> 2; $b = 12; // $a possui o valor binário 100100 // $a é deslocado de 2 bits a direita // $a passa a ter o valor 9 (001001) // $b possui o valor binário 1100; $b = ~$b; $c = $a & $b; // $b é invertido bit a bit, gerando o valor -13 (...11110011) // $c possui o valor 1 (0001) resultante de $a (1001) & $b (0011) É importante observar que um deslocamento de bits para a esquerda equivale a multiplicação do valor por 2, e um deslocamento de bits para a direita equivale a divisão do valor por 2. 5.5 - Comparação As comparações são feitas entre os valores contidos nas variáveis, e não as referências. Sempre retornam um valor booleano. == != < > <= >= igual a diferente de menor que maior que menor ou igual a maior ou igual a Exemplo: <? $a = 9; $b = 8; if ($a >= $b) // retorna verdadeiro, pois $a é maior ou igual a $b { echo "a é maior ou igual a b"; } ?> 5.6 - Lógicos Utilizados para inteiros representando valores booleanos: and or xor ! && || "e" lógico "ou" lógico ou exclusivo não (inversão) "e" lógico "ou" lógico Existem dois operadores para "e" e para "ou" porque eles têm diferentes posições na ordem de precedência. Exemplo: <? if (($y > $x) and ($z == 5)) // expressão válida somente se as { echo "y é maior que x e z é igual a 5"; } // duas expressões forem 'true' ?> 5.7 - Ternário Existe um operador de seleção que é ternário. Ele funciona da seguinte forma: (expressao1)?(expressao2):( expressao3) O interpretador PHP avalia a primeira expressão. Se ela for verdadeira, a expressão retorna o valor de expressão2. Senão, retorna o valor de expressão3. Exemplo: <? $a = 6; $b = 4; $valor = ($a > $b) ? ($a + 2):($b - 2); // como $a é maior que $b, retorna a // expressão 1 echo $valor; // exibe na tela o valor 8 ?> 5.8 - Incremento e Decremento O PHP, assim como o C, possui operadores aritméticos que atuam apenas sobre 1 operando, podendo incrementar ou decrementar esse operando. Os operadores utilizados para isso são os seguintes: ++ -- incremento decremento Esses operadores podem ser utilizados da seguinte forma: ++oper Pré-incremento. Primeiro incrementa o valor do operando e depois realiza a operação. --oper Pré-decremento. Primeiro decrementa o valor do operando e depois realiza a operação. Pós-incremento. Primeiro realiza a operação e depois incrementa o operando. oper++ oper-- Pós-decremento. Primeiro realiza a operação e depois decrementa o operando. Exemplos: $a = $b = 10; // $a e $b recebem o valor 10 $c = $a++; // $c recebe 10 e $a passa a ter 11 $d = ++$b; // $d recebe 11, valor de $b já incrementado 6. Estruturas de Controle As estruturas que veremos a seguir são comuns para as linguagens de programação imperativas, bastando, portanto, descrever a sintaxe de cada uma delas, resumindo o funcionamento. Porém, antes é necessário o conhecimento da definição de blocos, já utilizados por nós em exemplos anteriores. 6.1 - Blocos Um bloco consiste de vários comandos agrupados com o objetivo de relacioná-los com determinado comando ou função. Em comandos como if, for, while, switch e em declarações de funções blocos podem ser utilizados para permitir que um comando faça parte do contexto desejado. Blocos em PHP são delimitados pelos caracteres "{" e "}". A utilização dos delimitadores de bloco em uma parte qualquer do código não relacionada com os comandos citados ou funções não produzirá efeito algum, e será tratada normalmente pelo interpretador. Exemplo: if ($x == $y) comando1; comando2; No caso acima, o comando2 será realizado independentemente de $x ser igual a $y. Para que comando2 esteja relacionado ao if é preciso utilizar um bloco: if ($x == $y) { comando1; comando2; } Da forma como foi mostrado acima, tanto comando1 quanto comando2 apenas serão realizados se $x for igual a $y, devido a utilização do bloco. 6.2 - Comandos de seleção Também chamados de condicionais, os comandos de seleção permitem executar comandos ou blocos de comandos com base em testes feitos durante a execução. 6.2.1 - If O mais trivial dos comandos condicionais é o if. Ele testa a condição e executa o comando indicado se o resultado for true (valor diferente de zero). Ele possui duas sintaxes: if (expressão) comando; if (expressão){ comando1; comando2; comando3; comando4; comando5; comando6; comando7; comando8; } if (expressão): comando1; ... comandon; endif; Para incluir mais de um comando no if da primeira sintaxe, é preciso utilizar um bloco, demarcado por chaves. O else é um complemento opcional para o if. Se utilizado, o comando será executado se a expressão retornar o valor false (zero). Suas duas sintaxes são: if (expressão) comando; else comando; if (expressão): comando1; ... comandon; else comando1; ... comandon; endif; A seguir, temos um exemplo do comando if utilizado com else: if ($a > $b) $maior = $a; else $maior = $b; O exemplo acima coloca em $maior o maior valor entre $a e $b. Primeiramente, testase se $a é maior que $b. Se a sentença for verdadeira, a variável $maior recebe o valor de $a. Senão, a variável $maior recebe o valor de $b. Em determinadas situações é necessário fazer mais de um teste, e executar condicionalmente diversos comandos ou blocos de comandos. Uma estrutura do tipo a seguir: if (expressao1) comando1; else if (expressao2) comando2; else if (expressao3) comando3; else comando4; pode ser substituída por uma estrutura usando o comando opcional elseif. Ele tem a mesma função de um else e um if usados seqüencialmente, como no exemplo acima. Num mesmo if podem ser utilizados diversos elseif's, ficando essa utilização a critério do programador, que deve zelar pela legibilidade de seu script. O comando elseif também pode ser utilizado com dois tipos de sintaxe. Em resumo, a sintaxe geral do comando if fica das seguintes maneiras: if (expressao1) comando; [ elseif (expressao2) comando; ] [ else comando; ] if (expressao1) : comando1; ... comandon; [ elseif (expressao2) comando1; ... comandon; ] [ else comando1; ... comandon; ] endif; 6.2.2 - Switch O comando switch atua de maneira semelhante a uma série de comandos if na mesma expressão. Freqüentemente o programador pode querer comparar uma variável com diversos valores, e executar um código diferente a depender de qual valor é igual ao da variável. Quando isso for necessário, deve-se usar o comando switch. Segue abaixo a sintaxe desse comando: switch (operador) { case valor1: <comandos> break; case valor2: <comandos> break; ... case valorN: <comandos> break; default: <comandos> break; } A opção default funciona da mesma forma como o else do comando if. Se todas as expressões anteriores retornarem falso, o bloco de comandos referentes a opção default é o que será executado. O uso de default não é obrigatório. O exemplo a seguir mostra dois trechos de código que fazem a mesma coisa, sendo que o primeiro utiliza uma série de if's e o segundo utiliza switch: if ($conceito == "A") print "Seu conceito é elseif ($conceito == "B") print "Seu conceito é elseif ($conceito == "C") print "Seu conceito é else print "Seu conceito é switch ($conceito) { case "A": print "Seu break; case "B": print "Seu break; case "C": print "Seu break; default: print "Seu } A"; B"; C"; D"; conceito é A"; conceito é B"; conceito é C"; conceito é D"; É importante compreender o funcionamento do switch para não cometer enganos. O comando switch testa linha a linha os cases encontrados, e a partir do momento que encontra um valor igual ao da variável testada, passa a executar todos os comandos seguintes, mesmo os que fazem parte de outro teste, até o fim do bloco. É por este motivo que utiliza-se o comando break, quebrando o fluxo e fazendo com que o código seja executado da maneira desejada. Veremos mais sobre o break mais adiante. Veja o exemplo: switch ($i) { case 0: case 1: print "i é igual a zero"; print "i é igual a um"; case 2: } print "i é igual a dois"; No exemplo acima, se $i for igual a zero, os três comandos "print" serão executados. Se $i for igual a 1, os dois últimos "print" serão executados. O comando só funcionará da maneira desejada se $i for igual a 2. Em outras linguagens que implementam o comando switch, ou similar, os valores a serem testados só podem ser do tipo inteiro. Em PHP é permitido usar valores do tipo string como elementos de teste do comando switch. O exemplo abaixo funciona perfeitamente: switch ($s) { case "casa": print "A casa é amarela"; break; case "arvore": print "A árvore é bonita"; break; case "lâmpada": print "João apagou a lâmpada"; break; } 6.3 - Comandos de Repetição Freqüentemente deseja-se que certos comandos sejam executados repetidamente até que determinada condição seja satisfeita ou até que uma determinada variável alcance um certo valor. 6.3.1 - While O while é o comando de repetição (laço) mais simples. Ele testa uma condição e executa um comando, ou um bloco de comandos, até que a condição testada seja falsa. Assim como o if, o while também possui duas sintaxes alternativas: while (<expressão>) <comando>; while (<expressão>) { <comando1>; <comando2>; <comando3>; <comando4>; <comando5>; } while (<expressão>): <comando>; ... <comando>; endwhile; A expressão só é testada a cada vez que o bloco de instruções termina, além do teste inicial. Se o valor da expressão passar a ser falso no meio do bloco de instruções, a execução segue até o final do bloco. Se no teste inicial a condição for avaliada como falso, o bloco de comandos não será executado. O exemplo a seguir mostra o uso do while para imprimir os números de 1 a 10: $i = 1; while ($i <=10) print $i++; 6.3.2 - Do...While O laço do...while funciona de maneira bastante semelhante ao while, com a simples diferença que a expressão é testada ao final do bloco de comandos. O laço do...while possui apenas uma sintaxe, que é a seguinte: do { ... <comando> <comando> } while (<expressão>); O exemplo utilizado para ilustrar o uso do while pode ser feito da seguinte maneira utilizando o do... while: $i = 0; do { print ++$i; } while ($i < 10); 6.3.3 - For O tipo de laço mais complexo é o for. Para os que programam em C, C++ ou Java, a assimilação do funcionamento do for é natural. Mas para aqueles que estão acostumados a linguagens como Pascal, há uma grande mudança para o uso do for. As três sintaxes permitidas são: for (<inicialização>;<condição>;<incremento ou decremento>) <comando>; for (<inicialização>;<condição>;<incremento ou decremento>) { <comando>; <comando>; <comando>; <comando>; <comando>; } for (<inicialização>;<condição>;<incremento ou decremento>): <comando>; ... <comando>; endfor; As três expressões que ficam entre parênteses têm as seguintes finalidades: Inicialização: comando ou seqüência de comandos a serem realizados antes do início do laço. Serve para inicializar variáveis. Condição: Expressão booleana que define se os comandos que estão dentro do laço serão executados ou não. Enquanto a expressão for verdadeira (valor diferente de zero) os comandos serão executados. Incremento: Comando executado ao final de cada execução do laço. Um comando for funciona de maneira semelhante a um while escrito da seguinte forma: <inicialização> while (<condição>) { comandos ... <incremento> } Observe o exemplo abaixo referente a utilização do comando for: $soma = 0; for ($contador = 1; $contador <= 10; $contador++) { if ($contador % 3 == 0) $soma += $contador; } O código acima é inicializado através da expressão $contador = 1. A seguir, todo o bloco de instruções é executado enquanto a condição $contador <= 10 for satisfeita. Nota-se que ao final de cada iteração do laço, incrementa-se a variável contador de 1 através da expressão $contador++. Dessa forma, testa-se para cada iteração se o valor da variável $contador é divisível por 3 (resto 0). Se o teste resultar em true, incrementa-se na variável $soma o valor da variável $contador. Ao final do laço teremos, portanto, na variável $soma a "soma" de todos os números divisíveis por 3 que estão no intervalo de 1 a 10. Diferentemente da linguagem Pascal, em que o incremento natural da variável de controle do laço é realizada de apenas o valor 1, em PHP o incremento pode ser realizado de um valor indeterminado. Além disso, pode-se inicializar mais de uma variável no parâmetro de inicialização e pode-se ter mais de um operador no parâmetro de incremento. Observe o código abaixo que executa a mesma função do código anterior, porém com a inicizalização da variável $soma dentro do escopo do próprio comando for. for ($contador = 1, $soma = 0 ; $contador <= 10 ; $contador++) { if ($contador % 3 == 0) $soma+= $contador; } 6.3.4 - Foreach Esse comando funciona apenas a partir do PHP 4. De maneira simples, o comando foreach permite uma melhora navegação entre os elementos de um array. Existem duas formas de se utilizar esse comando: foreach ($nome_do_array as $valor) { comandos; } foreach ($nome_do_array as $chave => $valor) { comandos; } No primeiro caso, o array é visitado em cada um de seus elementos (por isso o nome for-each). A cada iteração, o valor do array visitado é passado para a variável $valor e o ponteiro interno do array é avançado. Assim sendo, pode-se trabalhar em cima de todos os elementos do array utilizando-se apenas a variável $valor. No segundo caso, o array também é visitado em cada um de seus elementos, passando o conteúdo da posição do array visitada para a variável $valor. Além disso, o índice da posição do array é passada para a variável $chave. Observe o exemplo abaixo: $vetor = array(1,2,3,4,5); foreach ($vetor as $elemento) { $elemento *= $elemento; echo "$elemento "; } A saída do código acima será o string "1 4 9 16 25". 6.4 - Quebra de fluxo Existem certos comandos que servem como estruturas auxiliares para a quebra de fluxo de outros comandos. Suas aplicabilidades são apresentadas a seguir. 6.4.1 - Break O comando break pode ser utilizado em estruturas como o do, for, while e o switch, como visto anteriormente. Ao encontrar um break dentro de uma dessas estruturas, o interpretador PHP pára imediatamente a execução da mesma, seguindo normalmente o fluxo do script. Observe o exemplo abaixo: while ($x > 0) { ... if ($x == 20) { echo "erro! x = 20"; break; } ... } No trecho de código acima, o laço while tem uma condição para seu término normal ($x <= 0), mas foi utilizado o break para o caso de um término não previsto no início do laço (no caso, se $x for igual a 20). Dessa forma, o interpretador seguirá para o comando seguinte ao laço. Além disso, pode-se colocar um argumento numérico ao lado do comando break, indicando o número de estruturas que devem ser finalizadas. Observe o exemplo abaixo: for ($ano = 2000 ; $ano < 2008 ; $ano++) { for ($mes = 1; $mes < 13 ; $mes++) { if (($mes == 9) && ($ano = 2001)) { echo "Queda das Torres Gêmeas!"; break 2; } } } Observe que no momento em que a variável $mes contiver o valor 9 e a variável $ano contiver o valor 2001, o comando break 2 será executado, finalizando as duas estruturas for e continuando normalmente a execução do código no comando seguinte ao for mais externo. 6.4.2 - Continue O comando continue deve ser utilizado no interior de laços e funciona de maneira semelhante ao break, com a diferença de que o fluxo ao invés de sair do laço volta para o início dele. Vejamos o exemplo: for ($i = 0; $i < 100; $i++) { if ($i % 2) continue; echo " $i "; } O exemplo acima é uma maneira ineficiente de imprimir os números pares entre 0 e 99. O que o laço faz é testar se o resto da divisão entre o número e 2 é 0. Se for diferente de zero (valor lógico true) o interpretador encontrará um continue, que faz com que os comandos seguintes do interior do laço sejam ignorados, seguindo para a próxima iteração. É importante observar que, da mesma forma como o comando break, o comando continue também aceita um argumento numérico ao seu lado, indicando quantos laços deve-se voltar ao início, ignorando o restante do código. 7. Funções Funções são trechos de código que permitem que uma mesma tarefa seja escrita apenas uma vez. Assim sendo, cada vez que é necessário a realização daquela tarefa, basta "chamar" a função, ao invés de reescrever o código referente a tarefa. 7.1 - Definindo Funções A sintaxe básica para definir uma função é: function nome_da_função([arg1, arg2, ..., argn]) { Comandos; [return <valor de retorno>]; } Qualquer código PHP válido pode estar contido no interior de uma função. Como a checagem de tipos em PHP é dinâmica, o tipo de retorno não deve ser declarado, sendo necessário que o programador esteja atento para que a função retorne o tipo desejado. É recomendável que esteja tudo bem documentado para facilitar a leitura e compreensão do código. Para efeito de documentação, utiliza-se o seguinte formato de declaração de função: tipo function nome_da_funcao(tipo arg1, tipo arg2, ...); Este formato só deve ser utilizado na documentação do script, pois o PHP não aceita a declaração de tipos. Isso significa que em muitos casos o programador deve estar atento aos tipos dos valores passados como parâmetros, pois se não for passado o tipo esperado não é emitido nenhum alerta pelo interpretador PHP, já que este não testa os tipos. As regras para nomeação de funções seguem os mesmos princípios das regras para nomeação de variáveis. Assim sendo, não podem começar com algum algarismo e não podem conter pontos, espaços, vírgulas, etc. 7.2 - Valor de Retorno Toda função pode opcionalmente retornar um valor, ou simplesmente executar os comandos e não retornar valor algum. Não é possível que uma função retorne mais de um valor, mas é permitido fazer com que uma função retorne um valor composto, como listas ou arrays. Observe o exemplo abaixo: function calcula_area($raio) { // função que calcula a área de um círculo dado o valor do raio return 2 * 3.14 * $raio; } $area = calcula_area(5); echo $area; // a variável $area recebe o valor 31.4 (double) 7.3 - Argumentos É possível passar argumentos para uma função. Eles devem ser declarados logo após o nome da função, entre parênteses, e tornam-se variáveis pertencentes ao escopo local da função. A declaração do tipo de cada argumento também é utilizada apenas para efeito de documentação. Segue abaixo um exemplo de função com passagem de parâmetros: function imprime($texto) { echo $texto . $texto; } imprime("PHP"); // resulta na saída na tela de "PHPPHP" 7.4 - Passagem de Parâmetros por Referência Normalmente, a passagem de parâmetros em PHP é feita por valor, ou seja, se o conteúdo da variável for alterado, essa alteração não afeta a variável original. Exemplo: function mais5($numero) { $numero += 5; } $a = 3; mais5($a); //$a continua valendo 3 No exemplo acima, como a passagem de parâmetros é por valor, a função mais5 é inútil, já que após a execução sair da função o valor anterior da variável é recuperado. Se a passagem de parâmetros fosse feita por referência, a variável $a teria 8 como valor. O que ocorre normalmente é que ao ser chamada uma função, o interpretador salva todo o escopo atual, ou seja, os conteúdos das variáveis. Se uma dessas variáveis for passada como parâmetro, seu conteúdo fica preservado, pois a função irá trabalhar na verdade com uma cópia da variável. Porém, se a passagem de parâmetros for feita por referência, toda alteração que a função realizar no valor passado como parâmetro afetará a variável que o contém. Há duas maneiras de fazer com que uma função tenha parâmetros passados por referência: indicando isso na declaração da função, o que faz com que a passagem de parâmetros sempre seja assim; e também na própria chamada da função. Nos dois casos utiliza-se o modificador "&". Vejamos um exemplo que ilustra os dois casos: function mais5(&$num1, $num2) { } $num1 += 5; $num2 += 5; $a = $b = 1; mais5($a, $b); mais5($a, &$b); /* Neste caso, só $a terá seu valor alterado, pois a passagem por referência está definida na declaração da função. */ /*As duas variáveis terão seus valores alterados, uma vez que a passagem por referência é feita na chamada da função*/ Assim sendo, após a 1ª chamada da função mais5, as variáveis $a e $b possuem os valores 6 e 1, respectivamente. Após a 2ª chamada, as variáveis $a e $b possuem os valores 11 e 6, respectivamente. 7.5 - Argumentos com Valores Pré-Definidos (Default) Em PHP é possível ter valores default para argumentos de funções, ou seja, valores que serão assumidos em caso de nada ser passado no lugar do argumento. Quando algum parâmetro é declarado desta maneira, a passagem do mesmo na chamada da função torna-se opcional. Observe o exemplo abaixo: function duplica($valor = 5) { echo $valor * 2; } duplica(); duplica(8); // imprime "10" // imprime "16" É importante lembrar que quando a função tem mais de um parâmetro, o parâmetro que tiver valor default deve ser declarado por último. Observe o caso abaixo: function teste($figura = "circulo", $cor) { echo "A figura é um " . $figura . " de cor " . $cor; } teste(azul); Essa função não vai funcionar da maneira esperada (ocorrendo um erro no interpretador), uma vez que o parâmetro com valor default foi declarado inicialmente. A declaração correta para essa função está apresentada a seguir: function teste2($cor, $figura = "circulo") { echo "A figura é um " . $figura . " de cor " . $cor; } teste2('azul'); Aqui a função funciona da maneira esperada, ou seja, imprime o texto: "A figura é um circulo de cor azul" 7.6 - Contexto O contexto é o conjunto de variáveis e seus respectivos valores num determinado ponto do programa. Na chamada de uma função, ao iniciar a execução do bloco que contém a implementação da mesma é criado um novo contexto, contendo as variáveis declaradas dentro do bloco, ou seja, todas as variáveis utilizadas dentro daquele bloco serão eliminadas ao término da execução da função. 7.7 - Escopo O escopo de uma variável em PHP define a porção do programa onde ela pode ser utilizada. Na maioria dos casos todas as variáveis têm escopo global. Entretanto, em funções definidas pelo usuário um escopo local é criado. Uma variável de escopo global não pode ser utilizada no interior de uma função sem que haja uma declaração. Exemplo: $php = "aba"; function imprime() { echo $php . $php; } imprime(); O trecho acima não produzirá saída alguma, pois a variável $php é de escopo global, e não pode ser referida num escopo local, mesmo que não haja outra com nome igual que cubra a sua visibilidade. Para que o script funcione da forma desejada, a variável global a ser utilizada deve ser declarada. Exemplo: $php = "aba"; function imprime() { global $php; echo $php . $php; } imprime(); // resulta na saída "abaaba" Uma declaração "global" pode conter várias variáveis, separadas por vírgulas. Uma outra maneira de acessar variáveis de escopo global dentro de uma função é utilizando um array pré-definido pelo PHP cujo nome é $GLOBALS. O índice para a variável referida é o próprio nome da variável, sem o caracter $. O exemplo acima e o abaixo produzem o mesmo resultado. Exemplo: $php = "aba"; function imprime() { echo $GLOBALS["php"] . $GLOBALS["php"]; echo $php; } imprime(); // imprime "abaaba" // não imprime nada 7.8 - Funções Recursivas Recursividade é uma técnica utilizada em programação para que uma função chame a si mesma. Toda função recursiva, portanto, deve possuir uma determinada condição de parada para que a execução do script não entre em um loop infinito. Assim sendo, observe o exemplo abaixo: function fatorial($numero) { if ($numero == 1) return 1; else return $numero * fatorial($numero - 1); } $valor_fatorial = fatorial(5); echo $valor_fatorial; // imprime 120 (= 5!) Observe que a função fatorial é uma função recursiva pois existe uma chamada para ela mesma dentro de seu bloco de código. Além disso, existe uma condição de parada (se a variável $numero for igual a 1). Se a condição não for satisfeita, a função retorna o valor do número multiplicado pelo número retornado pela chamada a função fatorial com o valor da variável $numero - 1. Funções recursivas utilizam-se de estruturas de dados tais como pilhas, que servem para guardar o contexto de cada momento em que a nova função é chamada. No exemplo acima, o processo de execucação do script se daria da seguinte forma: $valor_fatorial $valor_fatorial $valor_fatorial $valor_fatorial $valor_fatorial $valor_fatorial $valor_fatorial $valor_fatorial $valor_fatorial $valor_fatorial = = = = = = = = = = fatorial(5) 5 * fatorial(4) 5 * 4 * fatorial(3) 5 * 4 * 3 * fatorial(2) 5 * 4 * 3 * 2 * fatorial(1) 5*4*3*2*1 5*4*3*2 5*4*6 5 * 24 120 8. Variáveis 8.1 - O modificador Static Uma variável estática é visível num escopo local, mas ela é inicializada apenas uma vez e seu valor não é perdido quando a execução do script deixa esse escopo. Veja o seguinte exemplo: function conta_vezes() { $vezes = 0; echo $vezes; $vezes++; } O último comando da função é inútil, pois assim que for encerrada a execução da função a variável $vezes perde seu valor. Já no exemplo seguinte, a cada chamada da função a variável $vezes terá seu valor impresso e será incrementada: function conta_vezes2() { } static $vezes = 0; echo $vezes; $vezes++; O modificador static é muito utilizado em funções recursivas, já que o valor de algumas variáveis precisa ser mantido. Ele funciona da seguinte forma: O valor das variáveis declaradas como estáticas é mantido ao terminar a execução da função. Na próxima execução da função, ao encontrar novamente a declaração com static, o valor da variável é recuperado. Em outras palavras, uma variável declarada como static tem o mesmo "tempo de vida" que uma variável global, porém sua visibilidade é restrita ao escopo local em que foi declarada e só é recuperada após a declaração. Exemplo: function conta_vezes3() { echo $vezes; static $vezes = 0; $vezes++; } O exemplo acima não produzirá saída alguma. Na primeira execução da função, a impressão ocorre antes da atribuição de um valor à variável e, portanto, o conteúdo de $vezes é nulo (string vazia). Nas execuções seguintes da função conta_vezes3 a impressão ocorre antes da recuperação do valor de $vezes e, portanto, nesse momento, seu valor ainda é nulo. 8.2 - Variáveis Variáveis O PHP tem um recurso conhecido como variáveis variáveis, que consiste em variáveis cujos nomes também são variáveis. Sua utilização é feita através do duplo cifrão ($$). Veja como utilizar esse recurso através do exemplo a seguir. $jogo = "Half_Life2"; $$jogo = "Jogo perfeito"; O código apresentado acima é equivalente ao seguinte: $jogo = "Half_Life2"; $Half_Life2 = "Jogo perfeito"; A utilização de variáveis variá veis pode parecer, em um primeiro momento, obscura. Porém, ela possui aplicações muito necessárias a fim de 'simplificar' o código. É o caso de dados recebidos através de um formulário, por exemplo. Suponha que você esteja realizando um website, o qual apresenta um conjunto de questões de escolha entre alternativas (A, B e C por exemplo). Existem 20 questões diferentes com 3 alternativas para cada uma. Suponha também que você deseje descobrir quantas respostas foram dadas para cada uma das alternativas A, B e C. No programa que receberá os dados enviados pelo formulário (as 20 respostas), você não precisará realizar testes para cada resposta, a fim de descobrir qual alternativa foi escolhida. Essa má forma de programação é demonstrada abaixo: if ($resp1 == 'A') $A++; else if ($resp1 == 'B') $B++; else if ($resp1 == 'C') $C++; No exemplo acima, é suposto que as variáveis $A, $B e $C contém o número de respostas A, B e C, respectivamente. Além disso, $resp1 é o dado enviado pelo formulário referente a resposta da questão 1. Como o questionário contém 20 questões, você precisaria realizar 20 vezes os testes similares ao apresentado acima, dificultando a manutenção do código e a simplicidade. Em solução a esse problema, surgem as variáveis variáveis. Observe o código simplificado abaixo, que realiza a mesma coisa que o código anterior: $$resp1++; Simples e eficiente. Note que, caso a variável $resp1 contenha, por exemplo, o valor 'A', a variável $A será incrementada. Caso a variável $resp1 contenha o valor 'B', então a variável $B é que será incrementada. O mesmo se dá para o caso da variável conter o valor 'C'. Dessa forma, eliminamos os testes e aumentamos a simplicidade de nosso código. 8.3 - URLencode O formato URLencode é obtido substituindo os espaços pelo caracter "+" e todos os outros caracteres não alfa-numéricos (com exceção de "_") pelo caracter "%" seguido do código ASCII em hexadecimal. Exemplo: o texto "Testando 1 2 3 !!" em urlencode fica: "Testando+1+2+3+%21%21". 8.4 - Variáveis Enviadas pelo Navegador Para interagir com a navegação feita pelo usuário, é necessário que o PHP possa enviar e receber informações para o software de navegação. A maneira de enviar informações, como já foi visto anteriormente, geralmente é através de um comando de impressão, como o echo. Para receber informações vindas do navegador através de um link ou um formulário html o PHP utiliza as informações enviadas através da URL. Veremos com mais detalhes na sessão formulários. Exemplo: se seu script php está localizado em "http://localhost/teste.php3" e você o chama com a url "http://localhost/teste.php3?php=teste", o PHP, automaticamente, armazenará na variável superglobal $_GET no índice 'php' a string "teste". Note que o conteúdo da variável está no formato urlencode. Os formulários html já enviam informações automaticamente nesse formato, e o PHP decodifica sem necessitar de tratamento pelo programador. 8.5 - Variáveis de ambiente Embora possam ser usadas nos programas PHP, elas são variáveis pertencentes ao ambiente do servidor Web e não da linguagem PHP. Algumas dessas variáveis contém informações sobre o navegador do usuário, o servidor http, a versão do PHP e diversas outras informações. Para se ter uma listagem de todas as variáveis e constantes de ambiente e seus respectivos conteúdos, deve-se utilizar a função phpinfo(). Para se obter o valor das variáveis de ambiente, utilizamos a função gentev do PHP. Sua sintaxe é a seguinte: getenv("nome da variável"); Uma das mais importantes variáveis de ambiente é a que guarda o endereço IP do visitante, uma vez que a necessidade para um controle de acesso e segurança aos sites tem aumentado consideravelmente nos últimos anos. Cada máquina conectada a Internet possui um endereçp IP que a identifica na rede. Assim sendo, quando o usuário acessar o site e o código PHP for executado pelo servidor, poderá se descobrir o IP desse usuário da seguinte forma: $ip = getenv("REMOTE_ADDR"); Observa-se que a variável de ambiente REMOTE_ADDR é a variável que contém o endereço IP do visitante que solicitou a página. A seguir, apresentamos uma tabela com algumas das variáveis de ambiente disponíveis para um programa PHP: Variável de Ambiente SERVER_NAME Descrição Nome do Servidor REQUEST_METHOD Método de envio de dados utilizado (GET,POST) QUERY_STRING Armazena tudo o que vem após o ? em uma URL REMOTE_ADDR Endereço IP do visitante Variável de Ambiente Descrição REMOTE_USER Nome do usuário REMOTE_HOST Nome do host de onde veio a requisição HTTP_USER_AGENT Nome e versão do browser utilizado pelo cliente 8.6 - Verificando o Tipo de uma Variável Por causa da tipagem dinâmica utilizada pelo PHP, nem sempre é possível saber qual o tipo de uma variável em determinado instante sem contar com a ajuda de algumas funções que ajudam a verificar isso. A verificação pode ser feita de duas maneiras: 8.6.1 - Função que Retorna o Tipo da Variável Esta função é a gettype. Sua assinatura é a seguinte: gettype($nome_da_variável); A função gettype pode retornar as seguintes strings: "integer", "double", "string", "array", "object" e "unknown type". Exemplo: $valor = 3.5; $tipo = gettype($valor); echo $tipo; // resulta na saída "double" 8.6.2 - Funções que Testam o Tipo da Variável São as funções is_int, is_integer, is_real, is_long, is_float, is_string, is_array e is_object. Todas têm o mesmo formato, seguindo o modelo da assinatura a seguir: is_integer($nome_da_variável); Todas essas funções retornam true se a variável for daquele tipo, e false em caso contrário. Observe o exemplo a seguir: $variavel = "Meu Deus do Céu"; if (is_string($variavel)) echo "A afirmação de que a variável \$variavel é uma string é verdadeira"; else echo "A afirmação de que a variável \$variavel é uma string é falsa"; 8.7 - Destruindo uma Variável É possível desalocar uma variável se ela não for usada posteriormente através da função unset, que tem a seguinte assinatura: unset($nome_da_variável); A função destrói a variável, ou seja, libera a memória ocupada por ela, fazendo com que ela deixe de existir. Se mais a frente no código for feita uma chamada á variável, será criada uma nova variável de mesmo nome e de conteúdo vazio. 8.8 - Verificando se uma Variável Possui um Valor Existem dois tipos de teste que podem ser feitos para verificar se uma variável está setada: com a função isset e com a função empty. 8.8.1 - A Função Isset Essa função possui o seguinte protótipo: isset($nome_da_variável); Ela retorna true se a variável estiver setada (ainda que com uma string vazia ou o valor zero), e false em caso contrário. 8.8.2 - A Função Empty Essa função possui o seguinte protótipo: empty($nome_da_variável); Ela retorna true se a variável não contiver um valor (não estiver setada) ou possuir valor 0 (zero) ou uma string vazia. Caso contrário, retorna false. 8.9 - Arrays Multidimensionais Arrays multidimensionais são arrays simples com um dos (ou todos) seus elementos sendo outro array e assim consecutivamente. Exemplo: $Campeao[5] = 123456789 ; $Campeao[9] = "O Veloz"; $Tricampeao["casa"] = $Campeao; $Tricampeao["predio"] = 19191919; $Tricampeao["fazenda"] = 657; $Brasil[1] = $Tricampeao; $Brasil[2] = "Bicampeao"; $Brasil["copa"] = $Tricampeao; $Brasil[4] = "Tetracampeao"; $Brasil["mundo"] = "Pentacampeao"; echo echo echo echo $Campeao[5]; $Brasil[1]["casa"][5] ; $Tricampeao["casa"][5]; $Brasil["copa"]["predio"]; // // // // resultará resultará resultará resultará 123456789 123456789 123456789 19191919 Array Array Array Array simples tridimensional bidimensional bidimensional 9 - Includes Include é uma função do PHP que permite a inclusão do conteúdo de um outro arquivo no arquivo PHP atual, permitindo-se o reaproveitamento de uma ou mais funções ou arquivos. Uma grande utilização de includes, por exemplo, é quando precisamos realizar uma alteração que será refletida em todas as páginas do site automaticamente. Para isso, é muito mais útil alterar apenas um arquivo do que alterar os arquivos de todas as páginas. Dentro de includes podemos também definir funções e essas funções estarão disponíveis para todos os arquivos que chamarem essas includes. Observe o caso abaixo onde apresenta-se a forma de utilização sintática de uma include: funcoes.inc : <? function dobra_valor($numero) { // funcao que retorna o dobro do valor return 2*$numero; } function triplica_valor($numero) { // funcao que retorna o triplo do valor return 3*$numero; } ?> programa_principal.php : <? include("funcoes.inc"); $a = dobra_valor(5); // chama a função contida na include funcoes.inc $b = triplica_valor(3); // chama a função contida na include funcoes.inc echo $a * $b; // imprime 90 ?> 9.1 - Include x Require Além do comando include existe o comando require, que realiza a mesma função, porém com uma pequena diferença em relação a manipulação de erros. Caso o arquivo a ser incluído não exista, ambos os comandos produzem um Warning. Porém, o comando require emitirá, também, um Fatal Error, parando o processamento do script. É importante a sua utilização para a obrigação de término de processamento caso o arquivo informado não exista. O comando include, em oposto, continua a execução do script, existindo o arquivo ou não. Você pode incluir diversos arquivos através de um array de 'includes'. Dessa forma, caso você deseje incluir diversos arquivos dentro de um programa PHP e não queira escrever o comando include para cada um dos arquivos, poderá incluí-los através de um array como demonstrado abaixo: $inclusao = array("arquivo1.inc", "arquivo2.inc", "arquivo3.inc"); for ($i=0;$i < count($inclusao);$i++) include($inclusao[$i]); No código acima, a função count($inclusao) informa quantos elementos existem no array $inclusao. Os 3 arquivos cujos nomes estão colocados no array $inclusão não podem ser incluídos pelo comando require, uma vez que esse comando apenas pode incluir um arquivo. Observe este outro exemplo: if ($x > $y) { include("arquivo1.inc"); } else { include("arquivo2.inc"); } É importante observar que quando a função include é utilizada dentro de estruturas como o if, é obrigatória a utilização das chaves. 10 - Formulários Formulários são formas bastante comuns de adquirir dados preenchidos por usuários para a obtenção de determinadas informações em sites. Esses formulários são criados através da linguagem HTML, a qual foi vista anteriormente no curso. 10.1 - A Opção Action Quando criamos um formulário, é necessário criar, geralmente, um botão para enviar as informações contidas nele. Quando o usuário clicar nesse botão, as informações não serão enviadas para nenhum lugar, pois o navegador não sabe para onde enviá-las. Assim sendo, é necessário passar as informações para um programa PHP especificado pela opção action da tag form. Observe o exemplo abaixo, onde mostra-se um formulário e seu devido código fonte: <form action= "prog_recebe.php"> Nome: <input type= "text" name= "nome" size = "50"><p> Idade: <input type= "text" name= "idade" size= "3"><p> <input type= "submit" value= "Enviar" name= "enviar"> </form> Observa-se que quando o usuário clicar no botão "Enviar", os dados referentes aos campos "Nome" e "Idade" serão enviados ao programa prog_recebe.php e esse programa tratará as informações recebidas. Posteriormente veremos exemplos para tratamento de informações recebidas de formulários. 10.2 - Envio de Informações ao Programa PHP Embora saibamos especificar qual programa PHP receberá os dados do formulário, temos de especificar como esses dados serão passados ao programa. Para isso, existem dois métodos de passagem de parâmetros, o GET e o POST. Em formulários, para especificar o método de passagem, utilizamos a opção method da tag form. Caso desejássemos mandar os dados do exemplo anterior para o programa prog_recebe.php através do método POST, o código seria realizado da seguinte forma: <form action = "prog_recebe.php" method= "POST"> 10.2.1 - O Método GET Método padrão para o envio de dados. Se nenhum método for especificado na tag form, estamos utilizando o GET como default. Nesse método, os dados são enviados com o nome da página. Os campos do formulário são passados como parâmetros após o endereço destino. O caracter '?' representa o início de uma cadeia de variáveis e o símbolo '&' identifica o início de uma nova variável. As variáveis e seus respectivos valores são separados pelo caractere '='. Caso os dados do formulário do exemplo anterior fossem passados para o programa prog_recebe.php, o método utilizado fosse o GET, e os dados para o Nome e o Idade fossem "Ismael" e "19", respectivamente, teríamos o seguinte endereço ativado ao clique do botão "Enviar": http://www.seusite.com.br/prog_recebe.php?nome=Ismael&idade=19 O método GET possui algumas inconveniências, uma vez que existe um limite de caracteres que podem ser enviados (em torno de 2000) e o usuário poderá enxergar todos os parâmetros por meio da barra de endereços do navegador. Para solucionar isso, existe o método POST. 10.2.2 - O Método POST Nesse método, os dados são enviados por meio do corpo da mensagem encaminhada ao servidor. No caso do exemplo anterior, utilizando o método POST, quando o usuário clicar no botão "Enviar" o endereço ativado é apenas o especificado na opção action, sem nenhum dado adicionado após o endereço-destino. Além disso, não existe limitação de tamanho para os dados que serão enviados pelo formulário e pode-se enviar outros tipos de dados que não podem ser passados pelo método GET, como imagens. 10.3 - Tratamento das Informações Recebidas Além de especificar o programa a tratar as informações passadas por um formulário e definir o método de transferência de dados, é necessário conhecer as formas de acessar esses dados recebidos e trabalhar com eles dentro do programa PHP. Primeiramente, pode-se tratar esses dados como variáveis, colocando o símbolo '$' seguido do próprio nome do campo definido no formulário. No caso do exemplo de formulário criado anteriormente, poderíamos tratar os dados através das variáveis $nome e $idade. Veja um exemplo trivial de prog_recebe.php: <? if ($nome == "" || $idade == "") echo "Você não digitou todas as informações necessárias"; ?> Outra forma de tratar os dados recebidos é utilizando os arrays $_GET e $_POST, definidos pelo PHP, para armazenar os dados enviados pelos métodos GET e POST, respectivamente. Assim sendo, os nomes dos campos do formulário são usado como chaves para o array e os valores dos campos são armazenados como valores desse array. Veja o exemplo abaixo de um programa que recebe os dados do formulário mostrado anteriormente através do método POST: <? if ($_POST["idade"] > 18) echo "Você é maior de idade. Já pode dirigir."; ?> É importante observar que as variáveis $_GET e $_POST são variáveis superglobais, estando disponíveis em todos os escopos (níveis) de um script. Assim sendo, você não precisa colocar um global $Nome_da_Variavel para poder acessá-la dentro de funções ou métodos, como é necessário para as demais funções globais. 10.4 - Funções para Formatação de Dados Existem algumas funções úteis para a formatação dos dados recebidos por um programa. Algumas delas serão mostradas a seguir: 10.4.1 - HTMLspecialchars Essa função transforma os comandos HTML, fazendo com que estes sejam exibidos na tela como texto comum. Sua sintaxe é a seguinte: htmlspecialchars(<string>); Essa função retira as tags HTML e coloca caracteres especiais em seus lugares. As mudanças feitas são as seguintes: & é substituído por & " é substituído por " < é substituído por < > é substituído por > Observe o exemplo abaixo: <? $texto = "<b>Este texto era para aparecer em negrito</b>"; $texto2 = htmlspecialchars($texto); echo $texto . "<br>"; echo $texto2; ?> O resultado esperado para o código acima é o seguinte: Este texto era para aparecer em negrito <b>Este texto era para aparecer em negrito</b> Nota-se que após os caracteres '>' e '<' serem transformados em > e < pela função htmlspecialchars, o navegador leu esses códigos e apresentou na tela novamente os símbolos '>' e '<', mas não os executou como se fossem parte do código HTML. 10.4.2 - Stripslashes Um ponto importante ainda não discutido no processo de transferência de dados do formulário para o programa PHP é a existência de dados que contém caracteres especiais. No exemplo do formulário utilizado anteriormente, suponhamos que o usuário digite no campo 'Nome' o valor: Pedro Alvares Cabral, o "descobridor" do Brasil Na verdade, o valor recebido pelo PHP será: Pedro Alvares Cabral, o \" descobridor do \" Brasil Nota-se que o PHP coloca o caracter de controle '\' antes de caracteres especiais para evitar um erro de leitura nas variáveis. Existe uma função que retira esses caracteres de controle, a qual é chamada de stripslashes. Sua sintaxe é a seguinte: stripslashes(<string>) Observe o exemplo abaixo de um programa que recebe os dados acima mencionados do formulário: <? $nome_usuario = $_POST["Nome"]; $nome_usuario2 = stripslashes($nome_usuario); echo $nome_usuario . "<br>"; // imprime Pedro Alvares Cabral, o "descobridor do Brasil" ?> Observe que a retirada do caracter de controle impede que se possa imprimir o conteúdo da variável $nome_usuario2. 10.5 - Selecionando Código HTML É possível através de código PHP selecionarmos trechos de código HTML a serem mostrados na página. Por exemplo, podemos ter o formulário abaixo: <html> <head><title>Exemplo</title></head> <body> <? if (!$_POST['enviar']) { ?> <form action="<?= $_SERVER['PHP_SELF'] ?>" method="post"> Nome: <input type="text" name="nome"> <input type="submit" name="enviar" value="Enviar"> </form> <? } else { echo ("Seu nome é ".$_POST['nome']); } ?> </body> </html> No exemplo acima, veja que a ação do formulário está definida pela v ariável $_SERVER['PHP_SELF'] do PHP. Assim, é a própria página que tratará os dados do formulário enviados pelo usuário. Nesse exemplo, é possível ver a seleção que podemos fazer no próprio código HTML com o condicional "if" do PHP. O formulário apenas será mostrado se o usuário não tiver clicado no botão "Enviar". Depois de clicar apenas será mostrado o seguinte texto: Seu Nome é Nome_do_Usuário 11 - Manipulação de Arquivos Remotos Embora a utilização de um banco de dados seje amplamente difundido atualmente, o PHP permite a manipulação de arquivos de formato conhecido, evitando a necessidade da existência de um SGBD (Sistema de Gerência de Banco de Dados) instalado no servidor. Dessa forma, arquivos de texto comuns podem ser criados e editados para guardar pequenas quantidades de informações que são necessárias em certos casos, quando da criação de websites. Para manipular esses arquivos, o PHP fornece uma grande quantidade de funções que atuam diretamente no sistema de arquivos do sistema operacional. Veremos as principais a seguir. •1 - Fopen A função fopen é responsável pela abertura de um arquivo. Sua sintaxe é a seguinte: fopen (nome_arquivo, modo, [use_include_path]) Essa função retorna um ponteiro para o arquivo aberto, sendo usado futuramente como parâmetro para as demais funções de manipulação de arquivos. Além disso, pode-se usar um teste através do comando if, por exemplo, para verificar se o arquivo foi, de fato, aberto. Observa-se que o parâmetro nome_arquivo pode referenciar um arquivo que está no mesmo computador ou em um computador remoto. Já o parâmetro modo pode possuir os valores listados na tabela abaixo: Modo Descrição 'r' Abre somente para leitura * 'r+' Abre para leitura e escrita * 'w' Abre somente para escrita. Tamanho do arquivo: 0. Se arquivo não existir, será criado. * 'w+' Abre para leitura e escrita. Tamanho do arquivo: 0. Se arquivo não existir, será criado. * 'a' Abre somente para escrita. Se arquivo não existir, será criado. ** 'a+' Abre para leitura e escrita. Se arquivo não existir, será criado. ** * : Posiciona o ponteiro no início do arquivo ** : Posiciona o ponteiro no final do arquivo Existe ainda um terceiro parâmetro para essa função. Esse parâmetro indica se o arquivo deve ser procurado no caminho existente em uma variável chamada include_path. Para ativá-lo, passamos o valor 1. Observe o exemplo abaixo: $ponteiro_arquivo = fopen("http://www.inf.ufrgs.br/~seunome/teste.txt", "r"); 11.2 - Fclose A função fclose é responsável pelo fechamento de um arquivo. Sua sintaxe é a seguinte: fclose (ponteiro_arquivo) Essa função retorna true se o arquivo foi fechado com sucesso e false se houver alguma falha. O parâmetro utilizado para essa função é a variável na qual está contida o ponteiro para o arquivo desejado. Exemplo: fclose($ponteiro_arquivo); 11.3 - Fread A função fread é responsável pela leitura de um arquivo. Sua sintaxe é a seguinte: fread (ponteiro_arquivo, tamanho) Lê o número de bytes especificado em tamanho. A leitura termina quando o número de bytes especificado é lido ou o fim do arquivo (EOF) é alcançado. Exemplo: $texto = fread($ponteiro_arquivo, 256); // Lê 256 bytes do arquivo 11.4 - Fgets A função fgets também é responsável pela leitura de um arquivo, porém ela lê no máximo uma linha. É bastante utilizada quando queremos trabalhar individualmente com cada linha do arquivo. Sua sintaxe é a seguinte: fgets (ponteiro_arquivo, tamanho) Exemplo: $linha = fgets($ponteiro_arquivo,4096); 11.5 - Fwrite Essa função realiza a escrita em um arquivo. Sua sintaxe é a seguinte: fwrite (ponteiro_arquivo, string, [tamanho]) Observa-se que fwrite escreve o conteúdo do parâmetro string no arquivo referenciado pelo parâmetro ponteiro_arquivo. O uso de tamanho é opcional. Caso ele seja informado, a escrita cessará após ser atingido o número de bytes especificado. O exemplo abaixo reúne todos os conceitos das funções vistas até agora em um programa PHP, implementando um contador (útil para verificar o número de visitantes): <? $arquivo = "contador.txt"; $ponteiro_arquivo = fopen($arquivo,"r"); $valor = chop(fgets($ponteiro_arquivo,4096)); fclose($ponteiro_arquivo); $valor++; echo "$valor pessoas já visitaram esse site"; $ponteiro_arquivo = fopen($arquivo,"w"); fwrite($ponteiro_arquivo, "$valor"); fclose($ponteiro_arquivo); // abre o arquivo // obtém o valor atual // fecha o arquivo // incrementa o contador // abre o arquivo para escrita // salva o novo valor // fecha o arquivo ?> No exemplo acima, a função chop tem como meta remover os espaços e quebras de linha existentes no fim de uma string. Nota-se que o exemplo de código acima poderia ser utilizado como uma include, onde seria chamado na devida parte onde se desejasse mostrar a quantidade de usuários que visitou o website. Devido ao grande número existente de funções para a manipulação de arquivos, omitiremos as restantes. A documentação dessas funções, porém, pode ser facilmente encontrada na Web. 12 - Programação Orientada a Objetos A programação orientada a objetos é muito comum atualmente em diversas linguagens de programação, uma vez que reorganiza a forma de programar de modo a fazer com que partes associadas de código e dados sejam agrupados. 12.1 - Classes Uma classe é um conjunto de variáveis e funções relacionadas a essas variáveis. Uma vantagem da utilização de classes é poder usufruir do recurso de encapsulamento de informação. Com o encapsulamento, o usuário de uma classe não precisa saber como ela é implementada, bastando para a utilização conhecer a interface, ou seja, as funções disponíveis. Uma classe é um tipo e, portanto, não pode ser atribuída a uma variável. Para definir uma classe, deve-se utilizar a seguinte sintaxe: class Nome_da_classe [extends myparent] { var $variavel1; var $variavel2; function funcao1 ($parâmetro) { // === corpo da função === ... } ... } Nota-se que define-se uma classe através de um certo nome escolhido pelo programador. Dentro dessa classe, pode-se definir variáveis e funções que estão relacionadas entre si. Uma classe pode ser uma extensão de outra. Isso significa que ela herdará todas as variáveis e funções da outra classe, e ainda terá as que forem adicionadas pelo programador. Em PHP não é permitido utilizar herança múltipla, ou seja, uma classe pode ser extensão de apenas uma outra. Para criar uma classe extendida, ou derivada de outra, deve ser utilizada a palavra reservada extends, como pode ser visto no exemplo seguinte: class novaconta extends conta { var $numero; function numero() { ... } } A classe acima é derivada da classe conta, tendo as mesmas funções e variáveis, com a adição da variável $numero e a função numero. 12.2 - Objetos Variáveis do tipo de uma classe são chamadas de objetos e devem ser criadas utilizando o operador new, como mostra o exemplo abaixo: $variável = new $nome_da_classe; Para utilizar as funções definidas na classe, deve ser utilizado o operador "->", como mostra o exemplo abaixo: $variável->funcao1(); 12.3 - A Variável $this Na definição de uma classe, pode-se utilizar a variável $this, que é o próprio objeto. Assim, quando uma classe é instanciada em um objeto, e uma função desse objeto na definição da classe utiliza a variável $this, essa variável significa o objeto que estamos utilizando. Como exemplo da utilização de classes e objetos, podemos utilizar a classe conta, que define uma conta bancária bastante simples, com funções para ver saldo e fazer um crédito. class conta { var $saldo=0; function saldo() { return $this->saldo; } function credito($valor) { $this->saldo += $valor; } } $minhaconta = new conta; echo $minhaconta->saldo(); $minhaconta->credito(50); echo $minhaconta->saldo(); // imprime 0 // imprime 50 12.4 - Construtores Um construtor é uma função definida na classe que é automaticamente chamada no momento em que a classe é instanciada (através do operador new). O construtor deve ter o mesmo nome da classe a que pertence. Veja o exemplo: class conta { var $saldo; function conta ($valor) { $this->saldo = $valor; } function saldo() { return $this->saldo; } function credito($valor) { $this->saldo += $valor; } } Podemos perceber que a classe conta agora possui um construtor, que inicializa a variável $saldo com o valor contido no parâmetro $valor. Um construtor pode conter argumentos, o que torna esta ferramenta mais poderosa. No exemplo acima, o construtor da classe conta recebe como argumento um valor, que seria o valor inicial da conta. Observe o exemplo abaixo de instanciação de uma classe: $minhaconta = new conta(50); Dessa forma, passa-se como argumento para o construtor o valor 50, inicializando a variável $saldo do objeto com esse valor. Vale observar que para classes derivadas, o construtor da classe pai não é automaticamente herdado quando o construtor da classe derivada é chamado. 13 - Tratamento de erros Existem quatro tipos (até a versão 4.0) de erros no PHP para indicar a gravidade do erro encontrado ou ocorrido. Eles são: 1. 2. 3. 4. Erros de funções (function errors) Avisos (warnings) Erros de processamento (parser error) Observações (notice) As mensagens de erro são um item a quem os programadores devem prestar muita atenção, afinal nenhum programador gostaria de colocar no ar um sistema que mostre uma mensagem de erro na primeira visita de um usuário. Para evitar essas inconveniências, usa-se sempre "@" antes da cada chamada das funções. Se a opção track_errors no arquivo php.ini estiver habilitada, a mensagem de erro poderá ser encontrada na variável global $php_errormsg. A chamada da função ficaria assim: @strtolower(); Essa função deixaria todos os caracteres em minúsculo, mas como não foi passado nenhum argumento essa função deveria exibir uma mensagem de erro. 14 - Bancos de Dados Um banco de dados é um conjunto de dados integrados que tem por objetivo atender a uma comunidade de usuários. No caso de websites, bancos de dados podem ser utilizados para guardar informações de formulários preenchidos por usuários, de 'logins' e 'passwords' num sistema de controle de acesso, de produtos a venda de uma empresa, etc. •1 - Conceitos Básicos Para compreendermos o funcionamento de um banco de dados, temos de ter em mente alguns conceitos básicos listados a seguir: * Sistema de Gerência de Banco de Dados (SGBD): É um software que incorpora as funções de definição, recuperação e alteração de dados em um banco de dados. Em nosso curso, utilizaremos o MySQL. * Modelos Relacional de Bancos de Dados: É uma descrição dos tipos de dados que estão armazenados em um banco de dados baseada no princípio de que todos os dados estão guardados em tabelas. Assim sendo, os bancos de dados são formados por tabelas que podem se relacionar ou não. Chamaremos esses bancos de dados de relacionais. * Tabelas: Uma tabela é um conjunto não ordenado de linhas (ou tuplas). Cada linha é composta por uma série de campos (ou valor de atributo). Observe o exemplo abaixo da tabela Empregado, a qual possui 4 linhas. Cada uma das linhas possui 3 campos: 'CodigoEmp', 'Nome' e 'CodigoDepartamento'. Empregado CodigoEmp Nome CodigoDepartamento E1 João D2 E2 Pedro D3 E3 José D2 E4 Pedro D1 * Chave Primária: Uma chave primária é uma coluna ou uma combinação de colunas cujos valores distinguem uma linha das demais dentro de uma tabela. Na tabela Empregado, a chave primária é a coluna CodigoEmp. Assim sendo, nenhum empregado pode ter o mesmo valor em CodigoEmp que outro. Nota-se que nada restringe os valores contidos na coluna Nome, permitindo que existam dois empregados com o mesmo valor, no caso, Pedro. Observa-se também que uma chave primária não pode nunca ser nula. * Chave estrangeira: Uma chave estrangeira é uma coluna ou uma combinação de colunas, cujos valores aparecem necessariamente na chave primária de uma tabela. Na verdade, uma chave estrangeira é o mecanismo que permite a implementação de 'relacionamentos' em um banco de dados relacional. Observe o exemplo abaixo da tabela Departamento que está contida no mesmo banco de dados da tabela Empregado: Departamento CodigoDepartamento Nome D1 Compras D2 Engenharia D3 Vendas No exemplo, a coluna CodigoDepartamento é a chave primária da tabela Departamento. Pode-se dizer, então, que a coluna CodigoDepartamento da tabela Empregado é chave estrangeira em realção a chave primária da tabela Departamento. * Chave alternativa: Muitas vezes, mais de uma coluna ou uma combinação de colunas podem servir para distinguir uma linha das demais. Assim sendo, uma delas é escolhida para ser a chave primária, sendo as demais designadas como chave alternativas. * Registros: Cada uma das linhas de uma tabela. 14.2 - SQL (Structured Query Language) SQL é a linguagem padrão de pesquisa declarativa para bancos de dados relacionais. É através dessa linguagem que podemos realizar consultas ao banco de dados para obtermos as informações que desejamos. As quatro instruções básicas de SQL para manipulação de dados são as seguintes: SELECT, INSERT, UPDATE e DELETE. 14.2.1 - INSERT Esse comando insere linhas (ou registros) nas tabelas de um banco de dados. Observe a sintaxe desse comando descrita a seguir, a qual possui uma variação: INSERT into <nome_tabela> values (valor1,valor2,...valorn); INSERT into <nome_tabela> (nome_campo1,nome_campo2,...nome_campon) values (valor1,valor2,...valorn); Suponhamos que tenhamos um banco de dados chamado EMPRESA com as tabelas Empregado e Departamento tais como definididas anteriormente. Na primeira variação, os valores serão incluídos nos campos segundo a ordem de criação das colunas da tabela. Já a segunda variação permite que façamos a inclusão dos valores nas colunas segundo a ordem determinada pelo usuário. Nota-se que os campos não mencionados nessa segunda variação serão preenchidos com o valor NULL ou o valor-padrão (caso exista um). Caso queiramos inserir uma nova linha na tabela Departamento com os valores 'D4' e 'Financiamento' nos campos 'CodigoDepartamento' e 'Nome', respectivamente, usaríamos o seguinte comando: INSERT INTO Departamento VALUES ('D4', 'Financiamento'); ou INSERT INTO Departamento (CódigoDepartamento,Nome) VALUES('D4', 'Financiamento'); 14.2.2 - UPDATE O comando UPDATE realiza alterações nos valores dos registros de uma determinada tabela, podendo alterar um ou mais registros simultaneamente. Observe a sua sintaxe: UPDATE <nome_tabela> SET campo1=valor1 [, campo2=valor2, ... , campon = valorn] [WHERE <condições>]; A cláusula WHERE define as condições necessárias para que o registro seja alterado, por isso, devemos ter muito cuidado ao utilizarmos esse comando. Observe o exemplo abaixo em que se percebe a utilização do UPDATE: UPDATE Empregado SET CodigoDepartamento = 'D1' WHERE CodigoEmp = 'E1' Esse comando altera todas as linhas da tabela Empregados em que o código do empregado for E1, modificando o código de departamento para D1. 14.2.3 - DELETE O comando DELETE exclui um ou mais registros de determinada tabela. Observe a sintaxe desse comando: DELETE FROM <nome_tabela> [WHERE <condições>]; Nota-se que se a cláusula WHERE não for utilizada, todos os registros da tabela serão excluídos. Exemplo de utilização: DELETE FROM Departamento WHERE Nome = 'Vendas' // Exclui do BD todos os registros com o // valor 'Vendas' no campo 'Nome' 14.2.4 - SELECT Esse é o comando mais utilizado na maioria das aplicações que envolvem bancos de dados. Ele realiza a seleção de linhas de uma ou mais tabelas, sendo de suma importância para a manipulação e visualização das informações contidas em um banco de dados. Sua sintaxe básica é a seguinte: SELECT <lista_de_campos> FROM <lista_de_tabelas> [WHERE <condições>] Se a <lista_de_campos> for substituída por um asterisco (*), serão retornados todos os campos existentes na(s) tabela(s) em uso. Se a cláusula WHERE for omitida, serão mostrados todos os registros das tabelas determinadas em <lista_de_tabelas>. Observe o exemplo abaixo: SELECT Nome FROM Empregado WHERE CodigoDepartamento = 'D2' Essa consulta resultaria na seguinte tabela (segundo os dados exemplificados anteriormente nas tabelas 'Empregado' e 'Departamento': João José Observação: na cláusula WHERE (tanto nesse comando como nos comandos vistos anteriormente), caso haja o desejo de que mais de uma condição seja satisfeita, podemos usar os operadores lógicos AND e OR. Para os exemplos e explicações seguintes, criaremos uma nova tabela chamada Peça, tal que cada registro possui as informações do código da peça, do preço, do código do fornecedor e da cor da peça: Peca Codigo Preco CodFornec Cor 1 110 5 Amarelo 3 50 9 Vermelho 4 80 5 Azul 7 105 6 Amarelo Observe este outro exemplo de utilização do comando SELECT: SELECT Preco, Cor FROM Peca WHERE CodFornec = 5 AND Preco < 100 Esse comando SQL seleciona os campos Preço e Cor dos registros da tabela Peça, tais que possuam um fornecedor de código igual a 5 e um preço menor do que 100. O resultado da consulta seria o seguinte: 80 Azul Mais detalhes sobre demais variantes e comandos SQL estão fora do escopo deste curso de PHP, o qual tem por finalidade explorar a conexão entre o PHP e bancos de dados. 14.3 - PHP e Bancos de Dados Alguns provedores de hospedagem oferecem servidores com suporte ao MySQL. O MySQL nada mais é que um SGBD (Sistema de Gerência de Bancos de Dados), o qual tem como finalidade permitir a definição, alteração e manipulação do banco de dados desejado. O MySQL é, na verdade, apenas um dos possíveis SGBD's disponíveis nos servidores para tratamento de um BD e é ele que usaremos em nosso curso. Observe os tipos de dados disponíveis para o MySQL: Tipo Tinyint Descrição Inteiro pequeno. Varia de -128 a 127, Smallint Inteiro variando de -32768 até +32767. Mediumint Inteiro variando de -8388608 até +8488607. Int Inteiro normal, variando de -2147483648 até +2147483647. Bigint Inteiro grande, de -9223372036854775808 até +9223372036854775807. Float (precisão) Ponto flutuante com precisão definida. Float [(M,D)] Ponto flutuante de precisão simples. Double[(M,D)] Ponto flutuante normal. Real É um sinônimo para double. Tipo Descrição Decimal Esse tipo pode ser usado como uma string. Cada número corresponde a um caracter. Date Armazena uma data no formato aaaa-mm-dd. Pode variar de 1000-01-01 até 9999-12-31. Datetime Armazena data e hora. O intervalo suportado é de 1000-01-01 00:00:00 até 9999-12-31 23:59:59. Armazena a data em formato-padrão UNIX (número de segundos após o data base). Timestamp Time Year[(2/4)] Armazena um tempo. Varia de -838:59:59 até 838:59:59. Char(M) String de tamanho fixo. Varchar(M) String de tamanho variável. Possui no máximo 255 caracteres. Tinytext Texto contendo até 255 caracteres. Text Texto com até 65535 caracteres. Mediumtext Texto com o tamanho de 16777215 caracteres. Longtext Texto com o tamanho máximo de 4294967295 caracteres. Enum('v1',...) String que pode conter apenas um dos valores listados ou NULL. Set('v1',...) String que pode conter 0 ou mais valores, cada um deles pertencentes à lista informada. Armazena um ano com 2 ou 4 dígitos. O padrão é 4 dígitos. Varia entre 1901 e 2155 no formato de 4 dígitos e de 1970 a 2069 no formato de 2 dígitos. Para podermos acessar um banco de dados através de um programa PHP, é necessário primeiramente estabelecermos uma conexão com o mesmo. Essa conexão pode ser estabelecida através do comando apresentado a seguir: 14.3.1 - mysql_connect Esse comando realiza a conexão com o banco de dados, sendo atribuído em uma variável o resultado como um ponteiro, para referenciar essa conexão. Observe a sua sintaxe: mysql_connect([servidor [:porta]],[usuario],[senha]); Se desejássemos realizar a conexão com um banco de dados existente em um servidor local, com o nome de usuário 'Alguem' e senha 'alguma', utilizaríamos o seguinte comando: $conexao = mysql_connect("localhost","Alguem","alguma"); 14.3.2 - mysql_close Quando não formos mais utilizar uma conexão aberta em um programa PHP, podemos fechá-la com esse comando. Assim sendo, podemos fechá-la utilizando como parâmetro do comando mysql_close a variável que contém o ponteiro referente a conexão. Observe o exemplo abaixo, onde essa variável seria a $conexao. mysql_close($conexao); 14.3.3 - mysql_select_db Esse comando seleciona o banco de dados que queremos manipular ou obter informações. Segue como parâmetro para ele o nome do banco de dados escolhido. Caso quiséssemos estabelecer uma conexão com um banco de dados chamado 'produtos', utilizaríamos o comando da seguinte forma: mysql_select_db("produtos"); 14.3.4 - mysql_query Esse é o comando utilizado para enviarmos comandos SQL para o banco de dados com a finalidade de manipular as informações. Sua sintaxe é a seguinte: mysql_query(<comando>,[<conexão>]); Nota-se que esse comando não tem como parâmetro o banco de dados para o qual o comando SQL está enviado, uma vez que tem como premissa a idéia de que o banco de dados já foi conectado e selecionado com os comandos vistos anteriormente. Caso desejássemos enviar um comando SQL para outro banco de dados não selecionado no servidor, podemos utilizar o seguinte comando: mysql_db_query(<banco de dados>,<comando>,[<conexão>]); 14.3.5 - Manipulando Resultados dos Comandos SQL Existem diversas funções do PHP (direcionadas ao MySQL) que realizam o tratamento das informações retornadas por comandos SQL. Essas funções são de extrema importância para a compreensão da relação estabelecida entre o PHP e o banco de dados e as principais estão listadas a seguir: MySQL Descrição mysql_affected_rows Retorna o nº de linhas afetadas por uma operação SQL mysql_fetch_array Armazena em um array a linha do resultado. mysql_fetch_object Retorna uma linha como um objeto. mysql_fetch_row Armazena em um array a linha do resultado. mysql_result Retorna uma coluna do resultado. mysql_num_rows Retorna o nº de linhas de uma consulta. mysql_num_fields Retorna o nº de colunas de uma consulta. mysql_field_name Retorna o nome de uma coluna em uma consulta. Analisaremos cada uma delas detalhadamente a seguir, explicitando as suas diferenças e vantagens quanto a utilização em certas situações. * mysql_affected_rows: Esse comando retorna o nº de linhas afetadas por um comando SQL que não tenha tido como função retornar registros. Isso inclui os comandos de inserção (INSERT), atualização (UPDATE) e exclusão (DELETE), excluindo os comandos de seleção (SELECT). Sua sintaxe é a seguinte: mysql_affected_rows([<conexao>]); Observe que esse comando obtém o número de linhas afetadas do ÚLTIMO comando realizado, por isso, pode-se explcitar como parâmetro a variável que contém o ponteiro para a conexão com o MySQL. Imagine que tivéssemos estabelecido uma conexão com o banco de dados 'Empresa' que contém as tabelas Empregado, Departamento e Peça declaradas anteriormente, que o ponteiro estivesse na variável $conexão e que desejássemos realizar o seguinte comando SQL: DELETE FROM Empregado WHERE Nome = 'Pedro' Dessa forma, nosso programa PHP para descobrirmos quantas linhas foram deletadas através desse comando seria algo semelhante ao exemplo a seguir: <?php ?> ... mysql_query("DELETE FROM Empregado WHERE Nome = 'Pedro'"); echo "Numero de linhas apagadas: " . mysql_affected_rows($conexao); No caso, teríamos como saída a seguinte frase: Numero de linhas apagadas: 2 * mysql_num_rows: Diferentemente do comando visto acima, este comando obtém o número de linhas afetadas por um comando SQL de seleção (SELECT) que retorna um determinado número de registros. A sintaxe desse comando é a seguinte: mysql_num_rows(<resultado_selecao>); Segue abaixo o exemplo de sua utilização em um programa PHP que esteja manipulando o banco de dados 'Empresa': <?php ... $resultado = mysql_query("SELECT * FROM Empregado"); $num_linhas = mysql_num_rows($resultado); echo $num_linhas; // Valor esperado: 4 ?> * mysql_num_fields: Esse comando é utilizado para obtermos o número de campos (colunas) retornados em uma consulta. A sintaxe do comando é a seguinte: mysql_num_fields(<resultado_selecao>); Segue abaixo o exemplo de sua utilização em um programa PHP que esteja manipulando o banco de dados 'Empresa': <?php ?> $sql = "SELECT * FROM Empregado"; $resultado = mysql_query($sql); $colunas = mysql_num_fields($resultado); echo "Numero de colunas: " . $colunas; // resultado esperado: Número de colunas: 3 * mysql_result: Através desse comando podemos obter os valores dos campos retornados por um consulta. É importante destacar que ele retorna um valor de um campo por vez. Sua sintaxe é a seguinte: mysql_result(<resultado_consulta>,<linha>,<coluna>); Onde: <resultado_consulta> é a variável que recebeu o resultado do comando mysql_query. <linha> é o número da linha que desejamos recuperar (começando em 0). <coluna> é o número da coluna (começando em 0) ou nome do campo da tabela. Segue abaixo o exemplo de sua utilização em um programa PHP que esteja manipulando o banco de dados 'Empresa': <?php ... $sql = "SELECT * FROM Peca WHERE Preco < 90"; $resultado = mysql_query($sql); $linhas = mysql_num_rows($resultado); echo "Informações das peças com preço menor que 90:<br>"; for ($i=0;$i<linhas;$i++) { $codigo = mysql_result($resultado,$i,0); $preco = mysql_result($resultado,$i,"preco"); $codfornec = mysql_result($resultado,$i,2); $cor = mysql_result($resultado,$i,"cor"); echo "Código: " . $codigo; echo " Preço: " . $preco; echo " Código do Fornecedor: " . $codfornec; echo " Cor: " . $cor . "<br>"; } ... ?> * mysql_fetch_row e mysql_fetch_array: Existem outros dois comandos muito úteis para obter valores retornados por uma consulta a um banco de dados: mysql_fetch_row e mysql_fetch_array. Ambos os comandos colocam as linhas retornadas (uma por vez) em um array. A diferença entre as duas é que a função mysql_fetch_array permite o acesso aos índices do array por chave associativa (nome dos campos), enquanto a função mysql_fetch_row utiliza somente índices numéricos. A sintaxe das duas funções é a seguinte: mysql_fetch_row(<resultado_consulta>); mysql_fetch_array(<resultado_consulta>); Observe o exemplo abaixo baseado no banco de dados 'Empresa': <php $sql = "SELECT Codigo, Preco FROM Peca"; $resultado = mysql_query($sql); $linhas = mysql_num_rows($resultado); for ($i=0;$i<$linhas;$i++) { $registro = mysql_fetch_array($resultado); echo "Codigo: " . $registro[0] . "<br>"; echo "Preço: " . $registro["preco"] . "<br>"; } ?> É importante observar que a cada chamada desses comandos, o ponteiro interno dos dados é incrementado, não necessitando estabelecer um índice de linha como parâmetro para serem retiradas as informações. * mysql_fetch_object: Existe um outro comando para obtenção dos valores de uma consulta chamado mysql_fetch_object. Esse comando retorna um objeto que referencia uma linha do resultado. Sua sintaxe é a seguinte: mysql_fetch_object(<resultado_consulta>); Observe a maneira de utilizar esse comando no exemplo abaixo, baseado no banco de dados 'Empresa': <?php ?> ... $sql = "SELECT Preco,Cor FROM Peca WHERE Codigo = 4"; $resultado = mysql_query($sql); $objeto = mysql_fetch_object($resultado); echo "Codigo: " . $objeto->Preco . "<br>"; echo "Preço: " . $objeto->Cor . "<br>"; ... Resultado esperado: Código: 80 Preço: Azul * mysql_field_name: Esse comando possui a simples função de retornar o nome de uma determinada coluna retornada por uma consulta a um banco de dados. Sua sintaxe é a seguinte: mysql_field_name(<resultado_consulta>,<coluna>); Observe o exemplo de sua utilização no exemplo abaixo, baseado no banco de dados 'Empresa': <?php ... $resultado = mysql_query("SELECT * FROM Peca"); $nome_coluna = mysql_field_name($resultado,3); echo $nome_coluna; // resultado esperado: Cor ... ?> Essa foi uma pequena introdução a respeito de bancos de dados e a sua relação estabelecida com programas PHP para tornar websites mais dinâmicos e de maior utilidade prática. Maiores detalhes, comandos e funções podem ser encontrados em uma vasta bibliografia e em arquivos dispostos na Web. 15 – Cookies e Sessions Cookies e Sessions são recursos de suma importância utilizados por diversos websites que desejam manter e obter informações no browser do usuário ou que necessitam de um sistema para autenticação de usuários para um melhor controle de acesso às informações. Na verdade, cookies são arquivos-texto que podem ser armazenados no computador do usuário para serem recuperados posteriormente pelo servidor no qual o website está hospedado. Geralmente, o uso de cookies não é recomendado quando se trata de informações sigilosas, uma vez que os dados dos cookies são armazenados no diretório de arquivos temporários do visitante, sendo facilmente visualizado por pessoas mal intencionadas. Os cookies também são responsáveis pelos controles do tipo “Salvar Senha” e “Manter-me Conectado”. Para informações sigilosas é mais recomendado usar Sessions, que, assim como os cookies, também são arquivos-texto porém estes ficam armazenados no servidor (geralmente arquivos temporários), assim o usuário não precisa ter nada habilitado no seu browser. 15.1 - Cookies Vamos começar com a utilização dos cookies. A sintaxe para a criação de cookies é a seguinte: setcookie(nome,valor,[validade],[caminho],[nome_dominio],[seguro]); Onde: nome: Nome do cookie que está sendo enviado. Posteriormente, se tornará o nome da variável que fará referência ao cookie. valor: É o valor que a variável possuirá. Esse valor pode ser de todos os tipos. validade: É o tempo, em segundos após 1º de janeiro de 1970 às 00:00:00, que o cookie existirá no computador do visitante. Uma vez excedido esse prazo, o cookie se apaga de modo irrecuperável. Se esse argumento ficar vazio, o cookie se apagará quando o visitante fechar o browser. caminho: Endereço da página que gerou o cookie - automático nome_domínio: Domínio ao qual pertence o cookie - automático seguro: Indica se o cookie deverá ser transmitido somente em uma conexão segura HTTPS. Uma observação importante é que todos os cookies devem ser criados antes de qualquer tag HTML como, por exemplo, as tags <HTML> e <BODY>. Caso seja necessário apagar um cookie do browser do usuário, deve-se realizar o comando setcookie com apenas o parâmetro nome colocado. Após o envio dos cookies, todas as requisições de páginas feitas pelo usuário ao servidor conterá esses cookies, e poderemos utilizá-los em nossos programas PHP. Entretanto, cookies não podem ser utilizados na mesma página que os criou, podendo apenas ser utilizados a partir da próxima solicitação de página vinda do programa navegador do usuário. É importante ressaltar também que caso não queiramos passar um parâmetro intermediário no comando setcookie, deve-se utilizar "" para substituir esse parâmetro, com exceção dos parâmetros validade e seguro (que devem conter valores numéricos, no caso, o 0). 15.2 - Acesso aos Cookies pelo PHP Existem duas formas de acessar os cookies enviados para a máquina do usuário através de um programa PHP. Uma delas é utilizando o próprio nome do cookie como uma variável. O cookie 'senha' seria referenciado da seguinte forma: $senha Outra forma de acessar os cookies é por meio do array $HTTP_COOKIE_VARS, utilizando o nome do cookie como chave associativa. O cookie 'senha', nesse caso, seria referenciado da seguinte forma: $HTTP_COOKIE_VARS["senha"] Nota-se que a primeira opção é bem mais simples e trivial de ser usada, quando em comparação com a segunda opção. Porém, ambas as formas são aceitáveis em um programa PHP. 15.3 - Exemplo de Utilização de Cookies Vamos supor que desejamos construir um website que apenas possa ser acessado por usuários cadastrados no mesmo. Dessa forma, faz-se necessária a identificação desse usuário através de um formulário, para que se possa conferir seu 'Nome' e 'Senha', e permitir o acesso às demais páginas do site. Óbviamente, para que possam ser conferidos os dados passados pelo usuário no formulário, deve existir um banco de dados que contenha essas informações. Chamaremos esse banco de dados de 'Validade'. Esse banco de dados, além de eventuais informações adicionais contidas, contém uma tabela chamada 'Usuário', que é estruturada da seguinte forma: Usuário Nome Senha A página principal de nosso website possui o formulário que pede as informações a serem conferidas no banco de dados 'Validade', posteriormente. Segue abaixo o código dessa página: home.html: <html> <body> <form action="valida_usuario.php" method="POST"> Nome: <input type="text" name="usuario"><br> Senha: <input type="password" name="senha"> <input type="submit" value="Enviar" name="submeter"> </form> </body> </html> A seguir, encontra-se o código parcial do programa "valida_usuario.php", que recebe os dados enviados pelo formulário da página principal: valida_usuario.php: <?php $conexao = mysql_connect("localhost","usuario","senha"); mysql_select_db("Validade"); $usuario = $_POST["usuario"]; $senha = $_POST["senha"]; $sql = "SELECT * FROM Usuario WHERE Nome = '$usuario'"; $resultado = mysql_query($sql); $linhas = mysql_num_rows($resultado); if ($linhas == 0) // testa se a consulta retornou algum registro { echo "<html><body>Usuario inexistente<br>"; echo "<a href=\"home.html\">Voltar</a></body></html>"; } else // resultado retornou registro { if ($senha != mysql_result($resultado,0,"senha")) //confere senha { echo "<html><body>Senha inválida<br>"; echo "<a href=\"home.html\">Voltar</a></body></html>"; } else { // usuário e senhas corretos. Criam-se os cookies setcookie("nome_usuario",$usuario); setcookie("senha",$senha); // direciona para a página inicial dos usuários cadastrados echo "<html><body>Usuário e Senha combinam!<br>"; echo "<a href=\"principal.php\">Continue</a></body></html>"; } } mysql_close($conexao); ?> Observe que no programa acima é realizada uma consulta no banco de dados Validade a fim de encontrar o registro referente ao nome do usuário fornecido no formulário. Se o número de linhas do resultado for igual a 0, então significa que o nome do usuário não foi encontrado no banco de dados (Usuário inexistente). Caso contrário, testa-se se a senha fornecida no formulário é a mesma encontrada no registro retornado pela consulta. Se as informações não coincidirem significa que a senha fornecida está errada (Senha inválida). Se as informações coincidirem, o nome do usuário e a senha fornecidos são válidos e pode-se então criar os cookies com essas informações para identificação do usuário nas demais páginas do website, a fim de garantir permissão de acesso ao seu conteúdo. A partir do momento em que os cookies estão armazenados na máquina do usuário, toda a requisição de páginas feita por ele ao servidor conterá esses cookies e poderemos utilizá-los em nossos programas PHP. No exemplo do website que estamos criando, poderemos utilizar nas demais páginas os cookies criados através do formulário de login. Nota-se que quando o usuário fizer um login corretamente, existirá um link para a página principal.php. Porém, e se o usuário simplesmente digitar em seu browser esse link, não passando anteriormente pela página referente ao login? Aí é que os cookies entram em ação. É necessário que cada página desse website (incluindo a principal.php) contenha uma include que verifique se os cookies existem e se os dados pertencentes a esses cookies são satisfatórios: valida_cookies.inc: <?php if (!(empty($nome_usuario) OR empty($senha))) // se cookies existem { $conexao = mysql_connect("localhost","usuario","senha"); mysql_select_db("Validade"); $sql = "SELECT * FROM Usuario WHERE Nome = '$nome_usuario'"; $resultado = mysql_query($sql); $linhas = mysql_num_rows($resultado); if ($linhas == 1) // se achou um resultado válido, verifica a senha { if ($senha != mysql_result($resultado,0,"senha")) { setcookie("nome_usuario"); setcookie("senha"); echo "Você não efetuou o login"; exit; } } else // se não achou o nome do usuário no banco de dados { setcookie("nome_usuario"); setcookie("senha"); echo "Você não efetuou o login"; exit; } } else { // se cookies não existem echo "Você não efetuou o login"; exit; } mysql_close($conexao); ?> É importante observar que se os dados existentes nos cookies coincidirem com os dados mantidos no banco de dados Validade, o usuário poderá acessar o conteúdo da página visitada, uma vez que seu login foi realizado de maneira corretamente. Nota-se que os comandos de destruição dos cookies (setcookies com apenas o parâmetro nome) são os primeiros comandos da página, sendo enviados antes mesmo de qualquer tag HTML propriamente dita. Logo, deve-se incluir as includes no início das páginas que desejam verificar o login para que funcionem corretamente. Caso desejássemos realizar um programa PHP para realizar o logout do usuário (e a conseqüente exclusão dos cookies), poderíamos utilizar um programa no seguinte formato: logout.php: <?php setcookie("nome_usuario"); setcookie("senha"); echo "Logout realizado com sucesso!"; exit; ?> 15.4 - Sessions Para iniciarmos uma session, utilizamos a função sessionstart(). Vale ressaltar que é recomendado que a chamada desta função não esteja antes de nenhum Output (echo, print...), recomenda-se também que esta seja a primeira instrução do programa, isso deve-se ao delay que esta instrução sofre e ao paralelismo das instruções. Similarmente aos cookies, para definirmos variáveis de sessão basta usar a sintaxe $_SESSION[“variavel”]. Vamos a um exemplo de criação: <?php session_start("login"); $_SESSION("nome") = Petcomp ; $_SESSION(“senha”)=123456 ; ?> Uma session continuara existindo enquanto o usuário estiver navegando, uma vez que o browser foi fechado esta será apagada automaticamente. Mesmo assim é possível destruir sessions e variáveis de sessão utilizando as seguintes funções: unset($_SESSION[“<name>”]) para apagar uma variável e session_destroy() para acabar com todas sessions abertas. Como você já deve ter percebido, também existe a possibilidade de setar um tempo determinado para a session existir, a maioria dos sistemas utiliza este recurso no login e desconecta usuários inativos por tempo pré-determinado. A função usada para tal é session_cache_expire(<tempo_minutos>), o default para essa função é 180 minutos, mas é possível setar qualquer tempo. A função também retorna um inteiro avisando quantos minutos ainda restam. Importante ressaltar que este valor deve ser atualizado durante a navegação para que o usuário não perca o acesso mesmo navegando entre as páginas. Como exemplo tente usar o mesmo código que foi proposto para o login usando cookies e substitua as funções de cookie por session, considere incluir um tempo de expiração para sua session. Com certeza seu sistema de checagem de login ficara mais seguro. 16 – Bibliotecas Interessantes Decidimos colocar esta última sessão na apostila a fim de dar um overview de algumas das bibliotecas bastante usadas do php, para assim o aluno já ter alguma referência caso queira utilizar alguma destas funcionalidades. A seguir uma pequena lista de bibliotecas e suas funcionalidades. Biblioteca GD: Utilizada para edição e saídas em imagens, com ela é possível criar e manipular imagens em uma diversidade de formatos, incluindo gif, png, jpg, wbmp e xpm. Também é possível enviar streams de saída de imagem diretamente para o browser. Com ela você pode, por exemplo, criar imagens com textos, mesclar imagens, gerar figuras geométricas, códigos de barras, entre outros. Biblioteca JPGRAPH: Biblioteca utilizada para criar gráficos. Com ela é possível criar praticamente qualquer tipo de gráfico. Gráficos em pizza, barras, linhas, enfim, uma biblioteca muito útil para mostrar dados em formas gráficas. Biblioteca FPDF: Ótima biblioteca para manipulação de arquivos PDF. A biblioteca FPDF é free (ao contrario da biblioteca PFDlib) e é uma ótima ferramenta para geração de relatórios. Possui suporte a formatação de cabeçalho e rodapé, quebra de página, quebra de linha e justificação de texto automática, suporte a imagens, suporte a fontes tipo TrueType e Type1, entre outros. SMARTY: Esta biblioteca foi criada a fim de separar a aplicação lógica da apresentação do conteúdo. Com ela é possível sincronizar o trabalho do webdesigner e do programador da aplicação de maneira que, qualquer atualização ou modificação da forma como o conteúdo é gerado e enviado, não modificará a forma de como o webdesigner apresenta estes conteúdos na página. O SMARTY cria templates e scripts que padronizam os dados da aplicação. Biblioteca muito útil para uso em ambientes de trabalho em equipe, poupando muito trabalho e dor de cabeça dos envolvidos. 17 – Conclusões O php é sem dúvidas uma ferramenta extremamente útil, tanto no âmbito web como programação em geral, a prova disso é que temos grandes sites que usam esta linguagem, o Facebook é apenas um exemplo deles. Todo conhecimento repassado aqui é apenas uma boa introdução a todo poder que esta linguagem possui, por isso é importante estar atualizado e também participar da comunidade PHP na internet. Não atenha-se apenas as funções que repassamos aqui nesta apostila, existem outras muitas que podem ser utilizadas com a maioria das funcionalidades que se pode imaginar. O site php.net esta sempre atualizado com as últimas versões e utilidades do PHP. Esperamos que tenham gostado do material e estamos abertos a qualquer dúvida ou sugestão. Atenciosamente: Grupo PET Computação - UFRGS