6. Introdução à Linguagem PHP A comunicação na Web exige dois agentes: o cliente web e o servidor web. O cliente requer informação (a partir de uma página HTML acessada pelo navegador) e o servidor fornece a informação requerida. Isto é feito na web por meio de fluxos de textos que atendem ao protocolo HTTP (Hypertext Transfer Protocol). O cliente requer uma informação ao servidor, o servidor reconhece a requisição do cliente e gera um conteúdo correspondente (na forma de um texto HTML) e devolve este conteúdo como resposta ao cliente, que o visualiza no navegador. Cliente Navegador requisição resposta Servidor Web Servidor Gerador de Conteúdo Os programas JavaScripts são interpretados diretamente pelo navegador (ou seja, pelo próprio cliente). Neste caso, dizemos que a programação web é feita pelo lado do cliente (client-side programming). ELFS, 2003 164
No caso da linguagem PHP, a programação é interpretada pelo servidor que, a partir de um gerador de conteúdo (o interpretador da linguagem PHP) produz uma página HTML que é então devolvida ao cliente. Neste caso, dizemos que a programação é pelo lado do servidor (server-side programming). Assim, no caso da linguagem JavaScript, os programas fazem parte do documento HTML que está sendo visualizado no navegador (pois o próprio navegador tem que interpretá-los) sendo, portanto, possível ao cliente ter acesso ao código-fonte destes programas. No caso da linguagem PHP, a página que está sendo visualizada no navegador é o resultado da interpretação do programa-fonte pelo gerador de conteúdo do servidor, ou seja, a partir do código-fonte de um programa PHP é gerada um documento HTML correspondente (que não inclui o código-fonte). Assim, a programação pelo lado do servidor "esconde do cliente" os detalhes de programação. Nesta disciplina vamos usar o pacote PHP Triad for Windows, que inclui o servidor web Apache, o gerenciador de bancos de dados relacionais MySQL, e o interpretador da linguagem PHP. Este pacote irá criar uma pasta C:\apache onde serão instalados todos estes componentes. Dentro desta pasta, será criada a pasta htdocs como diretório padrão para os documentos web (arquivos HTML e arquivos PHP). ELFS, 2003 165
Para testar se o servidor Apache e o interpretador PHP estão funcionando, copie o arquivo a seguir para a pasta C:\apache\htdocs: <?php $txt1 = "O servidor Apache"; $txt2 = "o interpretador PHP"; $txt3 = "estão prontos para o trabalho!!"; echo "<h1><a href=http://www.apache.org> $txt1 </a><br>"; echo "e<br><a href=http://www.php.org> $txt2 </a></h1>"; echo "<h2><div style='color:red'> $txt3 </div></h2>";?> Agora, aponte o navegador para: http://localhost/aula06_01.php O resultado deve ser como o mostrado abaixo. aula06_01.php ELFS, 2003 166
O código PHP também pode ser incluído como scripts em um documento HTML (como em JavaScript). É preciso, no entanto, usar a extensão.php para o nome do documento. Exemplo: <html> <body> <?php $txt1 = "O servidor Apache"; $txt2 = "o interpretador PHP"; $txt3 = "estão prontos para o trabalho!!"; echo "<h1><a href=http://www.apache.org1> $txt1 </a><br>"; echo "e<br><a href=http://www.php.org1> $txt2 </a></h1>"; echo "<h2><div style='color:red'> $txt3 </div></h2>";?> </body> </html> aula06_02.php Execute no navegador http://localhost/aula06_02.php. Clique com o botão direito sobre a página exibida e escolha a opção "Exibir código-fonte" para se certificar de que o script PHP não fica disponível ao cliente. O importante, com a linguagem PHP, é a possibilidade de construção de páginas dinâmicas (páginas cujo conteúdo dependem de uma interação com o usuário). Para isto, vamos usar o gerenciador de bancos de dados MySQL. ELFS, 2003 167
Como padrão, a instalação do MySQL cria o usuário root que não requer senha. É papel do administrador dos bancos de dados acrescentar novos usuários e suas permissões de uso. Vamos criar o banco de dados dai para o usuário root. Para isto, digite em uma janela de comandos: mysqladmin -u root create dai Em seguida, vamos criar a tabela alunos do banco de dados dai, a partir dos seguintes comandos SQL: CREATE TABLE alunos ( num int(5) NOT NULL, nome varchar(20), sobrenome varchar(20), PRIMARY KEY (num), UNIQUE (num)); INSERT INTO alunos VALUES (99060,'Luis','Nascimento'); INSERT INTO alunos VALUES (99059,'Cristiane','Silva'); INSERT INTO alunos VALUES (99057,'Victor','Silva'); INSERT INTO alunos VALUES (99044,'Mariana','Peixoto'); INSERT INTO alunos VALUES (99036,'Filipe','Domiciano'); alunos.sql Salve o arquivo alunos.sql em uma [pasta]. Para incluir a tabela alunos no banco de dados dai, digite o comando: mysql -u root dai < [pasta]\alunos.sql Para verificar que tudo foi criado apropriadamente, vamos usar o monitor MySQL. ELFS, 2003 168
Digite na janela de comandos: mysql -u root Digite, então, os comandos a seguir (note que o ponto-e-vírgula é necessário) e verifique a resposta dada pelo monitor MySQL: show databases; use dai; show tables; desc alunos; select * from alunos; Para sair do monitor, digite: quit Outra forma de verificar bancos de dados e tabelas é com o programa winmysqladmin. Vamos agora usar o banco de dados dai para criar um programa PHP para mostrar, inserir, alterar e excluir linhas da tabela alunos. ELFS, 2003 169
Para isto, vamos considerar o seguinte documento HTML: aula06_03.htm <html> <head> <title>edição de Tabelas com PHP</title> </head> <body> <form name="edtab" action="aula06_03.php" method="post"> <h1>alunos de DAI</h1> <p>número: <input type="text" name="ednum" size="10" maxlength="5"></p> <p>nome: <input type="text" name="ednome" size="30" maxlength="20"></p> <p>sobrenome: <input type="text" name="edsobre" size="30" maxlength="20"></p> <br> <p>operação: <input type="radio" name="escolha" value="1" checked>listar</input> <input type="radio" name="escolha" value="2">incluir</input> <input type="radio" name="escolha" value="3">alterar</input> <input type="radio" name="escolha" value="4">excluir</input> </p> <input type="reset" value="limpar"> <input type="submit" value="executar"> </form> </body> </html> ELFS, 2003 170
Note que, neste formulário, o usuário deverá escolher uma das operações e clicar no botão Executar. Com isto será executado (no lado servidor) o script aula06_03.php, que construirá uma página de resposta à requisição do usuário. Note, no documento HTML, que estão definidos os identificadores: ednum, ednome e edsobre (nomes das caixas de edição) e também o identificador Escolha (identifica qual operação foi escolhida pelo usuário). Considere o seguinte script PHP: <?php // Edição de tabela de banco de dados. aula06_03.php /* Note que comentários podem ser feitos também de forma a ocupar diversas linhas. Neste caso, basta usar os delimitadores de início e fim de comentário. */ // ********************************************************* ELFS, 2003 171
function listagem($conecta) $sql = "select * from alunos"; Variáveis definidas dentro de funções em um script PHP são consideradas variáveis locais, a menos que sejam declaradas com o qualificador global. $query = mysql_db_query("dai", $sql, $conecta); echo("<h1>listagem de Alunos</h1>"); echo("<table border width=50%"); echo("<tr><th>número</th><th>nome</th><th>sobrenome</th></tr>"); while ($result = mysql_fetch_array($query)) echo("<tr>"); echo("<td>". $result["num"]. "</td>"); echo("<td>". $result["nome"]. "</td>"); echo("<td>". $result["sobrenome"]. "</td>"); echo("</tr>"); mysql_free_result($query); Sempre que o comando SQL resultar em uma tabela (como no caso de um select), os recursos de memória alocados à variável que armazena os resultados da consulta (no caso, a variável $query) devem ser liberados com a função mysql_free_result. // ********************************************************* A função mysql_fecth_array retorna uma linha da tabela (ou zero, caso não existam mais linhas). Note que os campos que compõem a linha são acessados como "índices". ELFS, 2003 172
function incluir($conecta,$ednum,$ednome,$edsobre) $sql = "insert into alunos (num,nome,sobrenome) values ". "( $ednum, '$ednome', '$edsobre' )"; $query = mysql_db_query("dai", $sql, $conecta); echo("<h1>inclusão de Alunos</h1>"); if ($query) echo("aluno $ednome incluído na tabela!"); else echo("erro na inclusão ". mysql_error(). "\n"); Note que o ponto (. ) é o operador de concatenação de strings. Note que se o nome de uma variável aparece em um string, ele será automaticamente substituído pelo valor da variável. // ********************************************************* function encontrar($conecta,$ednum) $sql = "select * from alunos where num = $ednum"; $query = mysql_db_query("dai", $sql, $conecta); ELFS, 2003 173
$result = mysql_fetch_array($query); if ($result["num"] == 0) echo("<h1>aluno $ednum não existe!!!</h1>"); $cod = 0; else $cod = 1; mysql_free_result($query); return $cod; Note que se um campo da tabela for do tipo varchar, o valor do campo deve ser delimitado por aspas ou por apóstrofos (é o caso dos campos nome e sobrenome, da tabela alunos). Para campos numéricos, o valor não precisa estar delimitado por aspas ou por apóstrofos (é o caso do campo num). // ********************************************************* function alterar($conecta,$ednum,$ednome,$edsobre) echo("<h1>alteração de Alunos</h1>"); if (encontrar($conecta,$ednum) == 1) $sql = "update alunos set nome = '$ednome', sobrenome = '$edsobre' ". "where num = $ednum"; ELFS, 2003 174
$query = mysql_db_query("dai", $sql, $conecta); if ($query) echo("aluno $ednum alterado!"); else echo("erro na alteração ". mysql_error(). "\n"); // ********************************************************* function excluir($conecta,$ednum) echo("<h1>exclusão de Alunos</h1>"); if (encontrar($conecta,$ednum) == 1) $sql = "delete from alunos where num = $ednum"; $query = mysql_db_query("dai", $sql, $conecta); ELFS, 2003 175
if ($query) echo("aluno $ednum excluído da tabela!"); else echo("erro na exclusão ". mysql_error(). "\n"); // ********************************************************* // // Aqui começa o script principal // // ********************************************************* $conecta = mysql_connect("localhost","root"); if ($conecta) switch ($Escolha) case "1": listagem($conecta); break; Note que o script principal tem acesso aos identificadores definidos no documento HTML que chamou o script. Estes identificadores são tratados como variáveis (como é o caso de $Escolha). Note que a linguagem PHP faz distinção entre letras maiúsculas e minúsculas. ELFS, 2003 176
Observe que é necessário case "2": passar como parâmetros incluir($conecta,$ednum,$ednome,$edsobre); de função os identificadores break; definidos no documento case "3": HTML, caso a função alterar($conecta,$ednum,$ednome,$edsobre); necessite de seus valores. break; case "4": excluir($conecta,$ednum); break; default: echo("operacao [". $Escolha. "] nao reconhecida"); break; else echo("erro na conexão ". mysql_error(). "\n"); mysql_close($conecta);?> Note que a função mysql_error() retorna, como um string, a mensagem de erro correspondente a uma operação SQL inválida. Isto ajuda na depuração do script PHP. ELFS, 2003 177
Devido à característica de ser processado pelo lado do servidor, um programa PHP não consegue interagir com os usuários depois que as páginas HTML são montadas e enviadas ao navegador. Entretanto, muitas vezes é preciso realizar tarefas na própria página como, por exemplo: validação de campos digitados pelo usuário, preenchimento dinâmico de listas com base em parâmetros informados na página, abertura de novas janelas, redirecionamento para outras páginas. Nestes casos, é mais interessante utilizar JavaScript. Considere, por exemplo, que no formulário de edição da tabela alunos desejamos garantir que o usuário digitou o número do aluno como uma sequência de 5 dígitos e que os dois primeiros dígitos devem ser iguais a "98" ou "99", antes que este dado seja enviado ao script PHP. Neste caso, podemos rescrever o documento HTML que define o formulário como: <html> <head><title>edição de Tabelas com PHP</title> <SCRIPT language="javascript"> function verifica_numero(valor) if (valor.length!= 5) alert("digite um número de 5 dígitos"); aula06_04.htm Os acréscimos ao documento aula06_03.htm aparecem em destaque. ELFS, 2003 178
ano = valor.substr(0,2); if (ano!= "98" && ano!= "99") alert("os dois primeiros dígitos devem ser '98' ou '99'"); num = valor.substr(2,3); ok = true; for (i = 0; i < 3; i++) if ( isnan(num.substr(i,1)) ) ok = false; if (!ok) alert("o número do aluno deve conter apenas dígitos!"); </SCRIPT> </head> <body> <form name="edtab" action="aula06_03.php" method="post"> <h1>alunos de DAI</h1> <p>número: <input type="text" name="ednum" size="10" maxlength="5" onchange="verifica_numero(ednum.value);"></p> <p>nome: <input type="text" name="ednome" size="30" maxlength="20"></p> <p>sobrenome: ELFS, 2003 179
<input type="text" name="edsobre" size="30" maxlength="20"></p> <br> <p> Operação: <input type="radio" name="escolha" value="1" checked>listar</input> <input type="radio" name="escolha" value="2">incluir</input> <input type="radio" name="escolha" value="3">alterar</input> <input type="radio" name="escolha" value="4">excluir</input> </p> <input type="reset" value="limpar"> <input type="submit" value="executar"> </form> </body> </html> Considere o seguinte formulário HTML, cujo código é apresentado a seguir. Neste formulário, quando o usuário clicar no botão Enviar, dependento da opção de cadastro, será chamado o script cad_cliente.php ou o script cad_fornece.php. ELFS, 2003 180
<html> <head> <title>php e JavaScript</title> <SCRIPT language="javascript"> aula06_05.htm function mostra_estado() var estados = new Array("SP - São Paulo", "RJ - Rio de Janeiro", "MG - Minas Gerais", "ES - Espírito Santo", "RS - Rio Grande do Sul", "CE - Ceará", "GO - Goiás", "AM - Amazonas"); for (i = 0; i < estados.length; i++) if ( document.cadastro.estado.value == estados[i].substr(0,2) ) document.cadastro.nomest.value = estados[i].substr(5,30); function verifica() var erro = "Foram encontrados os seguintes erros: "; ELFS, 2003 181
var ok = true; aula06_05.htm if ( document.cadastro.nome.value.length == 0 ) erro += "\n - O nome deve ser informado"; ok = false; if ( document.cadastro.email.value.length == 0 ) erro += "\n - O e-mail deve ser informado"; ok = false; if (!ok ) alert(erro); else if ( documento.cadastro.tipo[0].cheched ) document.cadastro.action = "cad_cliente.php"; else document.cadastro.action = "cad_fornece.php"; return ok; </SCRIPT> ELFS, 2003 182
aula06_05.htm </head> <body onload="mostra_estado();"> <h1>cadastro de Clientes e Fornecedores</h1> <form name="cadastro" action="????.php" onsubmit="return verifica();"> <p>nome: <input name="nome" type="text" size="30"></p> <p>e-mail: <input name="email" type="text" size="30"></p> <p>estado: <select name="estado" size="1" onchange="mostra_estado();"> <option value="sp">sp</option> <option value="rj">rj</option> <option value="mg">mg</option> <option value="es">es</option> <option value="rs">rs</option> <option value="ce">ce</option> <option value="go">go</option> <option value="am">am</option> </select> <input name="nomest" type="text" size="30"></p> <p>cadastro: <input name="tipo" type="radio" value="1" checked>cliente <input name="tipo" type="radio" value="2">fornecedor</p> <input name="enviar" type="submit" value=" Enviar "> </form> </body> </html> ELFS, 2003 183
Exercício: Considerando o formulário dado em aula06_05.htm, escreva: a) Uma função verifica_email para testar a validade do e-mail digitado. Considere que um e-mail válido é da forma: ***@***.com.br, onde *** representa um string qualquer. b) Os scripts cad_cliente.php e cad_fornece.php. Considere um novo banco de dados cadastros, contendo as tabelas clientes e fornecedores. Crie o banco de dados e as estruturas das tabelas usando o monitor MySQL. Geração de código JavaScript com PHP Com scripts PHP é possível a geração de códigos JavaScript dinâmicos. Por exemplo: <html> <head><title>gerando JavaScript com PHP</title></head> <body> <script language="javascript"> <?php $data = date("d/m/y",time()); echo "alert('data atual = $data');";?> </script> </body></html> aula06_06.php Note que este script PHP irá completar o código JavaScript do documento HTML que será enviado ao cliente. Execute este script e clique com o botão direito sobre a página exibida e selecione a opção Exibir código-fonte para verificar o documento enviado ao cliente. ELFS, 2003 184
Evidentemente, a partir de scripts PHP é possível a geração de código JavaScript muito mais sofisticado. Como o código JavaScript é um texto, em princípio, não existem limites para a geração deste código a partir de um script PHP. Uma outra aplicação de scripts PHP é na autenticação de usuários (que, evidentemente, não pode ser feita por código JavaScript, pois o programafonte estaria disponível a qualquer cliente). Considere, por exemplo, o seguinte documento HTML: <html> <head> <title>autenticação de Usuário</title> </head> <body> <h1>autenticação</h1> <form name="usuario" action="autoriza.php"> <p>login: <input name="login" type="text" size="20"></p> <p>senha: <input name="senha" type="password" size="20"></p> <input name="entrar" type="submit" value=" Entrar "> </form> </body> </html> aula06_07.htm ELFS, 2003 185
Vamos considerar que as senhas dos usuários estão armazenadas na tabela senhas do banco de dados usuarios. Vamos considerar a criação desta tabela a partir dos seguintes comandos SQL: CREATE TABLE senhas ( login varchar(20), senha varchar(20), UNIQUE (login) ); INSERT INTO senhas VALUES ('Senne','feg2003'); O script autoriza.php pode ser escrito como: senhas.sql autoriza.php <?php // ********************************************************* // // Um script simples de autenticação de usuários // // ********************************************************* $conecta = mysql_connect("localhost","root"); if ($conecta) $sql = "select * from senhas where login = '$login'"; $query = mysql_db_query("usuarios", $sql, $conecta); $result = mysql_fetch_array($query); ELFS, 2003 186
if ($result["login"]!= $login) echo("<h1>usuário $login não cadastrado!!!</h1>"); else O tag META pode ser usado para identificar propriedades de um if ($result["senha"]!= $senha) documento HTML (autor, data de expiração, lista de palavras-chave, echo("<h1>senha não confere</h1>"); etc.) e para especificar um cabeçalho HTTP a ser passado ao navegador, permitindo que uma else URL seja carregada. echo "<META HTTP-EQUIV='REFRESH' CONTENT=\"0; URL='http://www.feg.unesp.br'\">"; mysql_free_result($query); else Note o uso da barra invertida ( \ ) para poder incluir o caractere aspas ( " ) dentro de um string. echo("erro na conexão ". mysql_error(). "\n"); mysql_close($conecta);?> ELFS, 2003 187