Prévia do material em texto
AN02FREV001/REV 4.0
1
PROGRAMA DE EDUCAÇÃO CONTINUADA A DISTÂNCIA
Portal Educação
CURSO DE
AJAX E PHP COMO LINGUAGEM
DE SERVIDOR
Aluno:
EaD - Educação a Distância Portal Educação
AN02FREV001/REV 4.0
2
CURSO DE
AJAX E PHP COMO LINGUAGEM
DE SERVIDOR
MÓDULO IV
Atenção: O material deste módulo está disponível apenas como parâmetro de estudos para
este Programa de Educação Continuada. É proibida qualquer forma de comercialização ou
distribuição do mesmo sem a autorização expressa do Portal Educação. Os créditos do
conteúdo aqui contido são dados aos seus respectivos autores descritos nas Referências
Bibliográficas.
AN02FREV001/REV 4.0
3
SUMÁRIO
1 DETALHANDO O DOM (DOCUMENT OBJECT MODEL)
1.1 FUNÇÃO JAVASCRIPT PARA MUDANÇA DE CONTEÚDO
1.2 MANIPULAÇÃO DE CONTEÚDO HTML
1.3 MANIPULAÇÃO DE FORMULÁRIOS
1.4 ENVIANDO DADOS USANDO O MÉTODO POST
1.5 MANIPULAÇÃO DE EVENTOS
1.6 ONDE USAR E ONDE NÃO USAR
REFERÊNCIAS BIBLIOGRÁFICAS
AN02FREV001/REV 4.0
4
1 DETALHANDO O DOM (DOCUMENT OBJECT MODEL)
1.1 FUNÇÃO JAVASCRIPT PARA MUDANÇA DE CONTEÚDO
A base para o uso de funcionalidades que empregam o AJAX foi
abordado no capítulo anterior. Possuir conhecimentos aprofundados nas
diversas tecnologias que compõem a arquitetura fará com que qualquer
integração seja mais facilmente integrada. Este capítulo mostra maneiras de
tornar esses códigos reaproveitados e simples de serem utilizados. O primeiro
passo será transformar a função de conexão mostrada acima em um
componente que possa ser utilizado em outros trechos de código. Algo na
seguinte linha:
<script language="javascript">
var req;
function abre_conexao() {
req = false;
if (window.XMLHttpRequest && !(window.ActiveXObject)) {
try {
req = new XMLHttpRequest();
} catch(e) {
req = false;
}
} else if(window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
req = false;
}
}
}
}
</script>
AN02FREV001/REV 4.0
5
Toda função que desejar requisitar de forma assíncrona algum
conteúdo do servidor deve antes fazer uma chamada à função definida acima,
que na prática apenas abre e deixa disponível uma conexão com o servidor.
Esse trecho pode ser colocado num arquivo separado escrito em Javascript, de
forma que todos os arquivos usem esse mesmo trecho de código. Em seguida,
a reescrita da função mostrada acima ficaria assim:
function recupera_data_servidor(url) {
abre_conexao();
if (req) {
req.onreadystatechange = alerta_resultado;
envio = url + "?formato=" + get_idioma_escolhido();
req.open("GET", envio, true);
req.send("");
} else {
alert("Houve um erro ao estalecer uma conexao.");
}
}
function get_idioma_escolhido() {
for (i = 0; i < document.forms[0].idioma.length; ++i) {
if (document.forms[0].idioma[i].checked) {
return document.forms[0].idioma[i].value;
}
}
}
function alerta_resultado() {
if (req.readyState == 4) {
alert(req.responseText);
}
}
Agora, para cada comportamento diferente desejado deveria ser escrita
uma nova função, que chamaria a função de conexão e definiria o seu
comportamento específico. A partir de agora, com esta modularização, os
exemplos vão sempre considerar chamar a função abre_conexao() antes de
qualquer processo que faça requisições para o servidor.
AN02FREV001/REV 4.0
6
1.2 MANIPULAÇÃO DE CONTEÚDO HTML
Uma tarefa que sempre é necessária e comum de se encontrar em
páginas é a alteração de algum conteúdo baseado na resposta que o servidor
de aplicações devolver para a página. Por exemplo, pode-se alterar a cor e
texto de exibição de uma parte do sistema. Neste trecho de código em PHP
será retornada uma palavra baseado no segundo do servidor que estiver
configurado no momento:
<?php
$segundo = date("s");
$opcao = $segundo % 3;
$retorno = "";
switch ($opcao) {
case 0:
$retorno = "Primeira opcao";
break;
case 1:
$retorno = "Segunda opcao";
break;
case 2:
$retorno = "Terceira e ultima opcao";
break;
}
echo $retorno;
?>
O trecho de código acima recupera o valor do segundo no instante em
que a página é chamada, é feito o resto da divisão inteira pelo valor três e com
base no valor resultante da operação, algum dos textos é escolhido, sendo
então escrito na saída padrão, que tanto pode ser a tela, caso a página fosse
invocada num navegador, como escrito de volta para a função Javascript que a
estiver invocando. Do lado cliente pode ser escrita uma página que faz a
chamada da seguinte forma:
AN02FREV001/REV 4.0
7
<html>
<head>
<script language="javascript">
var req;
function abre_conexao() {
req = false;
if (window.XMLHttpRequest && !(window.ActiveXObject)) {
try {
req = new XMLHttpRequest();
} catch(e) {
req = false;
}
} else if(window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
req = false;
}
}
}
}
function altera_texto() {
abre_conexao();
if (req) {
req.onreadystatechange = muda_conteudo_texto;
envio = "retorna_texto.php";
req.open("GET", envio, true);
req.send("");
} else {
alert("Houve um erro ao estalecer uma conexao.");
}
}
function muda_conteudo_texto() {
if (req.readyState == 4) {
document.getElementById("caixa_texto").innerHTML += ", " +
req.responseText;
}
}
AN02FREV001/REV 4.0
8
</script>
</head>
<body>
<div
id="caixa_texto"
style="color:green">Valor inicial</div>
<input
type="button"
value="Trocar" onclick="altera_texto()" />
</body>
</html>
Ao abrir a primeira vez essa página, o resultado exibido na tela será:
FIGURA 1 - PÁGINA ABERTA PELA PRIMEIRA VEZ, SEM NENHUMA
REQUISIÇÃO FEITA AO SERVIDOR
FONTE:Arquivo pessoal do autor.
Depois de algumas execuções, o resultado será:
AN02FREV001/REV 4.0
9
FIGURA 2 - RESULTADO DE DIVERSAS REQUISIÇÕES
FONTE: Arquivo pessoal do autor.
O resultado de se pressionar diversas vezes o mesmo botão são as
diversas chamadas para o mesmo código no servidor. Voltemos um pouco para
analisar os pontos de destaque deste código no cliente (imaginando que no
servidor o código é relativamente simples). Toda a inteligência está nas
funções altera_texto() e muda_conteudo_texto(), que são invocadas
ao pressionar o botão na interface gráfica. A primeira função não traz nada de
novo, apenas uma chamada para a função que estabelece uma conexão com o
servidor e a definição do que fazer quando a requisição devolver o conteúdo
requisitado (no caso, a segunda função).
Já a função muda_conteudo_texto() traz alguns conceitos novos.
Ela ainda continua testando para o estado de retorno da função, só que agora
faz uso de um método disponibilizado a partir do modelo DOM. O objeto
document possui um método chamado getElementById(), que permite
recuperar qualquer estrutura que tenha sido nomeada com um código único na
página, que no nosso exemplo é a tag <div>. Uma vez recuperado o objeto
correto, podemos manipulá-lo da forma que acharmos necessário.
Para o caso de alterar o conteúdo HTML de um componente
(lembrando que um <div> é uma “tag vazia”, que permite que qualquer outro
conteúdo seja colocado dentro dela), isso sendo feito por meio da propriedade
AN02FREV001/REV 4.0
10
innerHTML, que tanto recupera quanto escreve o conteúdo na marcação. A
lógica se completa ao fazer com que o conteúdo anterior seja mantido na tag e
acrescentado o valor que for enviado pelo servidorna requisição criada pela
função. O trecho do HTML em si é simples, apenas com a definição da tag
<div> e do botão que dispara a ação.
1.3 MANIPULAÇÃO DE FORMULÁRIOS
Originalmente, no início da internet, toda e qualquer validação só era
possível ser feita por meio de processamento no servidor, pois o HTML não
oferecia (e continua a não oferecer) recursos de lógica que permitam manusear
dados. Vendo essa necessidade, foi introduzida a tecnologia Javascript, que
permite ainda, no lado cliente, realizar operações sobre os dados que foram
digitados pelos usuários ou que foram carregados durante a inicialização do
sistema.
Só que dependendo do nível de validação que se deseja fazer, muitas
informações precisam ser carregadas na página cliente, tornando-a
extremamente pesada. Pense na seguinte situação, de validação de e-mail:
existe um sistema em que é necessária a validação do endereço de e-mail
informado e que impede que o cadastro siga se houver o mesmo endereço já
cadastrado no sistema. Duas abordagens possíveis:
• Depois que o usuário preencher a informação desejada, o formulário é
submetido para o servidor, alguma linguagem de programação, como o
PHP, consulta a informação na base de dados e caso ela seja inválida,
retorna o fluxo para a tela de cadastro, informando do erro e pedindo
para que o usuário informe um endereço de e-mail diferente.
• Todos os endereços de e-mails já cadastrados são carregados na
página cliente, armazenados, por exemplo, num vetor Javascript, com
todos os valores possíveis. Caso a base de dados seja muito grande, o
vetor gerado será muito grande e consequentemente o tamanho do
AN02FREV001/REV 4.0
11
arquivo em que será aberto no navegador também será grande,
tornando todo o processo de abertura mais lento.
Outro aspecto negativo da segunda abordagem está no fato de que
uma informação extremamente sensível e valiosa da empresa estaria sendo
visível para qualquer pessoa que se interessasse em verificar o código-fonte da
página. Com o advento da plataforma AJAX, uma terceira opção está
disponível: validar os dados conforme o usuário digita o endereço, a validação
é feita e caso esteja incorreta, o usuário recebe um retorno imediato,
permitindo que o erro seja corrigido. Não entraremos, por hora, em como fazer
isso usando um banco de dados, mas usaremos endereços fixos para
exemplificar como o processo deve ser feito. Começando pelo arquivo no
servidor, sempre escrito em PHP:
<?php
$email = "";
if (isset($_GET['email'])) {
$email = $_GET['email'];
}
$invalido = 0;
if ($email) {
if ($email == 'teste@pe.com.br') {
$invalido = 1;
} else if ($email == 'valido@pe.com.br') {
$invalido = 1;
}
}
echo $invalido;
?>
O código acima simplesmente verifica se existe um e-mail passado
como parâmetro usando o método GET e caso ele exista, se possui um dos
AN02FREV001/REV 4.0
12
dois valores testados. Imaginando um sistema real, essa chamada com valores
fixos deveria ser trocada por uma consulta ao banco de dados, como será vista
abaixo. O retorno deste código será sempre 1 ou 0, representando
respectivamente que o e-mail não é válido ou que ele é válido. Novamente,
uma chamada direta ao arquivo é possível para fins de teste.
O código no lado do cliente será um formulário simples, com um campo
em que será informado o e-mail para validação e um botão, que deverá
disparar a requisição quando o preenchimento for finalizado. A interface gráfica
será a seguinte:
FIGURA 3 - FORMULÁRIO SIMPLES, PARA TESTES DE VALIDAÇÃO
FONTE: Arquivo pessoal do autor.
Ela é simples, com um campo texto e mais um botão. Inicialmente o
campo está vazio, sem que nenhuma informação seja preenchida. Caso o
usuário comece a digitar e exista um e-mail que conflite por já existir no banco
de dados, uma mensagem de erro será mostrada, como abaixo:
AN02FREV001/REV 4.0
13
FIGURA 4 - MENSAGEM DE ERRO APÓS O PREENCHIMENTO DE UM
VALOR JÁ EXISTENTE
FONTE: Arquivo pessoal do autor.
A mensagem de erro será mostrada assim que o usuário digitar a
última letra que coincida com algo já existente. Caso ele corrija, imediatamente
a mensagem de erro desaparece. O código no cliente que gera o
comportamento acima é definido a seguir:
<html>
<head>
<script language="javascript">
function valida_email() {
abre_conexao();
if (req) {
req.onreadystatechange = retorno_email;
envio = "email_valido.php?email=" +
document.forms[0].email.value;
req.open("GET", envio, true);
req.send("");
} else {
alert("Houve um erro ao estalecer uma conexao.");
}
}
AN02FREV001/REV 4.0
14
function retorno_email() {
if (req.readyState == 4) {
nok = req.responseText;
if (nok == 1) {
document.getElementById("msg_err").innerHTML = "Email
invalido";
} else {
document.getElementById("msg_err").innerHTML = "";
}
}
}
</script>
</head>
<body>
<form>
Email: <input
type="text"
name="email"
onkeyup="valida_email()" />
<div id="msg_err" style="color:red"></div>
<input type="button" value="Enviar" />
</form>
</body>
</html>
Novamente, a função de conexão foi omitida. O bloco que monta o
HTML possui uma chamada a função valida_email(), só que ela é
executada a cada vez que a tecla é liberada depois que um texto foi digitado no
campo, sendo isso feito por intermédio do evento onkeyup. O bloco <div>
inicialmente não possui qualquer conteúdo, pois não existe nenhum erro até o
momento que a informação coincida com o que foi encontrado no servidor, mas
de qualquer forma, o conteúdo do texto que estiver ali presente, deverá ser
exibido na cor vermelha, identificando um erro.
Outro ponto que merece destaque está na função retorno_email()
que trata o que o servidor retornar como resposta para a requisição. Nela, caso
o retorno seja o valor 1, indicando que o e-mail não é válido, o conteúdo do
<div> é alterado para a mensagem de erro ali definida. Por outro lado, caso o
retorno seja de que o e-mail continua válido, nenhuma mensagem é escrita no
campo. Isso garante que mesmo que caso aconteça algum erro num
determinado momento ele será apagado caso o usuário corrija a informação,
tornando o formulário válido novamente.
AN02FREV001/REV 4.0
15
Uma boa estratégia para evitar que submissões aconteçam em
formulários maiores que contenham erros é definir uma variável interna no
Javascript que armazena todos os erros existentes no momento da submissão,
caso essa variável não seja vazia, impeça que a submissão ocorra, o que
geraria desperdício de processamento no lado do servidor, pois os dados com
certeza não estarão corretos.
1.4 ENVIANDO DADOS USANDO O MÉTODO POST
Todas as requisições mostradas até agora foram do tipo GET, em que
os dados são enviados na própria URL, concatenados e transmitidos junto com
o nome do arquivo ao qual a requisição será direcionada. Eventualmente, caso
a quantidade de dados para ser manuseada seja muito grande ou sensível
(não se deseja que essas informações sejam facilmente vistas) pode ser
desejável o uso do método POST que, como visto, empacota o conteúdo num
pacote separado e o envia para o servidor. Pensando no código cliente escrito
usando os conceitos do AJAX, as mudanças são relativamente pequenas:
function valida_email() {
abre_conexao();
if (req) {
req.onreadystatechange = retorno_email;
params = "email=" +
encodeURI(document.forms[0].email.value);
req.open("POST", "email_valido.php", true);
req.setRequestHeader("Content-type", "application/x-www-
form-urlencoded");
req.setRequestHeader("Content-length", params.length);
req.setRequestHeader("Connection", "close");
req.send(params);
} else {
alert("Houve um erro ao estalecer uma conexao.");
AN02FREV001/REV 4.0
16
}
}
O trechoacima mostra o mesmo comportamento do mostrado acima,
só que a maneira de enviar os dados é ligeiramente diferente. Primeiro, os
parâmetros continuam concatenados como uma query string, só que são
armazenados dentro de uma variável Javascript qualquer, que neste caso foi
chamada de params, indicando os parâmetros que serão passados como
argumento para o servidor. Segundo, a função que abre a conexão com o
servidor passa como primeiro argumento agora o valor POST (anteriormente
era GET).
São acrescentadas também três chamadas a uma função que adiciona
alguns cabeçalhos especiais à requisição que será gerada. Nesses cabeçalhos
são escritos quais os tipos de dados que serão enviados para o servidor, o
número de caracteres que será remetido como parâmetro e que após a
conclusão da requisição, que a conexão precisa ser fechada. Por último, o
método send() passa a receber a variável Javascript que guarda os
parâmetros (anteriormente era uma string vazia).
1.4 MANIPULAÇÃO DE EVENTOS
Até o momento foram usados dois eventos principais do modelo DOM
associados a estruturas do HTML: onclick e onkeyup, só que existe uma
infinidade de eventos, cada um deles associados a componentes diferentes do
HTML. A lista abaixo detalha os principais eventos e como eles podem ser
utilizados para determinadas situações:
• onblur: Executa um código quando um elemento, janela ou quadro,
perde o foco. Usado para os componentes botão, checkbox, fileupload,
senha, radio, reset, select, submit, text, textarea e window. Muito
utilizado para validação do campo assim que o usuário passa para o
AN02FREV001/REV 4.0
17
próximo, pois garante que todo o texto já foi digitado, evitando
requisições desnecessárias para o servidor, validando conteúdo ainda
não finalizado.
• onchange: Executa um código quando um campo perde o foco e tem
seu valor modificado. Usado para fileupload, select, text, textarea. Sendo
sua maior aplicação em campos do tipo select que carregam outra caixa
de elementos quando outra opção é escolhida na primeira lista de
valores.
• onclick: O já conhecido onclick executa um código Javascript quando
um objeto é clicado. Usado para botão, document, checkbox, link, radio,
reset e submit.
• ondblclick: Próximo do comportamento do onclick, só que este executa
um código quando um duplo clique é dado no objeto. Usado para
document, Link.
• onfocus: Executa um código quando o objeto recebe o foco. Usado
para botão, checkbox, fileupload, senha, radio, reset, select, submit, text,
textarea, window.
• onkeydown: Executa um código quando uma tecla é pressionada.
Usado para document, image, link, text, textarea.
• onkeyPress: Executa um código Javascript quando o usuário pressiona
ou mantém pressionada uma tecla. Usado para document, image, link,
text, textarea.
• onkeyup: Executa um código quando o usuário libera uma tecla que foi
pressionada. Usado para document, image, link, text, textarea. Em geral,
para validações de campo texto, usa-se esse evento, pois com ele o
processo de digitar algum caractere foi realizado e ele pode ser
avaliado, indicando se o texto resultante está correto ou não.
• onload: Executa um código Javascript quando o navegador termina o
carregamento de uma janela, de todos os quadros dentro de um
frameset, de uma imagem. Usado para image e window.
• onmouseover: Executa um código quando o usuário move o cursor de
fora para dentro de uma determinada área (mapa de imagem ou link).
AN02FREV001/REV 4.0
18
Usado para links. O efeito visual deste evento é muito interessante, mas
ele precisa ser usado com cuidado, pois pode gerar um número de
requisições muito grande, dado que o mouse pode passar muitas vezes
por sobre o mesmo elemento.
• onselect: Executa um código Javascript quando o usuário seleciona um
texto em uma caixa. Usado para text e textarea.
• onsubmit: Executa um código quando o usuário clica o botão submeter
de um formulário. Usado para Form. Ele acaba sendo usado mais no
processo de submissão síncrona, depois que todos os dados foram
preenchidos pelo usuário e antes que os dados sejam enviados, uma
validação completa acontece.
• onUnload: Executa um código Javascript quando o usuário sai da
janela. Usado para window.
Todos os eventos em questão ficam associados a algum componente
do HTML, estruturados dentro do modelo DOM e são escritos com a seguinte
sintaxe:
evento = “código ou função javascript para ser executada”
Por questão de organização do código, sempre fica mais fácil delimitar
todo o código em questão dentro de uma função Javascript e chamar apenas
ela, do que encadear todos os comandos necessários entre as aspas próximas
ao evento.
1.6 ONDE USAR E ONDE NÃO USAR
Essa é uma questão de projeto crítica, pois deve levar em
consideração o tempo disponível e os requisitos que se deseja construir. Por
questão de projeto, o código necessário para uma solução usando AJAX tende
a ser espalhado pelos diversos pontos do sistema, então caso não exista
tempo para tornar tudo organizado e simples, pode ser muito complexo manter
AN02FREV001/REV 4.0
19
as adaptações e conservações futuras.
Isso é especialmente verdade quando se usa o AJAX de forma pura,
diretamente, sem o auxílio de qualquer framework que auxilie nesse
desenvolvimento, pois essas bibliotecas trazem consigo todo um conjunto de
padrões de escrita que facilitam a vida da equipe de desenvolvimento quando
estiverem trabalhando no código. Nesse material será abordado de forma
simplificado o uso do JQuery para criar soluções que usem AJAX e que
possam ser facilmente aplicadas em outros sistemas.
Outro fator a ser levado em consideração é o nível de experiência
interativa que se deseja oferecer ao usuário. Usar a tecnologia simplesmente
porque ela existe e está disponível, sem conhecer suas práticas e limitações
pode ser um grande erro, pois ela acaba sendo facilmente descontinuada.
Sendo assim, é importante ter em mente o que se deseja oferecer ao usuário,
quais premissas do sistema atual serão mudadas e o que ele ganhará ao
receber um sistema que se comporta de forma diferente, com mais e diferentes
recursos.
Talvez esse último ponto seja o mais interessante ao se abordar a
questão do uso ou não da tecnologia, pois é ele quem irá oferecer novas
funcionalidades para o sistema. Validação dinâmica de formulários, exibição de
mensagens de erro, atualização de partes dinâmicas diretamente do banco de
dados, atualização das informações do sistema e todo um grande conjunto de
funcionalidades, se forem agregadas para facilitar a vida do usuário do sistema
tendem a ser muito bem vistas.
E o grande exemplo desse uso extensivo da tecnologia é o próprio
Google. A grande maioria dos seus atuais sistemas, seja de uso corporativo,
seja de uso para o usuário final possuem técnicas e recursos que só são
possíveis graças à plataforma que o AJAX trouxe e ofereceu para a
comunidade de desenvolvimento. Ao construir os sistemas desta forma a
empresa está aproximando dos seus sistemas da internet algo que só era
possível com os sistemas que rodavam no desktop dessas mesmas pessoas,
com recursos e ferramentas que davam maiores liberdades às pessoas que
faziam essas interfaces gráficas.
AN02FREV001/REV 4.0
20
REFERÊNCIAS BIBLIOGRÁFICAS
IMASTER. Disponível em: <http://www.imaster.com.br>. Acesso em:
25.10.2010.
JQUERY. Disponível em: <http://jquery.com/)>. Acesso em: 25.10.2010.
PHP. Disponível em: <http://www.php.net>. Acesso em: 25.10.2010.
WEC. Disponível em: <http://www.w3c.org>. Acesso em: 25.10.2010.
WIKIPEDIA. Disponível em:
<http://pt.wikipedia.org/wiki/AJAX_(programa%C3%A7%C3%A3o)>. Acesso
em: 23.10.2010.
WIKIPEDIA. Disponível em: <http://pt.wikipedia.org/wiki/Internet_rica)>. Acesso
em: 23.10.2010.FIM DO MÓDULO IV