Вы находитесь на странице: 1из 10

O PHP e o HTTP

Por: J oo Martins
rea Cientfica de Linguagens de Programao
Escola Superior de Tecnologia e Gesto
Instituto Politcnico de Beja
2006


Introduo

Vamos apresentar algumas caractersticas do protocolo HTTP, nomeadamente como
passar dados entre pginas HTML usando o PHP.

O protocolo HTTP no mantm o seu estado

O protocolo HTTP no guarda o seu estado (diz-se stateless), ou seja, no tem
memria. Quando o servidor Web recebe um pedido por parte dum cliente este lana
um processo. Quando o pedido satisfeito o processo termina e, se o mesmo cliente
torna a fazer outro pedido, lanado um outro processo novo que nada sabe acerca do
anterior.

Mesmo que tenhamos um stio Web em que a navegao seja encadeada, ou seja da
Pgina 1 s se pode ir para a Pgina 2, e da Pgina 2 para 3, e assim por diante, o
protocolo HTTP no regista o facto de que se um utilizador est na Pgina 2 este veio
da Pgina 1. No se pode criar uma varivel na Pgina 1, e esperar que esta seja
importada para a Pgina 2, as variveis associadas a uma dada pgina so destrudas
assim que se muda para outra pgina, os pedidos so independentes.

Quando um cliente preenche um formulrio em HTML, temos de usar mecanismos
especiais para passar os seus valores de modo a serem mostrados noutra pgina ou a
serem usados por um programa. O PHP fornece as ferramentas necessrias para se
conseguir estas funcionalidades.

Pode-se usar cookies ou sesses para guardar os valores associados com uma dada
pgina. Mas, para j, vamos ver como se passa informao entre pginas Web
utilizando os mtodos POST e GET do protocolo HTTP, e como criar pginas
dinmicas e manipular os dados de formulrios.

Os argumentos do GET

O mtodo GET do HTTP passa os dados duma pgina para outra como parte do URI
(Uniform Resource Indicator). O GET concatena os variveis e os seus valores ao
URL: o URL seguido do caracter ? e o seguido do nome de cada varivel separada
por : (dois pontos) do seu valor.

Exemplo:
O cdigo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-
1" />
<title>Exemplo com GET</title>
</head>
<body>

<form action="http://localhost/futebol.php" method="get">
<p><b>Name:</b><input type="text" name="nome" size="50" /></p>
<p><b>Clube:</b>
<select name="clube" size="3">
<option value="SLB">Benfica</option>
<option value="SCP">Sporting</option>
<option value="FCP">Porto</option>
<option value="Outro">Outro</option>
<option value="null">No tem</option>
</select>
<br /><br />
<input type="submit" name="submit" value="Enviar" />
</form>

</body>
</html>

Gera a pgina:



Quando o boto enviar carregado o browser constri e submete a seguinte string ao
servidor:

http://localhost/futebol.php?nome=Eusebio&clube=SLB&submit=Enviar

o script PHP invocado (futebol.php) recolhe as variveis GET da resposta do cliente,
contidos no URI, e coloca-os no array superglobal $_GET.


O cdigo PHP seguinte utiliza as variveis que recebe do script clube.hml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-
1" />
<title>Ainda o exemplo com o GET</title>
</head>

<body>
<?php
echo 'Ento o ' . $_GET['nome'] . ' do '. $_GET['clube'] . '!';
?>
</body>
</html>

e produz o resultado:




Desvantagens do mtodo GET:
No adequado para logins e passwords j que estes ficam visveis no URI
enviado.
Todos os submisses do tipo GET ficam registados no log do servidor.
A dimenso do URL limitada. Quando se submete grande quantidade de
dados pode dar-se o caso de alguns se perderem (a especificao original do
HTML sugeria 255 caracteres, um risco ultrapassar este valor!).

O seu uso recomendado apenas na submisso de dados a um motor de busca. O
GOOGLE utiliza o mtodo GET:

http://www.google.pt/search?hl=pt-PT&q=php+get&meta=


O mtodo POST

O mtodo POST o mais adequado para transmisso de dados entre cliente e
servidor, nomeadamente o acesso a base de dados.

O mtodo POST tm as vantagens:
mais seguro que o GET dado que a informao introduzida pelo utilizador
nunca visvel na string do URL, nos logs do servidor, ou no cran.
O limite da quantidade de dados que se pode submeter muito maior
(alguns kB).

As suas desvantagens so:
Os resultados no podem ser registados (bookmarked).
Os dados tm uma validade, estipulado pelo browser, de modo que ocorre um
erro se o utilizador revisitar a pgina com o boto de Back.
Pode ser incompatvel com algumas firewalls, que analisa os dados como
forma de segurana.


Os dados submetidos com o mtodo POST esto disponveis no array superglobal
$_POST.

Formatao de variveis de formulrios

O PHP assigna, automaticamente, as variveis quando se submete a variveis com os
mtodos GET ou POST.

Por isso cada campo input do formulrio deve de ter um nome, assignado atravs do
seu atributo name.

No script:

<FORM ACTION=<?php echo $_SERVER[PHP_SELF]; ?>
METHOD=POST>
<INPUT TYPE=text NAME=email>
<INPUT TYPE=submit NAME=submit VALUE=Send>
</FORM>

O campo de texto com o nome email leva criao duma varivel $_POST[email]
ou simplesmente a varivel $email se a directiva register_globals estiver on no
ficheiro de configurao php.ini. O boto de submit tambm leva criao da
varivel $_POST[submit]: o nome usado no formulrio o nome da varivel!

Os nomes dos campos do formulrio no de comear por um nmero, dado que as
variveis em PHP no podem comear por nmeros, e tambm so case sensitive.

Se se pretender que o formulrio apresente valores por defeito os seus campos tm de
possuir o atributo value. Isto particularmente relevante para formulrios que
recebem valores duma base de dados, ou que tm de ser submetidos mais do que uma
vez (muito comum no caso do formulrio ser preenchido com erros).

Exemplo:
Formulrio com valores preenchidos por defeito:

<HTML>
<HEAD>
<TITLE>
A POST example: retirement savings worksheet
</TITLE>
<STYLE TYPE="text/css">
<!--
BODY {font-size: 14pt}
.heading {font-size: 18pt; color: red}
-->
</STYLE>
</HEAD>
<?php
// This test, along with the Submit button value in the form
// below, will check to see if the form is being rendered for
// the first time (in which case it will display with only the
// default annual gain filled in).
if (!IsSet($_POST['Submit']) || $_POST['Submit'] != 'Calculate')
{
$_POST['CurrentAge'] = "";
$_POST['RetireAge'] = "";
$_POST['Contrib'] = "";
$Total = 0;
$AnnGain = 7;
}
else {
$AnnGain = $_POST['AnnGain'];
$Years = $_POST['RetireAge'] - $_POST['CurrentAge'];
$YearCount = 0;
$Total = $_POST['Contrib'];
while ($YearCount <= $Years) {
$Total = round($Total * (1.0 + $AnnGain/100) +
$_POST['Contrib']);
$YearCount = $YearCount + 1;
}
}
?>
<BODY>
<DIV ALIGN="CENTER" ID="Div1" class="heading">
A retirement-savings calculator
</DIV>
<P class=blurb>
Fill in all the values (except Nest Egg")
and see how much money you'll have for your retirement
under different scenarios. You can change the values and
resubmit the form as many times as you like. You must fill
in the two Age" variables. The Annual return" variable has
a default inflation-adjusted value (7% = 8% growth minus 1%
inflation) which you can change to reflect your greater
optimism or pessimism.
</P>
<FORM ACTION="<?php echo $_SERVER['PHP_SELF']; ?>" METHOD="POST">
<P>Your age now: <INPUT TYPE="text" SIZE=5 NAME="CurrentAge"
VALUE="<?php echo $_POST['CurrentAge'];?>">
</P>

<P>The age at which you plan to retire:
<INPUT TYPE="text" SIZE=6 NAME="RetireAge" VALUE="<?php echo
$_POST['RetireAge']; ?>">

<P>Annual contribution:<INPUT TYPE="text" SIZE=15 NAME="Contrib"
VALUE="<?php echo $_POST['Contrib']; ?>"></P>

<P> Annual return:<INPUT TYPE="text" SIZE=5 NAME="AnnGain"
VALUE="<?php echo $AnnGain; ?>">
<BR /> <BR />
<P><B>NEST EGG</B>:<?php echo $Total; ?></P>

<P><INPUT TYPE="submit" NAME="Submit" VALUE="Calculate"></P>
</FORM>
</BODY>
</HTML>
que resulta no formulrio:



Os formulrios e a sua manipulao

comum utilizar o mesmo script para definir e tratar o formulrio. O que torna mais
fcil mostrar erros do preenchimento dos formulrios e fornece um maior controlo
sobre o nome das variveis.

O cdigo de manipulao do formulrio aparece antes deste ser mostrado, o que d
oportunidade de decidir o que se vai mostrar ao utilizador: uma mensagem de erro -
caso o utilizador tenha introduzido mal os dados, ou os campos obrigatrios que o
utilizador no preencheu, por exemplo. Pode-se estabelecer o valor das variveis ou
redireccionar o utilizador para outra pgina.

Existem duas formas de saber se o formulrio j foi submetido alguma vez: pode-se
usar o valor do boto submit, ou pode-se usar uma varivel escondida.

Utilizao de variveis do tipo array em formulrios

O PHP permite fazer o POST duma varivel do tipo array.

Exemplo:

O segmento de cdigo seguinte mostra a utilizao dum array para guardar os valores
das respostas

<?php
/******************************************************
* "How geeky are you?" script, showing with screens. *
* Screen 1: : quiz form. Screen 2: results page. *
******************************************************/
// The header which appears in both cases
// -------------------------------------------
$header_str = <<< EOHEADER
<HTML>
<HEAD>
<STYLE TYPE="text/css">
<!--
BODY, P, TD {color: black; font-family: verdana; font-size: 9 pt}
H1 {color: black; font-family: arial; font-size: 12 pt}
-->
</STYLE>
</HEAD>
<BODY>
<TABLE BORDER=0 CELLPADDING=10 WIDTH=100%>
<TR>
<TD BGCOLOR="#F0F8FF" ALIGN=CENTER VALIGN=TOP WIDTH=150>
</TD>
<TD BGCOLOR="#FFFFFF" ALIGN=LEFT VALIGN=TOP WIDTH=83%>
<table cellspacing=0 cellpadding=20 border=0 width="530"><tr><td
valign=top>
EOHEADER;

// The footer which appears in both cases
// --------------------------------------
$footer_str = <<< EOFOOTER
</td></tr></table>
</TD></TR></TABLE>
</BODY>
</HTML>
EOFOOTER;

// Screen 1: quiz form
// -------------------
$quiz_str = <<< EOQUIZ
<h2>How geeky are you?</h2>
<form action="geek_quiz.php" method="POST">
<br /><br />
0. Have you ever had a dream in which you were debugging?<br />
Yes <input type="checkbox" name="affirm[0]" value="1"/>
<br /><br />
1. Do you know the name of the company founded by Danny
Hillis?<br />
Yes <input type="checkbox" name="affirm[1]" value="1"/>
<br /><br />
2. Can you edit a file in both emacs and vi without recourse to
any documentation?<br />
Yes <input type="checkbox" name="affirm[2]" value="1"/>
<br /><br />
3. Is the computer you are using at this moment hooked up to a
KVM switch?<br />
Yes <input type="checkbox" name="affirm[3]" value="1"/>
<br /><br />
4. Are you wearing a logowear T-shirt?<br />
Yes <input type="checkbox" name="affirm[4]" value="1"/>
<br /><br />
5. Have you ever written a chess program?<br />
Yes <input type="checkbox" name="affirm[5]" value="1"/>
<br /><br />
6. Have you ever set up an SMTP server?<br />
Yes <input type="checkbox" name="affirm[6]" value="1"/>
<br /><br />
7. Have you ever discussed the merits of a commercial LISP
implementation?<br />
Yes <input type="checkbox" name="affirm[7]" value="1"/>
<br /><br />
8. Have you ever used the phrase:I can do that in two lines of
code, in public?<br />
Yes <input type="checkbox" name="affirm[8]" value="1"/>
<br /><br />
9. Have you ever refused an otherwise welcome sexual advance
because you were debugging?<br />
Yes <input type="checkbox" name="affirm[9]" value="1"/>
<br /><br />
<input type="submit" name="submit" value="Evaluate"></form>
EOQUIZ;

// ------------------
// Now for some logic
// ------------------
echo $header_str;
if (!isSet($_POST['submit'])) {
// First time, show the quiz form
echo $quiz_str;
} elseif ($_POST['submit'] == 'Evaluate') {
// Count up the yes answers
$num_affirm = count($_POST['affirm']);
// Come up with 4 different blurbs
if ($num_affirm >= 0 && $num_affirm <= 3) {
$result_str = "<P>Why even pretend to be something you are so
clearly not?</P>\n";
}
elseif ($num_affirm >= 4 && $num_affirm <= 6) {
$result_str = "<P>Come back when you've learned more craft,
Grasshopper.</P>\n";
} elseif ($num_affirm >= 7 && $num_affirm <= 8) {
$result_str = "<P>Pretty geeky, but not yet a Code
God.</P>\n";
} elseif ($num_affirm >= 9 && $num_affirm <= 10) {
$result_str = "<P>We're not worthy to be in the presence of
your bad geeky self!</P>\n";
}
echo $result_str;
}
echo $footer_str;
?>




Que resulta em



A resposta depende apenas do nmero de respostas afirmativas que o utilizador
assinalou:



Arrays superglobais do PHP

Os arrays $_GET, $_POST, $_COOKIE, $_ENV e $_SERVER esto disponveis em
qualquer script: so variveis globais por defeito. A disponibilidade destes arrays no
PHP 5.0 constitui um incremento na segurana.


Adaptado de:

Tim Converse, J oyce Park, Clark Morgan, PHP5 and MySQL Bible, Wiley
Interscience, 2004.