Web Applications in PHP Martin Kruli by Martin
Web Applications in PHP Martin Kruliš by Martin Kruliš (v 1. 1) 28. 11. 2019 1
HTTP Wrapper - Revision � HTTP Request Wrapper ◦ Data are automatically prepared in superglobal arrays �$_GET – parameters from request URL �$_POST – parameters posted in HTTP body (form data) �$_FILES – records about uploaded files �$_SERVER – server settings and request headers �$_ENV – environment variables � HTTP Response ◦ Script output is the response (echo …) ◦ Headers can be modified by specific functions header('header-line'); by Martin Kruliš (v 1. 1) 28. 11. 2019 2
HTTP Wrapper - Revision � Example <form action="? op=update& id=42" method="POST"> <input name="name" type="text"> <input name="surname" type="text"> <input name="age" type="number"> <input type="submit" value="Save"> </form> $_GET $_POST 'op' => 'update' 'id' => '42' 'name' => 'Martin' 'surname' => 'Kruliš' 'age' => '19' All values are strings by Martin Kruliš (v 1. 1) 28. 11. 2019 3
HTTP Wrapper - Revision � Request Information ◦ Decoded to the $_SERVER array �REQUEST_METHOD – used method (“GET” or “POST”) �SERVER_PROTOCOL – protocol version (“HTTP/1. 1”) �REQUEST_URI – request part of URL (“/index. php”) �REMOTE_ADDR – clients IP address �HTTP_ACCEPT – MIME types that the client accepts �HTTP_ACCEPT_LANGUAGE – desired translation �HTTP_ACCEPT_ENCODING – desired encodings �HTTP_ACCEPT_CHARSET – desired charsets �+ more info about the server and the client’s browser by Martin Kruliš (v 1. 1) 28. 11. 2019 4
Data Verification/Sanitization � What to Verify or Sanitize ◦ Everything that possibly comes from users: $_GET, $_POST, $_COOKIE, … ◦ Data that comes from external sources (database, text files, …) � When to Verify or Sanitize ◦ On input – verify correctness �Before you start using data in $_GET, $_POST, … ◦ On output – sanitize to prevent injections �When data are inserted into HTML, SQL queries, … by Martin Kruliš (v 1. 1) 28. 11. 2019 5
Input Verification � How to Verify ◦ Regular expressions ◦ Filter functions Safely retrieves $_GET['foo'] �filter_input(), filter_var(), … $foo = filter_input(INPUT_GET, 'foo', FILTER_VALIDATE_INT, $options); � Invalid Inputs Additional options based on input type (default, range…) ◦ Ostrich algorithm ◦ Attempt to fix (e. g. , select a valid part) ◦ User error by Martin Kruliš (v 1. 1) 28. 11. 2019 6
Output Sanitization � Sanitization ◦ Making sure the output matches target context ◦ Automated solutions are preferred � How ◦ ◦ to Sanitize String and filter functions, regular expressions htmlspecialchars() – encoding for HTML urlencode() – encoding for URL DBMS-specific functions (mysqli_escape_string()) �Better yet, use prepared statements by Martin Kruliš (v 1. 1) 28. 11. 2019 7
Formatted Data � URL Handling ◦ http_build_query() – construct URL query string ◦ parse_url() � Base 64 ◦ Encode (any) data into text-safe form (6 -bits/char) ◦ base 64_encode(), base 64_decode() � JSON ◦ json_encode(), json_decode(), json_last_error() ◦ Lists are arrays, collections are std. Class objects by Martin Kruliš (v 1. 1) 28. 11. 2019 8
Select Your Charset � One Charset to Rule Them All ◦ HTML, PHP, database (connection), text files, … ◦ Determined by the language(s) used �Unicode covers almost every language ◦ Early incoming, late outgoing conversions � Charset in Meta-data ◦ Must be in HTTP headers header('Content-Type: text/html; charset=utf-8'); ◦ Do not use HTML meta element with http-equiv �Except special cases (like saving HTML file locally) by Martin Kruliš (v 1. 1) 28. 11. 2019 9
HTTP Wrapper � File Uploads ◦ In form as <input type="file" name=. . . /> �Provide safe way to browse disk files ◦ HTTP wrapper handles the file �Stores it in temporary location �Provide related info in $_FILES[name] �'tmp_name' – path to the file in temp directory �'error' – error code (e. g. , UPLOAD_ERR_OK) �'name', 'type', 'size', … ◦ File exists only as long as the script runs �is_uploaded_file() – verification �move_uploaded_file() – a safe way to move files by Martin Kruliš (v 1. 1) 28. 11. 2019 10
File Upload Example <form action=". . . " method="post" enctype="multipart/form-data"> <input type="file" name="newfile"> </form> Necessary for file upload. . . if ($_SERVER['REQUEST_METHOD'] == 'POST') { $_FILES holds the metadata if (!empty($_FILES['newfile'])) { if ($_FILES['newfile']['error'] != UPLOAD_ERR_OK) { // Show error message. . . Path to temporary storage } if (!move_uploaded_file($_FILES['newfile']['tmp_name'], 'upload/'. $_FILES['newfile']['name'])) { // Show error message. . . Original file name } } Safe way how to move an uploaded file The uploaded file size is limited! (in php. ini settings) by Martin Kruliš (v 1. 1) 28. 11. 2019 11
Raw Request Body � Access to Request Body Data ◦ In case the data are sent in special format (e. g. , JSON) ◦ For other HTTP methods (PUT, DELETE) ◦ Read-only stream php: //input $body = file_get_contents('php: //input'); ◦ There are other streams worth mentioning �php: //output �php: //stdin, php: //stdout, php: //stderr �php: //memory, php: //temp by Martin Kruliš (v 1. 1) 28. 11. 2019 12
POST Request Processing � Problem with POST Request (a submitted form) Refresh Client (Browser) Again!!! add/change something script +read data (create HTML) Web Server Response (a HTML page) by Martin Kruliš (v 1. 1) 28. 11. 2019 13
POST Request Processing � Redirect Mechanism in HTTP ◦ 3 xx response code � 301 Moved Permanently � 302 Found (originally named Moved Temporarily) � 303 See Other ◦ Additional header 'Location' has the new URL ◦ Browser must try to load the new URL ◦ Loops in redirections are detected � Creating Redirect in PHP ◦ header("Location: my-new-url"); ◦ Automatically changes the response code (to 302) by Martin Kruliš (v 1. 1) 28. 11. 2019 14
POST Request Processing � Redirect (303 See Other) after POST Request (action. php) action. php add/change something Redirect (to index. php) Client (Browser) Refresh Redirects to a new URL (without updating history) GET (index. php) Web Server index. php generate HTML (only reads DB) HTML Page Example 1 by Martin Kruliš (v 1. 1) 28. 11. 2019 15
POST Request Processing � Redirect and Front Controller POST Request (index. php) add/change something Redirect (to index. php) Client (Browser) Refresh Redirects to a new URL (without updating history) GET (index. php) Web Server generate HTML (only reads DB) HTML Page Example 2 by Martin Kruliš (v 1. 1) 28. 11. 2019 16
Session Management � Managing User Session Data ◦ Intermediate state (not persisted) �User identity (after authentication) �Work in progress (e. g. , a shopping cart) ◦ HTTP is stateless �Cookies �PHP session API ◦ Cryptographic approach �Security tokens (public data, but digitally signed) by Martin Kruliš (v 1. 1) 28. 11. 2019 17
Session Management � Cookies ◦ A way to deal with stateless nature of the HTTP ◦ Key-value pairs (of strings) stored in the web browser �Set by special HTTP response header �Automatically re-sent in headers with every request �Each page (domain) has it own set of cookies ◦ Cookies in PHP �Cookies are set/modified/removed by setcookie() �The function modifies HTTP response headers �Cookies sent by browser are loaded to $_COOKIE[] by Martin Kruliš (v 1. 1) 28. 11. 2019 18
Session Management � PHP Session API ◦ Simple call to session_start() method ◦ Checks $_COOKIE and $_GET arrays for PHPSESSID variable which should have the ID ◦ If the variable is missing, new session is started �And a cookie with the new ID is set (if php. ini says so) � Accessing Session Data ◦ In the $_SESSION global array �Automatically loaded when the session is opened and serialized (saved) at the end of the script ◦ It can be read and written (incl. unset() on items) by Martin Kruliš (v 1. 1) 28. 11. 2019 19
Session Management � Security Tokens ◦ Can be generated/verified only at server ◦ Has public payload that holds important data �E. g. , user identity, expiration time, … ◦ Digitally signed using crypto hash functions payload: salt: hash(payload: salt: secret) ◦ Stored only at client side (unlike session IDs) �But they can be stolen the same �Complicated invalidation ◦ See JSON Web Tokens (JWT) for example by Martin Kruliš (v 1. 1) 28. 11. 2019 20
Databases � My. SQL ◦ Original mysql API is deprecated (as of PHP 5. 5) ◦ My. SQL Improved (mysqli) API �Dual object/procedural interface �Procedural interface is similar to original (deprecated) API �Advanced connectivity features �Persistent connections, compression, encryption �Directly supports transactions ◦ My. SQL Native Driver (mysqlnd) extension �More direct access to My. SQL server �Additional features (e. g. , asynchronous queries) by Martin Kruliš (v 1. 1) 28. 11. 2019 21
Databases � My. SQLi Procedural API ◦ Establishing connection with My. SQL server $mysqli = mysqli_connect("server", "login", "password", "db_name"); ◦ Performing queries $res = $mysqli->query("SQL …"); ◦ Terminating connection $mysqli->close(); ◦ Safe way to include strings in SQL query mysqli_real_escape_string($mysqli, $str); by Martin Kruliš (v 1. 1) 28. 11. 2019 22
Databases � My. SQL Results ◦ mysqli: : query() result depends on the query type �On failure always returns false ◦ Modification queries return true on success ◦ Data queries (SELECT, …) return mysqli_result obj �mysqli_result: : fetch_assoc() �mysqli_result: : fetch_obj() �mysqli_result: : fetch_all($format) �mysqli_result: : fetch_fields() �mysqli_result: : num_rows() �mysqli_result: : free_result() by Martin Kruliš (v 1. 1) 28. 11. 2019 23
Databases � My. SQLi Prepared Statements Placeholders ? can be used for bound variables ◦ Prepare new My. SQL statement $stmt = mysqli: : stmt_init(); mysqli_stmt: : prepare("SELECT. . . "); ◦ Binding parameters (by positional placeholders) mysqli_stmt: : bind_param($types, $var 1, …) �Types string – one char ~ one parameter ◦ Execute and get result object mysqli_stmt: : execute(); $res = mysqli_stmt: : get_result(); by Martin Kruliš (v 1. 1) 28. 11. 2019 24
My. SQL Example $mysqli = mysqli_connect("localhost", "login", "passwd", "dbname"); if (!$mysqli) // handle connection failure $mysqli->set_charset("utf 8"); $stmt = new mysqli_stmt($mysqli, 'SELECT * FROM lectures WHERE student_group = ? '); $student. Group = '3 rdyears'; $stmt->bind_param("s", $student. Group); $stmt->execute(); $res = $stmt->get_result(); while (($lecture = $res->fetch_object()) !== null) { echo "$lecture->id: $lecture->name"; } $mysqli->close(); by Martin Kruliš (v 1. 1) 28. 11. 2019 25
Frameworks � PHP ◦ ◦ ◦ ◦ ◦ Frameworks Symfony – one of the most popular Laravel – one of the most popular Slim - microframework Zend – one of the oldest Nette – Czech developer and comunity Code. Igniter Yii 2 Phalcon Cake. PHP … by Martin Kruliš (v 1. 1) 28. 11. 2019 26
Discussion by Martin Kruliš (v 1. 1) 28. 11. 2019 27
- Slides: 27