Server side scripting

Post on 04-Feb-2016

49 views 0 download

description

Server side scripting. Webtechnologie. Lennart Herlaar. Inhoud. PHP Meer PHP En nog meer PHP. Server side scripting. En n og meer PHP. Webtechnologie. Lennart Herlaar. Class based. Object model herschreven voor PHP5, deels 5.3 Breuk met PHP4; incompatible legacy code - PowerPoint PPT Presentation

Transcript of Server side scripting

Server side scripting

1WebtechnologieLennartHerlaar

Inhoud

• PHP

• Meer PHP

• En nog meer PHP

• Arrays beelden keys op values af• Ook als de indices integers zijn• Pas op met aannames m.b.t. de volgorde

• Veel array functies• in_array, array_search, array_merge,

array_reverse, array_flip, array_pop, array_push, array_map, ...

Associative arrays

$myarray = array(1 => "Dog", "Cat", "Scary" => "Bat");$myarray2 = array(0, 2 => 5, 3);$myarray[0] = "Rat";print_r($myarray);

array_keys($myarray); // (1, 2, "Scary", 0)array_values($myarray); // ("Dog", "Cat", "Bat", "Rat")count($myarray); // 4list($a, , $c) = $myarray2; // $a is 0, $c is 5

foreach ($students as $student) { echo("$student\n"); }foreach ($library as $isbn => $title) { echo "Book with ISBN $isbn has title $title\n";} // Volgorde?

Frustrerend?

Sorteren

• Grote hoeveelheid sorteerfuncties• sort(), asort(), arsort(), ksort(), krsort(), rsort(),

usort(), uasort(), uksort(), natsort, ...• Sort is de basis; herordening, integer keys

• r = reversed, a = value, k = key, u = user defined

• a en k laten de associatie intact• nat voor "natuurlijk" sorteren: img2.gif vs.

img12.gif

$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana");ksort($fruits); // a => orange, b => banana, d => lemonasort($fruits); // b => banana, d => lemon, a => orangesort($fruits); // 0 => banana, 1 => lemon, 2 => orange

Strings en arrays revisited

$name = "Blob";echo ":$name:"; // :Blob:echo "$nameje"; // lege stringecho "{$name}je"; // Blobjeecho "\{$name\}"; // \{Blob\}$a[2][3] = $name;echo "De {$a[2][3]}!"; // De Blob!echo "De " . $a[2][3] . "!"; // De Blob!echo "En niet de $a[2][3]!"; // En niet de Array[3]!

$words = explode(" ","Jack in the box"); // Array!$str = implode("-", $words); // Jack-in-the-boxstrtr($posting, array("ROTFLMAO" => "rolling on the floor...", ...));strtr($posting, "äåö", "aao");

• Daar gaan we weer...

Type juggling en casting

$myFirstVar = 42;$myFirstVar = 'We are sorry for the inconvenience';

$x = 1 + true;$x = NULL + false;$x = (bool)0;$x = (bool)0.0;$x = (bool)"";$x = (bool)"0";$x = (bool)"0.0";$x = ("0" == true);$x = (true == "false");$x = ("1" == 1);$x = ("1" === 1);

var_dump($x);var_export($x);

$x = "the answer is " . "42";$x = 3 . "5";$x = "the answer is " + "42";$x = 3 + "5";$x = 3 * "5";$x = "this is " + true;

Vergelijk dit met JavaScript...

$x = array_search($myval, $myarray);

Server side scripting

8WebtechnologieLennartHerlaar

En nog meer PHP

Class based

• Object model herschreven voor PHP5, deels 5.3• Breuk met PHP4; incompatible legacy code

• Objects en classes• Een object heeft functies en variabelen

• Methods en properties• Methods en properties kunnen dynamisch

aan objecten toegevoegd worden• Een object is een instantiatie van een

class• Een class is een blauwdruk voor een object

• De classes vormen een hiërarchie

Vergelijk dit met JavaScript...

Objecten

class Cart { private $items; // Pas op!

public function add_item ($artnr, $num) { $this->items[$artnr] += $num; }

public function remove_item ($artnr, $num) { if ($this->items[$artnr] >= $num) { $this->items[$artnr] -= $num; return true; } else { return false; } }}

$cart = new Cart;$cart->add_item(1, 1);$cart->add_item("42", 42);$another_cart = new Cart;$another_cart->add_item("0815", 3);

Public, private, protected

Object dynamics

• Naast object dynamics ook class dynamics• Lastiger dan prototype dynamics in

JavaScript• Probeer dit allemaal niet nodig te

hebben...

$cart1 = new Cart;$cart2 = new Cart;$cart2->add_item("a",10);$cart2->add_item("b",5);

$cart1->val = "cart1";echo ($cart1->val); // cart1echo ($cart2->val); // Niets

echo implode(";",$cart2->items); // 10;5unset ($cart2->items);echo ($cart2->items); // Niets

Class inheritance

• Geen multiple inheritance• Wel multiple interfaces

class Named_Cart extends Cart { private $owner; function set_owner($name) { $this->owner = $name; }

function get_owner() { return($this->owner); }}

Constructors

• Magic Method met de naam __construct• Constructor van super class moet

expliciet aangeroepen worden• Eveneens een destructor beschikbaar

class Constructor_Cart extends Cart { function __construct($item = "a", $num = 1) { $parent::__construct(); $this->add_item ($item, $num); }}

$default_cart = new Constructor_Cart;$different_cart = new Constructor_Cart("b", 17);

Paamayim Nekudotayim

• Dubbele dubbele punt

• Scope resolution operator

• Static properties en methods

• Geen instantiatie nodig

• Overridden methods

• Methods van super classes

• Class constants

class Foo { public static function myStaticFunc() {    [...]  }}

Foo::myStaticFunc();

class OtherClass extends MyClass { public function myFunc() { [...] parent::myFunc(); }}

Functies op objecten

function print_vars($obj) { $vars = get_object_vars($obj); foreach ($vars as $prop => $val) { echo "$prop = $val\n"; }}

function print_methods($obj) { $methods = get_class_methods(get_class($obj)); foreach ($methods as $method) { echo "function $method()\n"; }}

Zwak getypeerd, dynamisch

• Niet nodig variabelen of properties te declareren

• Type wordt "at runtime" bepaald, duck typing

• Automatische type conversion• Functies zijn in de regel geen 1st class

citizens• Functies en properties kunnen dynamisch

aan objecten toegevoegd worden (maar…)• Functies met mogelijk variabel aantal

parameters• Polymorfie• Nesting van functiedefinities, closures

(PHP5.3)

Vergelijk dit met JavaScript...

Centraal architectuur diagram

WebserverWebbrowser

RDBMSStatische

files

Form, parameters

HTML

HTM

L+

cod

e

SQ

L

Parameters, code

HTML

File a

ccess

Resu

lt s

et

Interpreterof compiler

Superglobals

• PHP kent een aantal bijzondere variabelen• Superglobals: automatisch beschikbaar in elke

scope

• Arrays met (veelal) informatie over de buitenwereld

• $_SERVER: server en execution environment

• $_GET: key / value paren uit de GET query string

• $_POST: key / value paren uit de POST body

• Ook: $_FILES, $_COOKIE, $_SESSION, $_ENV

• $_REQUEST = $_GET + $_POST + $_COOKIE

Superglobals

<?php echo $_SERVER["SERVER_NAME"] . "<br/>"; echo $_SERVER["SERVER_ADDR"] . "<br/>"; echo $_SERVER["SERVER_PORT"] . "<br/>"; echo $_SERVER["REQUEST_TIME"] . "<br/>"; echo $_SERVER["REQUEST_METHOD"] . "<br/>"; echo $_SERVER["REQUEST_URI"] . "<br/>"; echo $_SERVER["HTTPS"] . "<br/>"; echo $_SERVER["HTTP_USER_AGENT"] . "<br/>"; echo $_SERVER["REMOTE_ADDR"] . "<br/>"; echo $_SERVER["REMOTE_PORT"] . "<br/>";?>

Form processing

<form name="input" action="welcome.php" method="get"> First name: <input type="text" name="first"/><br/> Last name: <input type="text" name="last"/><br/> <input type="submit" value="Send"/></form>

<?php echo $_GET["first"]; // Geen URL decoding nodig echo $_REQUEST["first"];

extract($_GET, EXTR_PREFIX_ALL, "imported") // Pas op! echo $imported_first;

// Old-skool echo $HTTP_GET_VARS["first"];

// Met PHP directive register_globals = on echo $first; // Pas op! (Old skool; < PHP 5.4)?>

http://…/welcome.php?first=Willie&last=Wartaal

Odds & ends

• Includen van PHP code• include() en require()• Local / remote, scoping• Let op: HTML-context! Gebruik <?php ?>

• Aanpassen PHP settings• Vele tientallen setting• In de config file, maar soms ook "at runtime"• ini_set('display_errors', 1),

ini_get('post_max_size')• Genereren van HTTP headers

• header(), maar pas op met whitespace...

<?php// We serveren een PDF uit...header('Content-type: application/pdf');

// ...en we noemen 'm doc.pdfheader('Content-Disposition: attachment; filename="doc.pdf"');[...]?>

• Heel veel functies in de core...• ...en heel veel functies in extensions

• Compressie, cryptografie, cookies, beeldverwerking, e-mail, XML, file system, datum/tijd, sessions, URIs, FTP, databases, mathematische bewerkingen, TCP, sockets, HTTP, SOAP, JSON, LDAP, PDF, MIME, ...

• We komen er nog een aantal van tegen• State, sessions, databases, security, stateful

web• Belang van frameworks

Odds & ends

PEAR PECL

• phpinfo()

PHP configuratie

State, sessions, databases

24WebtechnologieLennartHerlaar

Inhoud

• State

• Cookies en sessions

• Webdatabases

• Databases en PHP

• (Transactions)

State

• HTTP revisited• HTTP is stateless• HTTP kent page based requests

• In de regel geen continu draaiende applicatie• Niet op de server, niet in de client

• Maar we willen wel persistency• State moet ergens opgeslagen worden• In de client, maar dan wel telkens meesturen• In de server, maar dan wel een

identificatieprobleem• Verschillende opties

Hidden input fields

• State wordt "verborgen" in het formulier• Hidden input fields, state opgeslagen in de client

• Bij submit worden deze waarden meegestuurd• Onderdeel van de GET query string / POST

body• En opnieuw verwerkt door het server side

script• Problemen met hidden input fields

• Verwarrend: gebruik back button geeft verlies state

• Inefficiënt: alle state ping-pongt heen en weer• Onveilig: de gebruiker kan eenvoudig bij de

state• Complex: scripten ping-pongen en input

validation

Hidden input fields

<form name="product" action="shop.php" method="get"> Product: <select name="product"> <option value="62629">Volvo</option> <option value="89124">Saab</option> <option value="64625">Fiat</option> <option value="31763">Audi</option> </select><br/> <input type="submit" value="Send"/> <input type="hidden" name="step" value="productinfo"/></form>

<form name="input" action="shop.php" method="get"> Full name: <input type="text" name="name"/><br/> Address: <input type="text" name="address"/><br/> <input type="submit" value="Send"/> <input type="hidden" name="step" value="buyerinfo"/> <input type="hidden" name="product" value="64625"/> <input type="hidden" name="price" value="8995"/></form>

<form name="input" action="shop.php" method="get"> card number: <input type="text" name="cardno"/><br/> card name: <input type="text" name="cardname"/><br/> <input type="submit" value="Send"/> <input type="hidden" name="step" value="paymentinfo"/> <input type="hidden" name="product" value="64625"/> <input type="hidden" name="price" value="8995"/> <input type="hidden" name="name" value="Willie Wartaal"/> <input type="hidden" name="address" value="..."/></form>

<form name="input" action="shop.php" method="get"> card number: <input type="text" name="cardno"/><br/> card name: <input type="text" name="cardname"/><br/> <input type="submit" value="Send"/> <input type="hidden" name="step" value="paymentinfo"/> <input type="hidden" name="product" value="64625"/> <input type="hidden" name="price" value="89"/> <input type="hidden" name="name" value="Willie Wartaal"/> <input type="hidden" name="address" value="..."/></form>

<form name="input" action="shop.php" method="get"> Full name: <input type="text" name="name"/><br/> Address: <input type="text" name="address"/><br/> <input type="submit" value="Send"/> <input type="hidden" name="step" value="buyerinfo"/> <input type="hidden" name="product" value="64625"/> <input type="hidden" name="price" value="8995"/></form>

Hidden input fields

shop.php?[...]step=buyerinfo&product=64625&price=8995shop.php?[...]step=buyerinfo&product=64625&price=89

Hidden input fields

<input type="hidden" name="step" value="buyerinfo"/><input type="hidden" name="product" value="64625"/><input type="hidden" name="price" value="8995"/><input type="hidden" name="checksum" value="7ce9e97f43808be0d23f0493c3e1345b"/>

md5("step=buyerinfo&product=64625&price=8995")

md5("step=buyerinfo&product=64625&price=8995MyLittleSecret")

md5("step=buyerinfo&product=64625&price=89")

6ae40396005969e2c301b5eafa463285

9eece848a4c43a0b1144f863d770c66b

<input type="hidden" name="step" value="buyerinfo"/><input type="hidden" name="product" value="64625"/><input type="hidden" name="price" value="89"/><input type="hidden" name="checksum" value="6ae40396005969e2c301b5eafa463285"/>

<input type="hidden" name="step" value="buyerinfo"/><input type="hidden" name="product" value="64625"/><input type="hidden" name="price" value="89"/><input type="hidden" name="checksum" value="9eece848a4c43a0b1144f863d770c66b"/>

REPLAY!md5("step=buyerinfo&product=64625&price=8995MyLittleSecretTimestamp")

<input type="hidden" name="step" value="buyerinfo"/><input type="hidden" name="product" value="64625"/><input type="hidden" name="price" value="8995"/><input type="hidden" name="ts" value="timestamp"/><input type="hidden" name="checksum" value="b368395508548682751710ccd2548d24"/>

• Feitelijk het opbouwen van state in de

URL• Bij gebruik van GET

• Generiek principe• Alle state aan elke link toevoegen als query

string

• Form action wordt het script met de state tot

nu toe

• Maar pas op...

• Dan wel gebruik maken van POST

• Beter: met hidden input fields en GET of POST

State opbouwen in URL

<form name="input" action="shop.php?step=paymentinfo&[...]&product=64625" method="post"> Full name: <input type="text" name="name"/><br/> Address: <input type="text" name="address"/><br/> <input type="submit" value="Send"/></form>

<a href="specials.html?[...]&step=buyerinfo&product=64625">See special deals</a>

't Heeft allemaal dezelfde problematiek!

State, sessions, databases

32WebtechnologieLennartHerlaar

Cookies en sessions

Cookies

• State wordt als "brokje" data opgeslagen• In de client

• Server geeft client opdracht cookie te zetten

• Client stuurt het cookie mee met elk request• Indien cookie en request matchen

• Uitwisseling op basis van HTTP headers• Server zet het cookie met Set-Cookie

• Cookies zijn key-value paren; associative array

Set-Cookie: product=64625; Max-Age=3600

Cookie: product=64625

Cookies

• Cookies hebben aanvullende attributen• Expires: wanneer het cookie verloopt (ook:

Max-Age)

• Domain: voor welke domeinen het cookie

geldig is

• Path: ...en voor welke URLs binnen het domein

• Secure: of het via HTTPS verzonden moet

worden

• HttpOnly: of het alleen bedoeld is voor HTTP

requests

Set-Cookie: userid=willie; Domain=shop.foo.com; Path=/accounts; Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; HttpOnlySet-Cookie: product=64625; Domain=.foo.com; Path=/; Expires=Wed, 04-Mar-2015 14:30:01 GMT;

Cookies in PHP en JavaScript

• PHP ondersteunt op transparante wijze cookies

• Header output eerst, dus cookies ook eerst!

• Cookies zijn vanuit JavaScript bereikbaar• Zowel lezen als schrijven is mogelijk• Alleen indien matchend en geen HttpOnly

document.cookie = 'koekje=hello;expires=Wed, 05 Mar 2014 14:35:01 GMT';

var koekje = document.cookie; // let op: string met key-value paren!

<?php $count = $_COOKIE["count"] + 1; setcookie("count", $count, time()+3600); echo $count;?>

Cookies?

• Soorten cookies• Persistent, Session, Supercookie,

Trackingcookie, ...• Cookies lossen niet alle eerdere

problemen op• Inefficiënt, onveilig

• Daarnaast nieuwe specifieke problemen• Cookies kunnen in de browser geweigerd

worden• Beperkingen m.b.t. aantal en omvang van

cookies• Cookies hebben een matige reputatie• Wettelijke beperkingen aan het gebruik van

cookies• Cookies soms ten onrechte geweigerd