Webprogramozás

Kliensoldali adatok mint bemenet, űrlapfeldolgozá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

Ismétlés

Ismétlés

Dinamikus szerveroldali webprogramozás: program állítja elő a tartalmat (HTML)

  • PHP nyelv
    • Adatszerkezetek
    • Programozási tételek
  • Program szerkezete
    • beolvasás
    • feldolgozás
    • kiírás
  • Kimenet (HTML)
    • statikus prototípus → dinamikus sablon
    • PHP alternatív szintaxisa

Ismétlés

<?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>

HTTP

Kérés

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
   

Válasz

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>

Szerverprogram bemeneti adatai

Kliensről érkező adatok

Böngésző

Kérésindítási lehetőségek

  • Cím beírása (GET)
  • Linkre kattintás (GET)
  • Űrlap elküldése (GET, POST)
  • JavaScript (GET, POST)
    • oldal újratöltés (location, GET)
    • űrlap elküldés(submit() metódus, GET, POST)
    • AJAX kérés (bármilyen HTTP metódus)

Címsor és hivatkozások

  • 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> elem

  • Attribútumok
    • action: szerveroldali erőforrás megjelölése
    • method: HTTP metódus
    • enctype: a formadatok kódolása a küldés során
  • enctype
    • application/x-www-form-urlencoded (alapértelmezett)
    • multipart/form-data (fájlfeltöltés, csak POST esetén)
    • text/plain (levélküldés)

Űrlap elküldése

  • Elküldés
    • submit gomb megnyomása
    • JavaScript: form.submit() meghívása
  • Lépések
    1. Elküldhető elemek kiválasztása
    2. Kérési adatok összeállítása
    3. Kérési adatok kódolása
    4. A kódolt kérési adatok elküldése

Űrlap elküldése

  1. Elküldhető elemek kiválasztása
    • name attribútum
    • nem disabled
    • bejelölt checkbox
    • bejelölt radio
    • kiválasztott select

Űrlap elküldése

  1. Kérési adatok összeállítása
    • Elküldhető formelemekből név=érték párokat készít
    • ezeket & jellel fűzi össze
    • name=Győző&pwd=secret&check1=value1&check2=on
  2. Kérési adatok kódolása
    • ld. enctype attribútum
    • name=Gy%C5%91z%C5%91&pwd=secret&check1=value1&check2=on
    • → Kérésszöveg (Query String)

Űrlap elküldése

  1. A kódolt kérési adatok elküldése
    • GET
      • URL: action-url + ? + query-string
      • URL mérete limitált a gyakorlatban (2 kB)
    • POST
      • a HTTP kérés üzenettörzsében utazik a kérésszöveg
      • sok adat küldhető

Űrlap elküldése – példa

Ű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

Űrlapelemek

  • Szöveges elemek
    • <input> type: text, password, hidden
    • <textarea>
    • mindig elküldésre kerülnek
    • akár üres szöveggel is
    • textareánál vigyázni kell: minden elküldésre kerül, ami a <textarea></textarea> elem között van

Űrlapelemek

  • checkbox, radio
    • csak bejelölve kerül elküldésre
    • ha nincs valueon érték
  • select
    • csak bejelölve kerül elküldésre
    • ha nincs valueoption szövege az érték
    • size>1 esetén ha nincs kiválasztva → nem küldi el
    • multiple esetén → ugyanazon névvel több név=érték pár (pl. sel=alma&sel=szilva)

Űrlapelemek

  • submit
    • ha van neve → elküldésre kerül az értékével (felirat)
  • file
    • enctype="multipart/form-data"
    • method="POST"

HTTP

GET kérések

  • Adatok
    • foo=1&bar=2
  • Felületi elemek
    • Címsor (adat kézzel)
    • Link (adat kézzel)
    • Űrlap GET: automatikus kérésszöveg
  • URL
    • <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
    ...

POST kérések

  • Adatok
    • foo=1&bar=2
  • Felületi elemek
    • Űrlap POST: automatikus kérésszöveg
  • HTTP
    • a kérésszöveg az üzenettörzsben utazik
    METÓDUS /<path>?<query> VERZIÓ
    Host: <host>
    FEJLÉC: ÉRTÉK
    FEJLÉC: ÉRTÉK
    FEJLÉC: ÉRTÉK
    
    ÜZENETTEST

Böngésző → HTTP

  • Kérésszöveg
    • URL <query> részében
    • Üzenettörzs

Common Gateway Interface

Szerver → Program

HTTP → CGI

Common Gateway Interface (CGI)

Azt határozza meg, hogy egy webszerver hogyan indíthat el egy programot és milyen módon cserél adatot vele.

  • Indítás: program futtatása
  • Adatok
    • környezeti változók
    • standard I/O

Kérés körülményei és HTTP fejlécek

  • Kérés körülményei → környezeti változók
    • HTTP kérés metódusa → REQUEST_METHOD
    • kliens IP címe → REMOTE_ADDRESS
    • üzenettest hossza bájtban → CONTENT_LENGTH
  • HTTP fejlécek → környezeti változók
    • HTTP_*
    • Pl. 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

URL

  • Kérés URL-je (szabad paraméter: <query>)

    <scheme>://<host>:<port>/<path>?<query>#<fragment>
  • URL → környezeti változók (fontos: QUERY_STRING)
    • <scheme>SERVER_PROTOCOL
    • <host>SERVER_NAME
    • <port>SERVER_PORT
    • <path>SCRIPT_NAME (PATH_INFO)
    • <query>QUERY_STRING

HTTP üzenettörzs

  • HTTP üzenettörzs szabad paraméter
  • Standard bemeneten jelenik meg
  • Környezeti változó
    • CONTENT_LENGTH: adatmennyiség hossza

Környezeti változók – példa

[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

CGI összefoglalás

  • HTTP kérés részei kerülnek átadásra a programnak
    • környezeti változók
    • standard bemenet
  • Felhasználói információ hol érkezhet (általában)
    • QUERY_STRING
    • HTTP üzenettörzs

HTTP → CGI

  • Szabad paraméterek
    • URL <query> része → QUERY_STRING
    • Üzenettörzs → Standard bemenet

CGI programok

CGI

  • CGI kommunikációja
    • környezeti változók
    • standard bemenet és kimenet
  • Programoknak tudnia kell
    • környezeti változók értékeit lekérdezni
    • olvasni a standard bemenetről
    • írni a standard kimenetre

Adatok tipikus beolvasása

  • REQUEST_METHODGET vagy POST
  • GET
    • QUERY_STRING
  • POST
    • CONTENT_LENGTH hosszan (pl. C++ getenv(str))
    • standard inputról olvasni (pl. C++ fgetc(stdin))
    • QUERY_STRING is töltve lehet (URL függő)

Példa C++ program

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++;
  }
}

CGI és PHP

Leképezés

  • Szabad paraméterek
    • QUERY_STRING$_GET
    • Standard bemenet → $_POST
  • Egyéb adatok
    • Környezeti változók → $_SERVER
  • Szuperglobális tömbök
// 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"

Szuperglobális tömbök

  • $_GET: QUERY_STRINGben é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 benne

Adatok útja

GET példa

Kliensen 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) {
}

POST példa

Ű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"
}

Bemeneti adatok feldolgozása PHP-ban

Példa

  • Kör kerületének kiszámítása
  • Bemenet: sugár
    • Kötelező
  • Kimenet: kerület
    • Valid oldalon jelenjen meg

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>

1. megoldás

1. megoldás

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>

2. megoldás

  • Lényegi logika kiemelése
  • Függvénybe zárása
  • Elkülönítjük az adatok beolvasásától és kiírásától
<?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>

Input hiánya és formátuma

  • http://localhost/circle.php → PHP hibák
  • Kezelni kell az input hiányát
    • Alapértelmezett érték
    • Hibaüzenet
  • Ha van input, akkor formátumellenőrzés

3. megoldás

Alapé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);
}

4. megoldás

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);
}

4. megoldás

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>

Általánosítás

  • Folyamat
    • Adatok ellenőrzése
    • Beolvasás
    • Feldolgozás
    • Kiírás
  • Több input esetén
    • bemeneti tömb ($_GET vagy $_POST)
    • típusos adatok tömbje ($data)
    • hibalista tömbje ($errors)
    • hibalista (HTML <ul>)

PHP validáció: filter_*()

filter_var() és filter_var_array()

Dokumentáció

// 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(.*)/",
  ],
]);

PHP filterek

  • FILTER_DEFAULT (szöveg)
  • FILTER_VALIDATE_BOOLEAN
  • FILTER_VALIDATE_EMAIL
  • FILTER_VALIDATE_FLOAT
  • FILTER_VALIDATE_INT
  • FILTER_VALIDATE_IP
  • FILTER_VALIDATE_MAC
  • FILTER_VALIDATE_REGEXP
  • FILTER_VALIDATE_URL

Általános feldolgozási logika

$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
}

“Kézi” validálás

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;
}

Általánosított validálás

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;
}

Általánosított validálás használata

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);
}

Hibák kiírása

<?php if ($errors) : ?>
  <ul>
    <?php foreach($errors as $error) : ?>
      <li><?= $error ?></li>
    <?php endforeach; ?>
  </ul>
<?php endif; ?>

5. megoldás

<?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; ?>

Űrlapok

Űrlapok

  • Kézi szerkesztés → URL → PHP helyett:
  • Űrlap → URL → PHP
  • http://localhost/circle.php?sugar=10

6. megoldás

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; ?>

Ergonómiai megfontolások

  • Az alkalmazás funkcionálisan teljesíti az elvárásokat
  • De nem ergonomikus a használata
    • Felhasználó nem tudja, mit írt be
    • Külön kattintásra (vissza) tud
      • javítani
      • újra számolni
  • Jó lenne ott jelezni a hibát, ahol az űrlap van
  • Jó lenne az űrlapon jelezni a megoldást is
  • Szemantikusan is helyesebb

Tervezés – oldalak

7. megoldás

<?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>

Űrlap állapottartása

Í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>

Szkript szerkezete

<?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>

Megjegyzendő