Webprogramozás
Horváth Győző
Egyetemi docens
1117 Budapest, Pázmány Péter sétány 1/c., 2.408-as szoba
Tel: (1) 372-2500/8469
horvath.gyozo@inf.elte.hu
Dinamikus szerveroldali webprogramozás: program állítja elő a tartalmat (HTML)
<?php
// input (?)
$tracks = [
["id" => 1, "name" => "guitar", "muted" => false],
["id" => 2, "name" => "bass", "muted" => true ],
["id" => 3, "name" => "vocal", "muted" => false],
];
// processing
$enabledTracks = array_filter($tracks, function ($track) {
return !$track["muted"];
});
// output
?>
<div id="tracks">
<?php foreach($enabledTracks as $t) : ?>
<div class="track">
<?= $t["name"] ?>
</div>
<?php endforeach ?>
</div>
GET / HTTP/1.1
Host: webprogramozas.inf.elte.hu
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: hu-hu,hu;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: __utma=159741371.1255432553.1308299517.1308299517.1308299517.1; __utma=32143338.2145495546.1326532899.1361177845.1362134456.25; __utmz=32143338.1361177845.24.12.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
Connection: keep-alive
HTTP/1.1 200 OK
Date: Wed, 03 Apr 2013 07:11:56 GMT
Server: Apache/2.2.10 (Linux/SUSE)
Last-Modified: Wed, 20 Feb 2013 08:39:44 GMT
ETag: "fe8438-6d6-4d623e65e9400"
Accept-Ranges: bytes
Content-Length: 1750
Content-Type: text/html
<!DOCTYPE html>
<html>
...
</html>
GET
)GET
)GET
, POST
)GET
, POST
)
location
, GET
)submit()
metódus, GET
, POST
)
A megadott URL kerül elküldésre
<a href="http://server.hu/index.php?adat=ELTE">Valami</a>
Általános formája
<scheme>://<host>:<port>/<path>?<query>#<fragment>
<form>
elemaction
: szerveroldali erőforrás megjelölésemethod
: HTTP metódusenctype
: a formadatok kódolása a küldés soránenctype
application/x-www-form-urlencoded
(alapértelmezett)multipart/form-data
(fájlfeltöltés, csak POST
esetén)text/plain
(levélküldés)submit
gomb megnyomásaform.submit()
meghívásaname
attribútumdisabled
név=érték
párokat készít&
jellel fűzi összename=Győző&pwd=secret&check1=value1&check2=on
enctype
attribútumname=Gy%C5%91z%C5%91&pwd=secret&check1=value1&check2=on
action-url
+ ?
+ query-string
Űrlap:
<form action="http://localhost/cgi-bin/cgi.exe" method="post">
<input type="text" name="alma" value="piros">
<input type="password" value="kek">
<input type="hidden" name="jelszo" value="titkos">
<input type="checkbox" name="check1" value="ertek1" checked>
<input type="checkbox" name="check2" checked>
<input type="submit">
</form>
Kérésszöveg (Query string)
alma=piros&jelszo=titkos&check1=ertek1&check2=on
<input>
type: text
, password
, hidden
<textarea>
<textarea></textarea>
elem között vancheckbox
, radio
value
→ on
értékselect
value
→ option
szövege az értéksize
>1 esetén ha nincs kiválasztva → nem küldi elmultiple
esetén → ugyanazon névvel több név=érték pár (pl. sel=alma&sel=szilva
)submit
file
enctype="multipart/form-data"
method="POST"
foo=1&bar=2
GET
: automatikus kérésszöveg<scheme>://<host>:<port>/<path>?<query>#<fragment>
http://pelda.hu/index.php?foo=1&bar=2
HTTP
METÓDUS /<path>?<query> VERZIÓ
Host: <host>
FEJLÉC: ÉRTÉK
...
foo=1&bar=2
POST
: automatikus kérésszövegMETÓDUS /<path>?<query> VERZIÓ
Host: <host>
FEJLÉC: ÉRTÉK
FEJLÉC: ÉRTÉK
FEJLÉC: ÉRTÉK
ÜZENETTEST
<query>
részébenSzerver → Program
HTTP → CGI
Azt határozza meg, hogy egy webszerver hogyan indíthat el egy programot és milyen módon cserél adatot vele.
REQUEST_METHOD
REMOTE_ADDRESS
CONTENT_LENGTH
HTTP_*
Accept
fejléc → HTTP_ACCEPT
környezeti változó[REMOTE_ADDR] => 188.142.184.197
[REMOTE_PORT] => 49323
[REQUEST_METHOD] => GET
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[HTTP_ACCEPT_LANGUAGE] => hu-hu,hu;q=0.8,en-US;q=0.5,en;q=0.3
Kérés URL-je (szabad paraméter: <query>
)
<scheme>://<host>:<port>/<path>?<query>#<fragment>
QUERY_STRING
)
<scheme>
→ SERVER_PROTOCOL
<host>
→ SERVER_NAME
<port>
→ SERVER_PORT
<path>
→ SCRIPT_NAME (PATH_INFO)
<query>
→ QUERY_STRING
CONTENT_LENGTH
: adatmennyiség hossza[HTTP_HOST] => webprogramozas.inf.elte.hu
[HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[HTTP_ACCEPT_LANGUAGE] => hu-hu,hu;q=0.8,en-US;q=0.5,en;q=0.3
[HTTP_ACCEPT_ENCODING] => gzip, deflate
[HTTP_REFERER] => http://webprogramozas.inf.elte.hu/~gyozke/wf2/temp/
[HTTP_COOKIE] => WACID=1263304129000A11327866; __utma=32143338.519822639.1361532995.1362426295.1363347264.4; __utmz=32143338.1362426295.3.3.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
[HTTP_CONNECTION] => keep-alive
[PATH] => /usr/sbin:/bin:/usr/bin:/sbin
[SERVER_SIGNATURE] => <address>Apache/2.2.10 (Linux/SUSE) Server at webprogramozas.inf.elte.hu Port 80</address>
[SERVER_SOFTWARE] => Apache/2.2.10 (Linux/SUSE)
[SERVER_NAME] => webprogramozas.inf.elte.hu
[SERVER_ADDR] => 157.181.161.8
[SERVER_PORT] => 80
[REMOTE_ADDR] => 188.142.184.197
[DOCUMENT_ROOT] => /srv/www/webprog
[SERVER_ADMIN] => root@webprogramozas.inf.elte.hu
[SCRIPT_FILENAME] => /home/gyozke/public_html/wf2/temp/getpost.php
[REMOTE_PORT] => 49323
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /~gyozke/wf2/temp/getpost.php
[SCRIPT_NAME] => /~gyozke/wf2/temp/getpost.php
[PHP_SELF] => /~gyozke/wf2/temp/getpost.php
[REQUEST_TIME] => 1365626159
QUERY_STRING
<query>
része → QUERY_STRING
REQUEST_METHOD
→ GET
vagy POST
QUERY_STRING
CONTENT_LENGTH
hosszan (pl. C++ getenv(str)
)fgetc(stdin)
)QUERY_STRING
is töltve lehet (URL függő)request_method = getenv("REQUEST_METHOD");
content_length_str = getenv("CONTENT_LENGTH");
content_length = atoi(content_length_str);
query_string_get = getenv("QUERY_STRING");
string query_string_post = "";
if (strcmp(request_method, "POST") == 0) {
int db = 0;
char c;
while (db < content_length && EOF != (c = fgetc(stdin))) {
query_string_post += c;
db++;
}
}
QUERY_STRING
→ $_GET
$_POST
$_SERVER
// GET kérésszöveg: alma=piros&korte=sarga
$_GET['alma']; //"piros"
$_GET['korte']; //"sarga"
// POST kérésszöveg: alma=piros&korte=sarga
$_POST['alma']; //"piros"
$_POST['korte']; //"sarga"
$_GET
: QUERY_STRING
ben érkező név=érték pároknak megfelelő tömb, ahol a név a kulcs.$_POST
: a standard inputon érkező név=érték pároknak megfelelő tömb, ahol a név a kulcs.$_SERVER
: az összes környezeti változót tartalmazza$_FILES
: a feltöltött fájlok helyét tartalmazza$_COOKIES
: a kliensről érkező sütik jelennek meg benneKliensen egy link
<a href="get.php?page=12&theme=dark">Példa hivatkozás</a>
PHP kód
var_dump($_GET);
var_dump($_POST);
Eredmény
array(2) {
["page"] => string(2) "12"
["theme"] => string(5) "dark"
}
array(0) {
}
Űrlap
<form action="post.php?page=42" method="post">
Name: <input type="text" name="name" value="somebody"> <br>
Password: <input type="password" name="pwd" value="secret"> <br>
<button type="submit" name="button" value="login">Send</button>
</form>
Eredménye
array(2) {
["page"] => string(2) "12"
}
array(3) {
["name"] => string(6) "somebody"
["pwd"] => string(6) "secret"
["button"] => string(5) "login"
}
sugar=10
→
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Kerület</title>
</head>
<body>
<p>Sugár = 10</p>
<p>Kerület = 62.83</p>
</body>
</html>
Az URL-ben adjuk át paraméterként
http://pelda.hu/kerulet.php?sugar=10
<?php
// debug
print_r($_GET);
print_r($_POST);
// input
$sugar = $_GET['sugar'];
// processing
$pi = pi();
$ker = 2 * $sugar * $pi;
// output
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Kerület</title>
</head>
<body>
<p>Sugár = <?= $sugar ?></p>
<p>Kerület = <?= $ker ?></p>
</body>
</html>
<?php
declare(strict_types=1);
// debug
print_r($_GET);
print_r($_POST);
// business logic
function kerulet(float $sugar): float {
return 2 * $sugar * pi();
}
// input
$sugar = (float)$_GET['sugar'];
// processing
$ker = kerulet($sugar);
// output
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Kerulet</title>
</head>
<body>
<p>Sugár = <?= $sugar; ?></p>
<p>Kerület = <?= $ker; ?></p>
</body>
</html>
http://localhost/circle.php
→ PHP hibákAlapértelmezett érték
// Segédfüggvény
function is_empty($input, $key) {
return !(isset($input[$key]) && trim($input[$key]) !== '');
}
$hiba = '';
$sugar = null;
// Hiány esetén alapértelmezett érték
if (is_empty($_GET, 'sugar')) {
$sugar = 0.0;
}
// Formátumellenőrzés
else if (!is_numeric($_GET['sugar'])) {
$hiba = 'A sugár nem szám!';
}
else {
$sugar = (float)$_GET['sugar'];
}
if ($hiba === '') {
// processing
$ker = kerulet($sugar);
}
Hibaüzenet
// Segédfüggvény
function is_empty($input, $key) {
return !(isset($input[$key]) && trim($input[$key]) !== '');
}
$hiba = '';
$sugar = null;
// Hiány esetén hibaüzenet
if (is_empty($_GET, 'sugar')) {
$hiba = 'A sugár megadása kötelező';
}
// Formátumellenőrzés
else if (!is_numeric($_GET['sugar'])) {
$hiba = 'A sugár nem szám!';
}
else {
$sugar = (float)$_GET['sugar'];
}
if ($hiba === '') {
// processing
$ker = kerulet($sugar);
}
Kimenet: hibaüzenet kiírása
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Kerulet</title>
</head>
<body>
<?php if ($hiba) : ?>
<p><?php echo $hiba; ?></p>
<?php else : ?>
<p>Sugár = <?php echo $sugar; ?></p>
<p>Kerület = <?php echo $ker; ?></p>
<?php endif; ?>
</body>
</html>
$_GET
vagy $_POST
)$data
)$errors
)<ul>
)filter_*()
filter_var()
és filter_var_array()
// is_numeric helyett
if (!filter_var($input['sugar'], FILTER_VALIDATE_FLOAT)) {
$hiba = 'A sugár nem szám!';
}
// Összetettebb: szűrés és validálás
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$hiba = "Nem jó e-mail formátum!";
}
// Opciók
filter_var($string, FILTER_VALIDATE_REGEXP, [
"options"=>[
"regexp"=>"/^M(.*)/",
],
]);
$errors = [];
$input = $_GET;
// Ellenőrzés
if (validate($input, $data, $errors)) {
// Beolvasás
$sugar = $data['sugar'];
// Feldolgozás
$ker = kerulet($sugar);
} else {
// Hiba: $errors tömb
}
Ajánlott
function validate($input, &$data, &$errors) {
// sugár vizsgálata
$data['sugar'] = null;
if (is_empty($input, 'sugar')) {
$errors[] = 'A sugár megadása kötelező';
}
else if (!is_numeric($input['sugar'])) {
$errors[] = 'A sugár nem szám!';
}
else {
$data['sugar'] = (float)$input['sugar'];
}
return !(bool)$errors;
}
Opcionális: útban az ellenőrző függvénykönyvtárak felé
function validate($input, $rules, &$data, &$errors) {
$errors = [];
$filtered_inputs = filter_var_array($input, $rules);
foreach ($filtered_inputs as $key => $value) {
$data[$key] = null;
if (is_null($value) || is_empty($input, $key)) {
if (isset($rules[$key]['default'])) {
$data[$key] = $rules[$key]['default'];
} else {
$errors[] = "{$key} hiányzik";
}
}
else if ($value === false) {
$errors[] = $rules[$key]['errormsg'];
}
else {
$data[$key] = $value;
}
}
return !(bool)$errors;
}
Opcionális: útban az ellenőrző függvénykönyvtárak felé
$rules = [
'sugar' => [
'filter'=> FILTER_VALIDATE_FLOAT,
'errormsg' => 'A sugár nem megfelelő formátumú!',
// 'default' => 0.0,
],
];
if (validate($input, $rules, $data, $errors)) {
//Beolvasás
$sugar = $data['sugar'];
// Feldolgozás
$ker = kerulet($sugar);
}
<?php if ($errors) : ?>
<ul>
<?php foreach($errors as $error) : ?>
<li><?= $error ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php
// debug
print_r($_GET);
print_r($_POST);
// business logic
function kerulet(float $sugar): float {
return 2 * $sugar * pi();
}
// helper function
function is_empty($input, $key) {
return !(isset($input[$key]) && trim($input[$key]) !== '');
}
function validate($input, &$data, &$errors) {
// sugár vizsgálata
$data['sugar'] = null;
if (is_empty($input, 'sugar')) {
$errors[] = 'A sugár megadása kötelező';
}
else if (!is_numeric($input['sugar'])) {
$errors[] = 'A sugár nem szám!';
}
else {
$data['sugar'] = (float)$input['sugar'];
}
return !(bool)$errors;
}
// start
$errors = [];
$input = $_GET;
// check
if (validate($input, $data, $errors)) {
// input
$sugar = $data['sugar'];
// processing
$ker = kerulet($sugar);
}
// output
?>
<?php if ($errors) : ?>
<ul>
<?php foreach($errors as $error) : ?>
<li><?= $error ?></li>
<?php endforeach; ?>
</ul>
<?php else : ?>
<p>Sugár = <?php echo $sugar; ?></p>
<p>Kerület = <?php echo $ker; ?></p>
<?php endif; ?>
http://localhost/circle.php?sugar=10
circle.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Kerulet</title>
</head>
<body>
<form action="circle.php" method="get">
Radius:
<input type="text" name="sugar" value="10">
<button>Calculate</button>
</form>
</body>
</html>
circle.php (ugyanaz)
<?php
declare(strict_types=1);
// debug
print_r($_GET);
print_r($_POST);
// business logic
function kerulet(float $sugar): float {
return 2 * $sugar * pi();
}
// helper function
function is_empty($input, $key) {
return !(isset($input[$key]) && trim($input[$key]) !== '');
}
function validate($input, &$data, &$errors) {
// sugár vizsgálata
$data['sugar'] = null;
if (is_empty($input, 'sugar')) {
$errors[] = 'A sugár megadása kötelező';
}
else if (!is_numeric($input['sugar'])) {
$errors[] = 'A sugár nem szám!';
}
else {
$data['sugar'] = (float)$input['sugar'];
}
return !(bool)$errors;
}
// start
$errors = [];
$input = $_GET;
// check
if (validate($input, $data, $errors)) {
// input
$sugar = $data['sugar'];
// processing
$ker = kerulet($sugar);
}
// output
?>
<?php if ($errors) : ?>
<ul>
<?php foreach($errors as $error) : ?>
<li><?= $error ?></li>
<?php endforeach; ?>
</ul>
<?php else : ?>
<p>Sugár = <?php echo $sugar; ?></p>
<p>Kerület = <?php echo $ker; ?></p>
<?php endif; ?>
<?php
$errors = [];
$input = $_GET;
if (count($_GET) !== 0) {
// validate
if (validate($input, $data, $errors)) {
// input
$sugar = $data['sugar'];
// processing
$ker = kerulet($sugar);
}
}
// output
?>
<body>
<?php if ($errors) : ?>
<ul>
<?php foreach($errors as $error) : ?>
<li><?= $error ?></li>
<?php endforeach ?>
</ul>
<?php endif ?>
<form action="" method="GET">
Radius:
<input type="text" name="sugar" value="10">
<button>Calculate</button>
</form>
<?php if (isset($ker)) : ?>
<p>Sugár = <?php echo $sugar; ?></p>
<p>Kerület = <?php echo $ker; ?></p>
<?php endif ?>
</body>
Írjuk vissza a kitöltött adatokat, legalább hiba esetén!
<form action="circle.php" method="get">
Sugár: <input type="text" name="sugar"
value="<?= $input['sugar'] ?? '' ?>">
<input type="submit">
</form>
<?php
// Adatszerkezetek és ezeket feldolgozó függvények
// Adatok és függvények
////////////////////////////////////////////////////////
// A kérés fogadásáért, beolvasásért, ellenőrzésért és kiírásért felelős rész
// Ellenőrzés
// Beolvasás
// Feldolgozás meghívása
// Kiírás
?>
<!-- /////////////////////////////////////////////////// -->
<!-- Megjelenítendő HTML sablonja -->
<!doctype html>
<html>
<!-- HTML sablon -->
<html>