COMP5390 Web Programming Frameworks Yang He and Doug Santry 1 Topics • The Challenges of Implementing Modern Websites • The MVC architecture: Model, View, Controller • Introduction to CodeIgniter 2 Project Scale • Web applications can get very large and complex. • There are 1,000s of files in a modern website. • Leads to a chaotic project: • Difficult to maintain (fix bugs) • Difficult to extend (add features) • Difficult to monitor 3 Website Design • Consider a website such as amazon.com. How many webpages are on the site? • Consider Amazon’s product catalogue. How many webpages need to access it? • Price search • Item search • Manufacturer search • Stock management • Even a user’s account requires a great deal of functionality. • Conclusion: A website is like any large piece of software. Normal software engineering methods and best practice are required. 4 Good Design • Many websites re-use the same basic design. It makes no sense to repeatedly re-invent the wheel. • How different are John-Lewis and Debenhams? • Access and manipulation of data needs to be isolated and monitored. • Multiple groups of developers need to implement features simultaneously. • Divorce the presentation team from the feature team. 5 MVC architecture 6 MVC • The most common project structure enforced (or at least encouraged) by frameworks. • MVC stands for: • Model : responsible for data access and business logic • View : responsible for presentation of results • Controller : responsible for manipulating the data • A popular design pattern. 7 Models • The models implement the business logic. • In a library application, one could employ a model that provides for “book” and “borrower”; they could be encapsulated in an SQL table. • One can implement more complex functions designed to find, process and collate the data ready for reports and analytics. • Models can also be derived from models, to perform more complex tasks • Potential data propagation lag • Potential addition of response latency 8 Views • Build the pretty HTML pages to be returned to the requestor. • Using HTML and CSS means that these are maintainable by designers using design-focussed tools. 9 Controllers • The controller typically does only a little bit of work for each request • Select a model • Run a function in the model • Maybe pass it some data from POST or GET • Select a view • Pass it the output of the function 10 MVC sequence 2: Load model 3: Invoke model function (with GET/POST data 1: Incoming GET or POST HTTP request Controller Model (business logic) 5: Return results 6: Load view 7: Invoke view (with results from model) 4: Query/update database View (presentation logic) 8: HTTP response: return generated HTML 11 Business Logic • MVC best practice is: “Fat Models, Skinny Controllers” • Put as much business logic as possible into the models • Keep the controllers simple! • Offers best chance of code reuse • We strive to be DRY (Don’t Repeat Yourself) 12 MVC Frameworks • There are many MVC frameworks. Just a few of the most popular: • CodeIgniter • Symfony • Laravel • Choosing the right one is subjective • Like many choices in engineering it is about trade-offs • Libraries • Hiring talent • Security • Compatibility 13 COMP5390 CodeIgniter Introduction Doug Santry 1 CodeIgniter • We will use CodeIgniter for our MVC framework. • The learning curve is low. • It is powerful – you will learn how to do cool stuff quickly. • The first practical class after the Project Week will install and configure CI. • PLEASE DO NOT DOWNLOAD CI PRIOR TO YOUR PRACTICAL CLASS. • We use a special version. • CI needs to be carefully installed on raptor - not your personal devices. 2 CodeIgniter Layout public_html NEVER EDIT THIS! application config controllers index.php models views 3 A Simple Application 4 CodeIgniter's version of MVC • All requests go through index.php • Index.php implements the logic (“special sauce”) that is CI. 5 Example Controller • Example file: application/controllers/Welcome.php <?php defined('BASEPATH') OR exit('No direct script access allowed'); class Welcome extends CI_Controller { /** * Index Page for this controller. * Security check * Maps to the following URL * http://example.com/index.php/welcome * - or – * http://example.com/index.php/welcome/index * - or – * Since this controller is set as the default controller in * config/routes.php, it's displayed at http://example.com/ * * So any other public methods not prefixed with an underscore will * map to /index.php/welcome/<method_name> * @see https://codeigniter.com/user_guide/general/urls.html */ public function index() { $this->load->view('welcome_message'); } } All controllers extend this class. It provides all the "plumbing" Default Action handler Loads a view (views/welcome_message.php) 6 Writing Our Own Controller • Create controllers/Dictionary.php <?php defined('BASEPATH') OR exit('No direct script access allowed'); class Dictionary extends CI_Controller { public function index() { echo "Hello world – I am the default method for this controller"; } } • URL: index.php/dictionary/index or index.php/dictionary • NOTE: Class name and filename start with an uppercase letter. The URL does not. 7 Controllers, Actions and URLs • Let’s look at a CodeIgniter URL http://raptor.kent.ac.uk/~your-login/index.php/dictionary/get/2 • It appears to be a request for a file named, “2”: WRONG! • In CI, ”dictionary", ”get" and "2" are called URL segments or slugs. • These segments mean: load the dictionary controller, run its get() action, passing 2 as an argument. CI runs: • Dictionary->get (2); 8 More Complex Controllers • The implementation of get: <?php defined('BASEPATH') OR exit('No direct script access allowed'); class Dictionary extends CI_Controller { public function index () { echo "Hello world";} public function get ($ID = null) { if($ID == null) echo ”Error: no element to retrieve."; else echo ”request for element $ID"; } } • /dictionary/ results in “Hello world” • /dictionary/get/ results in, “Error: no element to retrieve.” • /dictionary/get/3 results in, “request for element 3” 9 More on Controllers • Actions can have multiple parameters: • …/index.php/controller/method/arg-1/…/arg-n • .../dictionary/multiGet/3/5/7 • Dictionary->multiGet (3, 5, 7); • Controller action names with a leading underscore are not accessible. • _checkCredentials (); // If used in an URL it will not be serviced • They can be called from inside the controller. • This is different from PHP private/public. 10 Views • We saw before how to load a view in a controller: $this->load->view('SomeView'); • Views live inside the application/views folder. • Views are not classes. They are normal PHP files, containing HTML and (typically) some echo statements. 11 A Simple View (views/dictionary_get.php) <!DOCTYPE html> <html> <head><title>Lookup Result</title></head> <body> <table> <tr><th>Name</th><th>Value</th></tr> <tr><td>ID</td><td><?php echo $id; ?></td></tr> <tr><td>Contents</td><td><?php echo $value; ?></td></tr> </table> </body> </html> • A controller loads this view with: $this->load->view(‘dictionary_get’); • Where are the $id and $value variables set? 12 Passing Data to a View • Add an extra parameter to the load->view() $this->load->view(dictionary_get', $data); • This can be an object or an associative array • The array keys (or object properties) will be turned into variables inside the view by CI • So, if we set: $data = array(); $data['id'] = 2; $data[‘value'] = "no data yet"; • The view will see $id and $value variables. 13 Updated Controller <?php defined('BASEPATH') OR exit('No direct script access allowed'); class Dictionary extends CI_Controller { public function index() { echo "Hello world";} public function get($ID = null) { if($ID == null) { echo ”nothing requested"; return; } $data['id'] = $ID; $data[‘value'] = ”can’t lookup data yet"; $this->load->view(‘dictionary_get', $data); } } • Making results pretty (important for real websites!) is separated from processing. 14 Models • Models live in the application/models directory • All models extend from CI_Model • Just as controllers extend from CI_Controller • It’s a good idea to name your model classes along the lines of Dictionary_model (in Dictionary_model.php) • First character MUST be capitalized in class name and in filename. • Add functions to your model to implement features exposed to users in the controller. 15 A Simple Model <?php class Dictionary_model extends CI_Model { public function fetchEntry ($Id) { $data['id'] = $Id; $data[‘value'] = ‘This is Fake!'; return $data; } } • And change the controller to use the model: public function get($ID = null) { $this->load->model(‘dictionary_model'); $data = $this->dictionary_model->fetchEntry($Id); // Returns associative array $this->load->view(dictionary_get', $data); // so we can pass it to the view } • Note that dictionary_model gets added to $this by CI 16 URL: …/index.php/dictionary/get/7 application/models/Dictionary_model.php application/controllers/Dictionary.php class Dictionary extends CI_Controller { public function index () { // default action } public function get ($Id = null) { if ($ID == null) { echo ”nothing requested"; return; } } } $this->load->model (‘dictionary_model’); // Returns associative array $data = $this->dictionary_model->fetchEntry ($Id); // so we can pass it to the view $this->load->view (‘dictionary_get', $data); class Dictionary_model extends CI_Model { public function fetchEntry ($Id) { $data['id'] = $Id; $data[‘value'] = ‘This is Fake!’; } } return $data; application/views/dictionary_get.php <!DOCTYPE html> <html> <head><title>Lookup Result</title></head> <body> <table> <tr><th>Name</th><th>Value</th></tr> <tr><td>ID</td><td><?php echo $id; ?></td></tr> <tr><td>Contents</td><td><?php echo $value; ?></td></tr> </table> </body> </html> 17 That’s it! (for the basics) • You now know enough to be able to write a simple web app using CodeIgniter. • The key to understanding CI is grasping the relationship between URLs and controller classes. • There are plenty of more examples to come. 18 Summary • We have introduced CodeIgniter. • Please do not install CI until your practical class. • See also: http://tutorialcodeigniter.com/beginners/ • Next lecture: hooking up a database to CI code. 19 COMP5390 CodeIgniter SQL Database Doug Santry 1 Topics • CodeIgniter Database Configuration • CI and SQL queries • CI and Query Builder 2 CI Database Access • CodeIgniter directly supports database access. • Fully integrated • But first, CodeIgniter needs to be configured. • Where • Which • Authenticate • Your workspace: /proj/comp5390/kentmart/your-login/public_html/application 3 Configuring Database Access • Edit application/config/database.php $active_group = 'default'; $query_builder = TRUE; $db['default'] = array( 'dsn' => '', 'hostname' => 'dragon.kent.ac.uk', 'username' => 'Your_Kent_Login_Username', 'password' => ‘Your dragon password – NOT Kent password', 'database' => 'Your_Kent_Login_Username', 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => FALSE, 'db_debug' => (ENVIRONMENT !== 'production'), 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, 'failover' => array(), 'save_queries' => TRUE ); 4 CI Database Access • Before running queries connect to the DB. • $this->load->database(); • Usually a good idea to make the call in the constructor • With a connection to the DB established we can interact with the DB. • $this->db->query(•••); • Runs a query and returns the result • There are two ways to interact with the DB: • SQL • Query Builder 5 CI Database Queries with SQL The dictionary_model interacting with a DB: <?php class Dictionary_model extends CI_Model { public function __construct() { $this->load->database(); } public function fetchDictionary ($key) { $query = 'SELECT * FROM dictionary WHERE key = ?'; $results = $this->db->query ($query, array ($key)); return $results->result_array (); } } 6 Constructing SQL Queries • Query placeholders in CI are satisfied by an array holding the values in order, so: $query = 'SELECT * FROM dictionary WHERE key= ? LIMIT ?'; $results = $this->db->query($query, array($key, 1)); • As a special case, if there is only one, you do not need the array. Our first example could have been written thus: $result = $this->db->query($query, $key); 7 Interpreting DB Results Queries return results, our data, and there two ways to view them. $query = 'SELECT * FROM dictionary WHERE key = ?'; $results = $this->db->query($query, array ($key))); 1. Objects foreach ($results->result() as $row) { echo $row->key; echo $row->value; } 2. Arrays foreach ($results->result_array() as $row) { echo $row[‘key’]; echo $row[‘value’]; } 8 An Example Method in the Model Fetch values and compute the average: public function computeValueScaler () { $data = $this->db->query("SELECT value FROM dictionary"); $n = $data->num_rows (); if($n == 0) return 0; $sum = 0; foreach ($data->result_array() as $row) { $sum += $row[‘value']; } return $sum / $n; // return a scaler } 9 Moving Data from a Model to a View • The model implements a method that fetches the data. • It is the role of the MVC’s View to package the results up in HTML. • The model’s action: public function getDictionaryArray () { $results = $this->db->query ('SELECT * FROM dictionary'); return $results->result_array (); // NOTE: API } 10 The Controller Coordinates Contollers/dictionary.php – action in the Dictionary class public function viewDictionary () { $this->load->model(‘dictionary_model'); $data = $this->dictionary_model->getDictionaryArray(); if(count ($data) == 0) { echo ”Dictionary is Empty"; return; } $viewData = array("results" => $data); $this->load->view('view_dictionary', $viewData); } 11 views/view_dictionary.php and in the view (note the importance of an API): <?php foreach ($results as $row) {?> <tr> <td><?php echo $row[‘key']; ?></td> <td><?php echo $row[‘value']; ?></td> </tr> <?php } ?> 12 URL: …/index.php/dictionary/get/7 application/models/Dictionary_model.php application/controllers/Dictionary.php class Dictionary extends CI_Controller { public function index () { // default action } public function get ($key = null) { if ($key == null) { echo ”nothing requested"; return; } } } $this->load->model (‘dictionary_model’); // Returns associative array $data = $this->dictionary_model->fetchEntry ($key); // so we can pass it to the view $this->load->view (‘dictionary_get', $data); class Dictionary_model extends CI_Model { public function fetchEntry ($key) { $this->load->database(); $query = 'SELECT * FROM dictionary WHERE key = ?'; $results = $this->db->query($query, array ($key))); return $results->result_array (); } } application/views/dictionary_get.php <!DOCTYPE html> <html> <head><title>Lookup Result</title></head> <body> <table> <tr><th>Name</th><th>Value</th></tr> <tr><td>Key</td><td><?php echo $key; ?></td></tr> <tr><td>Contents</td><td><?php echo $value; ?></td></tr> </table> </body> </html> 13 More examples (note userguide3 for V3) • https://codeigniter.com/userguide3/database/index.html • https://codeigniter.com/userguide3/database/results.html 14 CI Database Queries with Query Builder • A programmatic mechanism for interacting with the database • Query Builder “builds” the query incrementally • The class simply builds the SQL strings for the programmer, at runtime, and calls ::query (). • Sometimes referred to as Active Record • Stateful – watch out! 15 Query Builder • Dictionary_model::fetchEntry written with Query Builder public function fetchEntry ($key) { $this->db->select(‘*’); $this->db->from(‘dictionary’); $this->db->where(‘key’, $key); // run the constructed query and reset – resets state $this->db->get (); return $query->row (); // Only one entry, if any } 16 Query Builder Notes • • • All the fetching, counting and utility methods available for “normal” database queries are available for QB. There is no “right” or “wrong” way to interact with the database. QB can be used to implement more dynamic functionality in the model. • Really necessary? Rarely. 17 Our Journey…So Far • • • • We proposed a design pattern, MVC, that abstractly provides the structure that we need to implement website designs efficiently. CodeIgniter 3.1.11 is a framework to concretely implement MVC quickly in real code. Today we learnt how to use CodeIgniter’s DB facilities to use MVC to implement real functionality. Assessment tip: Verify SQL statements before coding them in CI. • Use your usual way of interacting with SQL to develop and debug SQL. YOU CAN NOW BUILD REAL STUFF! 18 Challenges These are the implementation challenges that Facebook, Google et cetera think about every day • • Concurrency: what happens if our application has multiple pending requests? Carrying Capacity: what is the maximum number of transactions per second that raptor could do? • • • Useful to understand how many machines our application will require Scale Out: how would we distribute our application over multiple physical machines? Geographical Caching: How should we keep instances of our DB on every continent ”consistent”? 19 Summary • SQL databases in CodeIgniter 3.1.11 • Remember to edit the database config file with your correct database information (not fun to debug). • A connection has to be established to the DB before it can be used. • This can be done in the model’s constructor or the individual methods. • Everything else follows the usual CI MVC approach • We have reached the point where we could build a real web application - the pieces are coming together. 20 COMP5390 CodeIgniter Sessions and Data 1 Topics • Rewriting and Routing • GET and POST data • Sessions • Caching • Profiling • Automatically loading CI components • Helpers 2 HTTP GET and POST Requests • HTTP has many verbs. We are interested in: GET and POST. • GET simply requests data. • We answer with our view. • HTTP POST looks like GET superficially. • POST uploads data to the web-server. • Pictures • Videos • Any sort of file • POST also uploads HTML forms – data typed in by the user in their web-browser. • The forms can be anything. • You design and implement forms in your returned view. 3 Forms and PHP • Forms can be used to solicit input from a user. • There are two elements: • The required information. • Where to send the information. <form action=“http://your-site/verifyLogin” method="POST"> Login: <input type="text" name=”customer"> Password: <input type="text" name=”credentials"> <input type="submit” name=“submit” value=”Submit”> </form> 4 CI and POST Requests • We know how CI handles HTTP GET parameters. • Class/method/parameters/… • CI handles POST the same way – but we also need access to the data. • To retrieve POST data (e.g. a field in a form, "secure" data) use: $value = $this->input->post(‘field name’); • Returns NULL if the field does not exist. • The field name is created by you when you design your html form. • An HTML form may have multiple fields. Each one will have an entry in CI’s post data. 5 CodeIgniter’s Request Flow • All requests go through index.php • Index.php implements the logic (“special sauce”) that is CI. 6 Review: CodeIgniter URI Segments • CodeIgniter URIs look like: • http://example.com/class/function/param... http://raptor.kent.ac.uk/proj/comp5390/kentmart/your-login/index.php/class/... • URLs form the API to the application. • They are externally visible • They are public • We want them to look elegant and avoid betraying internals • Security and privacy etc. • Apache can transforms URLs for us • We do not want 180+ students given access to configuring the web server • We can change the way the slugs are interpreted using CI routing 7 The Problem • As presented, CI’s segment system by itself is quite inflexible. • Routing remaps the default class/function/parameter sequence so that a URL can be interpreted prior to processing, that is, CI will remap the elements of the URL. • http://example.com/product/1 • http://example.com/product/2 • http://example.com/product/3 • Normally 'product' would be the class (controller) and '1', '2' and '3' would be the methods. • But what is required is to use 1, 2 and 3 as arguments to a method. • We want CI to remap the URL prior to invocation. 8 Answer: CI Routing (Remapping) • Routes live in application/config/routes.php • Inside this file you will see that there is a $routes associative array. • One adds a new route by adding an element to this array. • Some example routes: $route[‘set'] = ‘dictionary’; $route[‘set’][‘put’] = ‘dictionary_safe’; $route['posts/read'] = 'notes/view’; $route[‘dictionary/:num'] = ‘dictionary/get/$1’; $route[‘product/([a-Z]+)/:num'] = ‘$1/browse/$2’; // remap controller // more secure version // remap 1 method // :num = any number // regex /TVs/123 9 PHP Session Handling • One can use "native" PHP sessions in CI • CI also has its own, equivalent but more flexible, mechanism. • Load the session library using: $this->load->library ('session'); • Implies session_start () • Then the PHP $_SESSION super-global associative array is available. • $value = $_SESSION[‘key’]; • I recommend you use CI’s primitives. • Difficult to distinguish between Lvalues and Rvalues. • $_SESSION[‘key’] = $value; • $value = $_SESSION[‘key’]; • Makes searching the code more difficult. 10 Native CI Session Handling • CI includes great support for sessions. • There are 3 important primitives that we will cover. • Read: $value = $this->session->userdata (‘name’); Returns NULL if not found. • Write: $this->session->set_userdata (‘name’, $value); • Delete: $this->session->unset_userdata (‘name’); • I recommend using these. • Distinct names so easy find particular case in the code. 11 Page Caching - CAREFUL • Some pages are expensive to generate: • May involve lots of expensive database queries • Fetching lots of data over a network connection • The caching mechanism allows a controller to request that its output be cached for n minutes • If CI receives another request for the same data (method and parameters) in this time, the cached copy is served • Serving stale data is an extremely serious bug. Be very sure that the page to be cached is valid following aging • Caching is “rare” on the modern web. • More common to cache components instead. • Dynamically generated data far more common. 12 Enabling Caching • Add the following to an action in a controller: $this->output->cache (5); //cache for 5 mins • Set the cache directory's path in the config/database.php file. • The application/cache directory contains the cached output, make sure it is writeable: chmod uog+rwx /path/to/your-cache/cache • Delete the folder’s contents to reset the cache. • Note: raptor is like the wild west with many simultaneous users on it. A production system would have a security model. 13 Profiling • Useful when performance becomes an issue. • Find out where the time is going • The CodeIgniter profiler outputs useful information at the bottom of your page: • Memory usage • Time taken to load/run CI, your controller, and the overall page generation • DB queries performed • HTTP headers sent • Obtained by instrumenting the code. We insert one line in an action: $this->output->enable_profiler (TRUE); 14 Helpers • Helper functions are useful functions designed to perform small tasks. • Think of them as utility functions or libraries. • They are gathered into individual helper classes, which you load with the following line: $this->load->helper (‘name’); • Once loaded you can use all of the class’s functions as if they were built-in PHP functions. • Let’s look at a few of the helper classes, and some of their useful functions. 15 The URL helper site_url (‘dict/get/house'); • Will turn the supplied slugs into a full URL to the page. • Useful for safely coding re-directs. base_url ('media/css/file.css'); • Similar idea, but for files as opposed to controller actions. current_url (); and uri_string (); • The current URL, and controller/action/param slugs, respectively anchor('notes/view/1', 'First Note'); • Returns a full <a href=“”></a> tag for the page, with text 16 The Form Helper – Builds HTML Forms In a view you can use: echo form_open (‘dict/set’); This will produce: <form method="post" accept-charset="utf-8" action="http://example.com/index.php/dict/set"> The form can be labelled: echo form_open (“dict/set”, id=“dictSet”); This applies to all form attributes. 17 The ”form” Helper Family There are many useful forms in the family. • form_input ('notes', 'write text here’); • Produces an input tag with the specified name and default text • form_password (), form_upload (), form_textarea () • Same as above, but for password, file uploads and text areas • form_dropdown (field_name, $array_of_opts) • Creates dropdown input, with options for everything in the array 18 Autoload • If you're going to use a helper everywhere, add it to the list of "autoloaded" helpers in config/autoload.php • You can also autoload libraries (e.g. database) by editing a different array element in the same file: $autoload['libraries'] = array('database', 'session'); • But watch out for overheads. • Loading the database library causes a connection, even if you don't use the database in that request • The profiler will help you decide what to autoload. 19 Other (Occasionally) Useful Things • CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) Generator • To generate captcha images and deter spam bots • Date (& Date Conversion) Helper • To make working with dates a bit easier • Form Validation Library • Automatically reject form input that isn’t valid • Table Generator • Generate HTML tables from arrays inside your constructor, passing them to the view ready-made to reduce complexity • Paginator Generator • Tell it an action that accepts a page number, a no. of records, and no. of records per page, and it generates the links 20 Summary • URL remapping (routing) • Caching: how to configure and control • Profiling CI applications • Helper: libraries of utility functions • Autoloading 21 COMP5390 The “Web” 1 Topics • Web-Scale Computing • What is it? • What is driving growth? • How is it done? • Web network protocols. • Some of the pieces. • Examples of web network protocols. 2 Housekeeping • Group 20 is cancelled owing to the strike. • All other groups are going ahead. • The raptor webserver is available on VPN again. Web-Scale Computing • Web-scale computing, or planetary-scale computing, encompasses enormous services, services that humanity increasingly relies upon. • Google search engine: how many users, to the nearest 10 million, do you think are using this service 24/7? • 70,000 searches per second • 5.4 billion per day • Facebook users upload 400,000,000 files every day. • How much free space do they require every day? • Email • Must be reliable (can not lose data) • Must be available (users must always be able to access said data) • How many simultaneous users do you think Microsoft email services has at any given moment? • There are thousands of examples, and many you are not aware of: • Domain Name Service (DNS) • Internet Routing Protocols The Number of Users is Enormous • There are circa 15,000,000,000 mobile devices active on the Internet • Internet of Things (IoT): 10,000,000,000 • Laptops? • Desktops? • Other? The Internet Distributed Systems • One computer is not powerful enough to handle millions of users. • The work is distributed over multiple different machines. • The machines cooperate to deliver the service. • www.cnn.com is actually many computers. • The machine you connect to will talk to many other computers to build the webpage. Datacenters House the Applications that We Use There are thousands of datacenters around the world. The Internet Microsoft Azure: • 200 datacenters • 4,000,000 servers • Average of 20,000 servers per DC The datacenters are populated with: • Tens of thousands of computers • Atomic clocks • Private networks • Storage • Emergency Power Applications are Built on Applications Application Platforms Application Development/Deployment (PaaS) Development Services Versioning Messaging Security/Identity Primary application at the top Runtime Data Services Application Services Relational Columnar Document Key-Value Object Batch File/Block Middleware Unified Infrastructure Orchestration Infrastructure Services Security SLA Monitoring Physical Infrastructure Infrastructure Logging Dedicated VMWare Provisioning Data at the bottom Storage (Disk/Flash) 8 Websites are Comprised of Multiple Applications Product Images Object Store Financial Transactions Relational Store User Sessions KV Store Shopping Cart KV Session Store Personalized Recommendations Graph Store Product Catalog Document Store Analytics Column Store Datacenter Architecture Application Support Services Authenticate ! Shopping Basket " Recommendations # Ratio of Machines 15000:2500:2500 Datacenter Datacenter security DMZ Application ! Logical Security • DMZ (Demilitarized Zone) • Only machines externally visible • Very limited number of machines they connect to Support Services Authenticate Shopping Basket " Recommendations # Physical Security • A building • Gates and walls • Security guards • Access controls Datacenter Process Flow 1 " 2 9 Build Web Page 1. 2. 3. 4. 5. 6. 7. 8. 9. Connect Authenticate Fetch credentials Receive credentials Verify Log (fail/success) Receive result Build webpage Send webpage Support Services DMZ Authenticate 3 ch t e F d e r C als i t en 4 6 8 7 L og Datacenter Aut h ent ica tion IP Address Review • How do computers connect to each on the Internet? § They must find each other: they need names. • Every computer on the Internet has a unique IP address. • An IP address is a 32-bit number. § 232 = 4,294,967,296 possible values § Remember my claim of more than 25,000,000,000 devices on the Internet? ! 192.65.8.16 ! 192.65.8.22 ! 192.65.8.129 Internet ! 192.65.8.179 Mapping Names to Computers • Domain Name Service (DNS) • Maps human mnemonic to IP Address § Raptor à 129.12.4.232 • Sites such as CNN and Amazon are really millions of machines. • How does DNS handle it? Computer Names 1. 2. 3. 4. Ask DNS: Who is raptor? DNS: 129.12.4.232 Connect to 129.12.4.232 I login Load Distribution • Larges sites need to distribute visitors over machines in the DMZ. • Ideally all the machines in the DMZ would be equally “busy”. § What does busy mean? • Return multiple answers. § amazon.co.uk à { 54.239.33.58, 178.236.7.220, 54.239.34.171 } § cnn.com à { 151.101.67.5, 151.101.3.5, 151.101.195.5, 151.101.131.5 } • The client goes through the list until is manages a connection. • A website thousands. § The DNS server sends back a random selection. § Clients go through the list until they connect. Load Distribution example.com = { 192.0.0.1, 192.0.0.2, . . . 1. Ask DNS for example.com 2. DNS chooses 3 random IPs: { 192.0.0.24, 192.0.0.55, 192.0.0.122 } 3. Safari starts from the left and continues until it connects. 192.0.0.128 } Because the choices are random all DMZ machines should have the same number of connections – equally loaded. Distributed Systems Client-Server • Client-Server: different responsibilities • Manager- (many) Workers: manager assigns jobs to workers § Often used in scientific computing and machine learning. Manager § Manager schedules jobs and workers compute. • Peers Worker § Cooperative § Little or no synchronization Worker Distributing Users Across State • A common problem, N machines and millions of users. • DNS will distribute randomly. § What if we have to visit a particular machine? • How do we ensure that all N machines are utilized equally? • Managers/Workers § Requires synchronization (expensive) § Performance bottleneck § Central point of failure Peer Distribution with Sharding Request: Santry Request: Khan A-D E-I J-P P-U V-Z Distributed Systems – Network Protocols • If an application is distributed, then the pieces communicate over a network. • We need a network protocol. • Distributed applications need to talk to other ancillary applications over a network. • We need a network protocol. • Network protocols are notoriously difficult to implement and debug. • Make the protocol as simple as possible. • Very few messages types, e.g. HTTP • Human readable messages, e.g. HTTP COMP5390 Webservices 1 Topics • Web Services • SOAP • REST 2 Who (What?) Uses the Web? • Thus far we have discussed the interaction between humans and webservers. • People use web browsers and apps. § Results of requests need to be graphically pretty. § Reddit trades on being vintage or, ”old school”, but most sites could not. • Machines also need to talk to machines. • A web service is a service offered by machines for machines. • The machines talk over HTTP. • The applications are limitless. Web Services (WS) • Price comparison sites talk to many websites. § Landing site talks to individual vendors. • Syndication: mirror content between sites. § Facebook mirrors Instagram § UK Met Service • Mashup: mirror content from multiple sites. § News amalgamators (e.g. Apple News) • Embedding § Maps § Videos • Business-to-Business, or B2B § Automated processes implemented with WS. Price Aggregator Web Service American Airlines Flights to Miami, please expedia.com British Airways EasyJet Completely Automated Public Turing test to tell Computers and Humans Apart Google Advertising Real-Time Auction Auction Nissan new car google.com Dacia BMW The Web as APIs • API: Application Programming Interface • Facebook: § GraphAPI § Facebook Login § Marketing API § https://developers.facebook.com/docs/ • Google § Maps § Advertising § Gmail § GoogleDocs § https://developers.google.com/apis-explorer The Web as APIs • Machines do not visit “web pages”. § Actively prevented with CAPTCHA • Machines request services and raw information. • Machines do not want pretty HTML pages. Remote Procedure Call (RPC) • Machines need to agree on a language to speak. • How computer programs ask for data and services? à They call functions x = factorial (5); Program int factorial (int N) { fact = 0; • Can we call a function on another machine? for (i in 1:N) fact *= i; return fact; } Heterogenous RPC Challenges Intel Xeon CPU Apple ARM M2 SoC x = factorial (5); Internet int factorial (int N) { fact = 0; for (i in 1:N) fact *= i; return fact; } Heterogenous RPC Challenges Intel Xeon CPU Apple ARM M2 SoC Integer Representation in a Computer: C main () { int x = 5; int y = 7; int z = x + y; } x86 pushq movq xorl movl movl movl addl movl popq retq %rbp %rsp, %rbp %eax, %eax $5, -4(%rbp) $7, -8(%rbp) -4(%rbp), %ecx -8(%rbp), %ecx %ecx, -12(%rbp) %rbp M2 (ARM) sub mov str mov str ldr ldr add str mov add ret sp, sp, #16 w8, #5 w8, [sp, #12] w8, #7 w8, [sp, #8] w8, [sp, #12] w9, [sp, #8] w8, w8, w9 w8, [sp, #4] w0, #0 sp, sp, #16 • 5 = 00000101 or 10100000 • little endian versus big endian • 52353 = 1100110010000001 • 2 byte integer • 5 bytes of ASCII (one for each character) Simple Object Access Protocol (SOAP) • SOAP is an RPC network protocol for the Internet. • Everything is encoded in XML. • Extremely complicated. • Defines function names, arguments and return. factorial (int) à int • SOAP is stateful. • Implementing, documenting and disseminating is challenging. • Debugging is a challenge. SOAPy is not Simple! To communicate we need the following: • The name of a machine to connect to • The name of an end-point to connect to • The name of an API • Define the data types used by API • Define the arguments and return values of the functions • None of this can change without a great deal of trouble § The web moves at the speed of code! § SOAP can’t keep up with the rate of innovation and security patches. Representational State Transfer (REST) • A design paradigm § Not mutually exclusive with SOAP (but in practice generally they are) • Designed for Internet scale services. • Uses HTTP GET/POST § Pretty darn simple! § Your web browser works like this. • Access is with URLs § That is also the API • Loose coupling between client and server. § Stateless Representational State Transfer (REST) 6 Design Principles to guide RESTful API design: • Uniform API: Everything accessed the same way. • Client-Server based: Communication is point to point, HTTP • Stateless Operation: Server knows nothing of client. § Request has sufficient information to perform operation correctly. • Cache Management: Data labelled. § Cacheable (expiry date) § No cache (purely dynamic) • Code on Demand: Server can customize response on a per client bias. § javascript REST Example: Kentmart Design the website as a finite state automaton untrusted Kentmart/login Kentmart/authenticate untrusted Kentmart/ Kentmart/search Kentmart/buy/Id untrusted api.nasa.gov : Asteroids Near Earth https://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-07&end_date=2015-09-08&api_key=DEMO_KEY Parameter Type Default Description start_date YYYY-MM-DD none Starting date for asteroid search end_date YYYY-MM-DD 7 days after start_date Ending date for asteroid search api_key string DEMO_KEY api.nasa.gov key for expanded usage Web Services Data: json {"links":{"next":"http://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-08&end_date=2015-09-09&detailed=false&api_key=DEMO_KEY","previous":"http://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-06&end_date=2015-0907&detailed=false&api_key=DEMO_KEY","self":"http://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-07&end_date=2015-09-08&detailed=false&api_key=DEMO_KEY"},"element_count":25,"near_earth_objects":{"2015-0908":[{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/2465633?api_key=DEMO_KEY"},"id":"2465633","neo_reference_id":"2465633","name":"465633 (2009 JR5)","nasa_jpl_url":"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=2465633","absolute_magnitude_h":20.36,"estimated_diameter":{"kilometers":{"estimated_diameter_min":0.2251930467,"estimated_diameter_max":0.5035469604},"meters":{"estimated_ diameter_min":225.1930466786,"estimated_diameter_max":503.5469604336},"miles":{"estimated_diameter_min":0.1399284286,"estimated_diameter_max":0.3128894784},"feet":{"estimated_diameter_min":738.8223552649,"estimated_diameter _max":1652.0570096689}},"is_potentially_hazardous_asteroid":true,"close_approach_data":[{"close_approach_date":"2015-09-08","close_approach_date_full":"2015-Sep-08 20:28","epoch_date_close_approach":1441744080000,"relative_velocity":{"kilometers_per_second":"18.1279547773","kilometers_per_hour":"65260.6371983344","miles_per_hour":"40550.4220413761"},"miss_distance":{"astronomical":"0.302747 8814","lunar":"117.7689258646","kilometers":"45290438.204452618","miles":"28142173.3303294084"},"orbiting_body":"Earth"}],"is_sentry_object":false},{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/3426410?api_key=DEMO_KEY"},"id":"3 426410","neo_reference_id":"3426410","name":"(2008 QV11)","nasa_jpl_url":"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3426410","absolute_magnitude_h":21.34,"estimated_diameter":{"kilometers":{"estimated_diameter_min":0.1434019235,"estimated_diameter_max":0.320656449},"meters":{"estimated _diameter_min":143.4019234645,"estimated_diameter_max":320.6564489709},"miles":{"estimated_diameter_min":0.0891057966,"estimated_diameter_max":0.1992466184},"feet":{"estimated_diameter_min":470.4787665793,"estimated_diamete r_max":1052.0225040417}},"is_potentially_hazardous_asteroid":false,"close_approach_data":[{"close_approach_date":"2015-09-08","close_approach_date_full":"2015-Sep-08 14:31","epoch_date_close_approach":1441722660000,"relative_velocity":{"kilometers_per_second":"19.7498128142","kilometers_per_hour":"71099.3261312856","miles_per_hour":"44178.3562841869"},"miss_distance":{"astronomical":"0.259125 0701","lunar":"100.7996522689","kilometers":"38764558.550560687","miles":"24087179.7459520006"},"orbiting_body":"Earth"}],"is_sentry_object":false},{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/3553060?api_key=DEMO_KEY"},"id":"3 553060","neo_reference_id":"3553060","name":"(2010 XT10)","nasa_jpl_url":"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3553060","absolute_magnitude_h":26.5,"estimated_diameter":{"kilometers":{"estimated_diameter_min":0.0133215567,"estimated_diameter_max":0.0297879063},"meters":{"estimated_ diameter_min":13.3215566698,"estimated_diameter_max":29.7879062798},"miles":{"estimated_diameter_min":0.008277629,"estimated_diameter_max":0.0185093411},"feet":{"estimated_diameter_min":43.7058959846,"estimated_diameter_ma x":97.7293544391}},"is_potentially_hazardous_asteroid":false,"close_approach_data":[{"close_approach_date":"2015-09-08","close_approach_date_full":"2015-Sep-08 12:07","epoch_date_close_approach":1441714020000,"relative_velocity":{"kilometers_per_second":"19.1530348886","kilometers_per_hour":"68950.9255988812","miles_per_hour":"42843.4237422604"},"miss_distance":{"astronomical":"0.491743 5147","lunar":"191.2882272183","kilometers":"73563782.385433689","miles":"45710414.7542113482"},"orbiting_body":"Earth"}],"is_sentry_object":false},{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/3726710?api_key=DEMO_KEY"},"id":"3 726710","neo_reference_id":"3726710","name":"(2015 RC)","nasa_jpl_url":"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3726710","absolute_magnitude_h":24.3,"estimated_diameter":{"kilometers":{"estimated_diameter_min":0.0366906138,"estimated_diameter_max":0.0820427065},"meters":{"estimated_di ameter_min":36.6906137531,"estimated_diameter_max":82.0427064882},"miles":{"estimated_diameter_min":0.0227984834,"estimated_diameter_max":0.0509789586},"feet":{"estimated_diameter_min":120.3760332259,"estimated_diameter_ma x":269.1689931548}},"is_potentially_hazardous_asteroid":false,"close_approach_data":[{"close_approach_date":"2015-09-08","close_approach_date_full":"2015-Sep-08 09:45","epoch_date_close_approach":1441705500000,"relative_velocity":{"kilometers_per_second":"19.486643553","kilometers_per_hour":"70151.9167909206","miles_per_hour":"43589.6729637806"},"miss_distance":{"astronomical":"0.0269252 677","lunar":"10.4739291353","kilometers":"4027962.697099799","miles":"2502859.9608192662"},"orbiting_body":"Earth"}],"is_sentry_object":false},{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/3727181?api_key=DEMO_KEY"},"id":"37271 81","neo_reference_id":"3727181","name":"(2015 RO36)","nasa_jpl_url":"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3727181","absolute_magnitude_h":22.9,"estimated_diameter":{"kilometers":{"estimated_diameter_min":0.0699125232,"estimated_diameter_max":0.1563291544},"meters":{"estimated _diameter_min":69.9125232246,"estimated_diameter_max":156.3291544087},"miles":{"estimated_diameter_min":0.0434416145,"estimated_diameter_max":0.097138403},"feet":{"estimated_diameter_min":229.3718026961,"estimated_diameter_ max":512.8909429502}},"is_potentially_hazardous_asteroid":false,"close_approach_data":[{"close_approach_date":"2015-09-08","close_approach_date_full":"2015-Sep-08 14:36","epoch_date_close_approach":1441722960000,"relative_velocity":{"kilometers_per_second":"15.8053596703","kilometers_per_hour":"56899.294813224","miles_per_hour":"35355.0090465835"},"miss_distance":{"astronomical":"0.0540392 535","lunar":"21.0212696115","kilometers":"8084157.219990045","miles":"5023262.364730821"},"orbiting_body":"Earth"}],"is_sentry_object":false},{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/3727639?api_key=DEMO_KEY"},"id":"372763 9","neo_reference_id":"3727639","name":"(2015 RN83)","nasa_jpl_url":"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3727639","absolute_magnitude_h":21.7,"estimated_diameter":{"kilometers":{"estimated_diameter_min":0.1214940408,"estimated_diameter_max":0.2716689341},"meters":{"estimated _diameter_min":121.4940407996,"estimated_diameter_max":271.6689340891},"miles":{"estimated_diameter_min":0.0754928736,"estimated_diameter_max":0.1688071972},"feet":{"estimated_diameter_min":398.6025088171,"estimated_diamete r_max":891.3023057169}},"is_potentially_hazardous_asteroid":false,"close_approach_data":[{"close_approach_date":"2015-09-08","close_approach_date_full":"2015-Sep-08 15:42","epoch_date_close_approach":1441726920000,"relative_velocity":{"kilometers_per_second":"12.0811420305","kilometers_per_hour":"43492.1113096542","miles_per_hour":"27024.3066079349"},"miss_distance":{"astronomical":"0.168419 3589","lunar":"65.5151306121","kilometers":"25195177.358205543","miles":"15655557.2525527734"},"orbiting_body":"Earth"}],"is_sentry_object":false},{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/3730577?api_key=DEMO_KEY"},"id":"37 30577","neo_reference_id":"3730577","name":"(2015 TX237)","nasa_jpl_url":"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3730577","absolute_magnitude_h":23.3,"estimated_diameter":{"kilometers":{"estimated_diameter_min":0.058150704,"estimated_diameter_max":0.130028927},"meters":{"estimated_d iameter_min":58.1507039646,"estimated_diameter_max":130.0289270043},"miles":{"estimated_diameter_min":0.0361331611,"estimated_diameter_max":0.0807962044},"feet":{"estimated_diameter_min":190.7831555951,"estimated_diameter_ max":426.6041048727}},"is_potentially_hazardous_asteroid":false,"close_approach_data":[{"close_approach_date":"2015-09-08","close_approach_date_full":"2015-Sep-08 14:19","epoch_date_close_approach":1441721940000,"relative_velocity":{"kilometers_per_second":"6.573400491","kilometers_per_hour":"23664.2417675863","miles_per_hour":"14704.0395583094"},"miss_distance":{"astronomical":"0.07952387 58","lunar":"30.9347876862","kilometers":"11896602.433824546","miles":"7392205.9712328948"},"orbiting_body":"Earth"}],"is_sentry_object":false},{"links":{"self":"http://api.nasa.gov/neo/rest/v1/neo/3731587?api_key=DEMO_KEY"},"id":"37315 87","neo_reference_id":"3731587","name":"(2015 COMP5390 Web Development Daniel Soria ¡ Adapting sites for mobile § In the browser § In the network § In the server ¡ Content transformation ¡ Browser-services for mobile § Location ¡ Web App or Native App? Page 2 Page 3 http://wtfmobileweb.com Managing browser differences has a long frustrating history § I usually have 3 browsers installed, just in case ¡ Managing device differences exacerbates the problem § Problem = Number of browsers x Number of devices ¡ Adapting sites to device capabilities can be done either: § Client side: At render-time in the browser § In-network: On-the-fly as the content is transferred § Server side: At content-generation time ¡ Page 4 Page 5 Page 6 ¡ CSS allows rules to be selected by “querying” the media types and capabilities of the device on which a document is being displayed. ¡ Use it either in a CSS file: @media screen { /* rules which only apply to screens */ } ¡ Or in the link element of a document’s head: <link rel="stylesheet" type="text/css" media="screen" href=“ScreenSite.css"> <link rel="stylesheet" type="text/css" media="print" href=“PrintSite.css"> Page 7 ¡ As well as the type of media (print, screen, handheld) you can query the capabilities of the device: § width and height (of the screen or browser window) § available colours § orientation – for example is a phone in landscape or portrait mode? § resolution ¡ And combine the resulting values using and, or, not and only: media=“screen and (min-device-width: 800px)” media=“orientation : portrait” ¡ Watch for browser specific capabilities e.g.: -moz-touch-enabled Page 8 ¡ One method: a transcoding proxy ¡ Interpose a proxy between the browser and the server ¡ Intercept HTTP requests for (e.g.) images § Get the image from the originating host § Re-encode it to lower resolution § Return it to the original requestor ¡ Never popular: too much effort ¡ With HTTPS (TLS) not really viable. Page 9 ¡ Use the User Agent string from the http request header, e.g.: 129.12.4.232 - - [23/Nov/2020:11:06:26 +0000] "GET /index.php HTTP/1.1" 200 3151 "-" "Mozilla/5.0 (Linux; Android 9; VOG-L09) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.116 Mobile Safari/537.36” ¡ ¡ The field is parsed in to components and matched. User Agent will probably be replaced with “HTTP Client Hints“ § Multiple HTTP headers (easier to parse and Interpret) § Chrome already implements them. Page 10 ¡ Layout changes § Rearranging logos and menus to avoid scrolling and reflect screen aspect ratio (portrait/landscape) ▪ E.g., see http://getbootstrap.com § Changing the scale of diagrams ¡ Substitutions – audio or images for video ¡ Avoiding unavailable formats (Flash) Page 11 ¡ Accelerometer ¡ Position § Global Positioning System (GPS) § WiFi § Bluetooth § Cellular Towers ¡ Light Detection and Ranging (LIDAR) § True 3D model of world ¡ Video (including stills) § Stereoscopic ¡ Audio ¡ Wearable devices are targeting medical diagnostics. Page 12 ¡ Media audio and video capture/display ¡ Touch events: direct support for multi-touch (otherwise represented as a Mouse event) ¡ Local storage (for name/value pairs) that can survive browser sessions ¡ Local SQL databases and application caches for offline use ¡ Geolocation best-effort: where am I? Page 13 <!DOCTYPE html> <html> <head> <script> var x = document.getElementById ("demo"); function getLocation () { } if (navigator.geolocation) { navigator.geolocation.getCurrentPosition (showPosition); } else { x.innerHTML="Geolocation not supported by this browser."; } function showPosition (position) { x.innerHTML="Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude; } </script> <button onclick="getLocation()">Try It</button> <p id="demo"></p> </body> </html> ¡ Uses data from (with typical accuracy values): § IP address lookup (100m, but often very wrong) § WiFi signal strengths (50m) § GSM base-station signal strengths (500m? depending on tower density) § GPS data (5m horizontal, much worse vertically) ¡ Requires explicit user approval (for privacy/security) ¡ Latitude, Longitude & Altitude ¡ Accuracy estimates. ¡ “High accuracy” option requests (e.g.) GPS data ¡ Heading & Speed – Heading only if speed != 0 Page 15 Page 16 http://xkcd.com/1174/ Web App ¡ Develop once, deploy everywhere ¡ No revenue-sharing with platform owner ¡ Cross-platform UI provides consistency for the app ¡ ??? Page 17 Native App ¡ Need to develop for each platform ¡ Easy purchase through app stores ¡ Platform-specific UI provides consistency with other apps ¡ Usually just the web version in disguise ¡ ??? Simply using the same website does not work. Which is the app, and which the website? ¡ W3Cs Mobile Web Best Practices (classic) ¡ Google's What Makes a Good Mobile Site? ¡ W3Cs Javascript APIs Current Status ¡ HTML5 Geolocation example at W3Schools ¡ Mobile App Developers are Suffering blog post by Alex Austin @ branch.io (accessed 22/11/17) Page 20 COMP5390 Web Programming Recap Doug Santry and Yang He Topics • Recap some of the highlights of COMP3230 • HTML, CSS and JavaScript • PHP basics • PHP errors • Look at objects in PHP • Preparation for using PHP web development frameworks 2 Acronym Soup • HTTP – Hypertext Transfer Protocol • Protocol browsers use to request content over a network from a server. • HTTPS almost exclusively used now (TLS). • HTML – Hypertext Markup Language • Markup language used to format webpages. • CSS – Cascading Style Sheets • Presentational language used to format webpages (HTML). • JS – JavaScript • Programming language used to run programs on the client (in the web browser). • PHP – Hypertext Preprocessor • Programming language used server-side to generate webpages. • SQL – Structured Query Language • Language used to interact with some databases (relational algebra). 3 Static vs. Dynamic Content • Static content • A file to send to the client • Music • Films • Photographs • Archival Material • Dynamic content • A webpage generated by the web server on demand. • Modern web sites wrap static content dynamically • Almost every webpage (facebook, BBC, Amazon, …) 4 Recap COMP3230: HTML CSS JavaScript 5 HTML • Pages start and end with <html> </html> elements • normally contains <head> </head> and <body> </body> elements • HTML elements are (usually) added in pairs • HTML attributes go inside HTML elements • Remember: • <h1> … <h5>, <p>, <a>, <div>, <span>, <table> (<tr> , <td>) • <img>, <br>, <hr> • <style>, <link>, <script> <!DOCTYPE html> <html> <head> <title>Hello world</title> </head> <body> <h1>Page title</h1> <p>A paragraph</p> <a href=“www.somewhere.com”>Name</a> </body> </html> 6 CSS Basics • HTML is a language for formatting the contents of a webpage • Similar to Word (.docx) or Pages (.pages) • CSS is used to visually style web documents: • CSS renders webpages making them look more professional. • Double win: simultaneously makes it easier to create webpages. • CSS can be declared: • Inline • Internal • External 7 CSS Example <!DOCTYPE html> <html> <head> <title>Hello world</title> Internal CSS <style type="text/css"> .messages { color: red; font-weight: bold; } </style> </head> <body> <p class="messages">Hello world</p> <p style="color: blue">Hello again</p> </body> Inline CSS </html> 8 CSS External <!DOCTYPE html> External CSS <head> <title>Hello world</title> <link rel="stylesheet" type="text/css" href=“my-styles.css"> </head> <body> <p class=“messages">Hello world</p> </body> my-styles.css </html> .messages { color: red; font-weight: bold; } 9 CSS Rules, Declarations and Selectors Selector Declaration Declaration h1 { color: blue; font-weight: bold; } Property Value Property Value • A CSS selector is the bit that selects the HTML elements to be affected by the rule • A CSS declaration sets a specified property of the selected element(s) to a specified value • A CSS rule is the whole thing List of Properties: https://www.w3schools.com/cssref/index.php 10 CSS Selector examples h1 selects all h1 elements .foo selects all elements with the attribute class = “foo” #foo selects the element with the attribute id = “foo” h1.foo selects all h1 elements with the attribute class = “foo” div p selects all p elements inside a div 11 JavaScript • JavaScript is downloaded and executed by the browser. • JavaScript code can modify the contents of the page after it has been displayed by the browser by modifying the DOM (Document Object Model). • Similar to CSS, JavaScript can be declared internally or externally <script type="text/javascript"> alert('annoying popup'); </script> Internal JS External JS <script type="text/javascript" src="annoyingPopup.js"/> 12 The Document Object Model • The DOM works by organising HTML elements into a tree structure • Example: Image: http://www.webstepbook.com/supplements/slides/lecture16-dom_tree.shtml <html> <head> <title></title> <meta /> <meta /> </head> <body> <h1></h1> <p> <a></a> </p> <ul> <li></li> <li></li> <li></li> </ul> </body> </html> 13 PHP Recap 14 PHP • PHP is a language used to programmatically generate webpages. • PHP code is executed on the web server. • Dynamic webpages are generated with PHP. • When a PHP script is interpreted, the code between the <?php and ?> tags is run, and the rest of the page is output verbatim: <!DOCTYPE html> <head><title>PHP script with HTML</title></head> <body> <?php print "<h1>Hello world</h1>"; ?> <p>Normal HTML text</p> </body> </html> 15 Forms and PHP • Forms can be used to solicit input from a user. • There are two elements: • The required information. • Where to send the information. <form action=“http://your-site/verifyLogin” method="POST"> Login: <input type="text" name=”customer"> Password: <input type="text" name=”credentials"> <input type="submit” name=“submit” value=”Submit”> </form> 16 A PHP Class <?php class UserRequest { private $hits = 0; public function search ($item) { $this->hits = $this->hits + 1; // search code here… } public function showHits ($item) { echo $this->hits; } } ?> 17 Visibility and Access • Data and functions in an object can be marked as: • private - visible only to the implementation of the object • public - visible to users of the object as well • Objects have constructors (used to initialise data) called _ _construct (note two underscores) • Whenever you create an object, its constructor (if any) is implicitly called • The current object is accessed with $this (be careful!) • #1 bug: $this->hits++ is not the same as $hits++. • You can refer to data/functions in a particular class using className:: or parent:: 18 PHP Inheritence Superclass (parent) Subclass (child) class Animal { private $name; private $legs; public function __construct($n, $l) { $this->name = $n; $this->legs = $l; } public function getName() { return $this->name; } } class Dog extends Animal { private $type; public function __construct($name, $type) { parent::__construct($name, 4); $this->type = $type; } public function getType() { return $this->type; } } $dog = new Dog('Alf', 'Dalmatian'); echo 'Name: '. $dog->getName() . ' Type: ' . $dog->getType(); 19 PHP Warnings, Errors and Notices PHP offers many levels of problem reporting: • A Parse Error means that code is not syntactically correct • e.g. missing ;, { or ) • PHP will simply give up when it encounters malformed code • A Fatal Error is a serious problem when running your code • e.g. a function not defined • Execution stops immediately • A Warning is a less serious problem • E.g. a missing function argument • PHP will try to continue running • A Notice is a minor issue • E.g. echoing a variable that doesn’t exist • PHP will try to continue, but it might not end well 20 Parse Errors and Line Numbers Parse errors include the file and line number. Always start there. But the problem may lie somewhere else: • It is the line where PHP noticed the problem. • Missing semicolons are usually noticed on the next line down. • Errors with quotes are often not detected until the next string (and it might be far away in the code). • Errors with brackets are sometimes noticed much later in your script, or right at the end. Good indentation can speed up the detection of mistake. • Commenting code out until the mistake is no longer reported can help. Slowly uncomment piece by piece and the problem should be found. • Be the parser! Read the code carefully to find the mistake. 21 Example Parse Error On line 3 1 2 3 4 5 6 7 <?php function output($a) { if (true Missing the { closing bracket ) echo "$a"; } } Mentions something else And only on the next line Parse error: syntax error, unexpected '{' in example.php on line 4 22 Decoding PHP's error messages • A very common parse error is: Parse error: syntax error, unexpected <foo>, expecting <bar> in <script> on line <number> • <foo> and <bar> vary, they can be brackets, semicolons, or any of the PHP language tokens (identified as T_SOMETHING) • Example: Parse error: syntax error, unexpected '}', expecting ',' or ';' in index.php on line 14 • The general way to fix these is to: • Find <foo> on line <number> • Look back at the preceding code (same line, and then previous line) to figure out why PHP was expecting <bar> 23 Fatal Errors, Warnings and Notices • The line number here is much more reliable • Messages generally helpful, e.g.: Fatal error: Cannot redeclare foo() (previously declared in file.php:17) in anotherfile.php on line 119 • This error says that the function foo() is already defined • If you’ve got lots of warnings/errors/notices, pay attention to the first one - others may be a consequence of that • A variable may well be null because of the first problem, and other operations on that variable may fail as a result 24 Debugging Techniques • Unlike Java, PHP is interpreted. • Syntax errors are discovered at run-time. • The code is executed remotely. • No debuggers to step through the code. • While developing instrument your code. • echo() • var_dump() • print_r() • Careless mistakes are difficult to find later. • Comment your code. • Indent your code (this will help you find bugs while writing code). 25 var_dump Example php > var_dump ($dog); object(Dog)#1 (3) { ["type":"Dog":private]=> string(9) "Dalmatian" ["name":"Animal":private]=> string(3) "Alf" ["legs":"Animal":private]=> int(4) } 26 Experiment with PHP Interactively • Login to raptor • ssh on MacOS • Putty.exe on Windows • php –a • Cut&paste code to find problems. • Try it with the inheritance example. • Paste the superclass • Paste the subclass • Paste the code that instantiates and runs. The result should be: Name: Alf Type: Dalmatian • What is the difference between var_dump and print_r? 27 Interactive PHP and Debugging php > $myvar = array ('a' => ‘Debug', 'b' => ’Code', 'c' => array (’Macos’, ’Windows’)); php > $debug = print_r ($myvar, true); php > echo $debug Array ( [a] => Debug [b] => Code [c] => Array ( [0] => Macos [1] => Windows ) ) 28 Summary • We have briefly refreshed material from COMP3230. • You should know where the different languages fit in the big picture. • There are many great sites where help can be found. PHP is here: • https://www.php.net • We have looked at OO techniques in PHP. • There are PHP interpreters for MacOS, Windows and Linux available to download for practice. • Try var_dump ($myvar) and var_dump ($debug). What is the difference? 29 COMP5390 Web Development Daniel Soria iOS and Android are very prescriptive. They need control. ¡ Security § Social app should not access bank application ¡ Privacy § Cameras and microphones are sensitive ¡ Power Management § A rogue application can run down the battery ¡ Verify terms of use. Page 2 Page 3 ¡ Views § UI elements ¡ Content Providers § Enable data sharing between applications ¡ Resource Manager § Provides access to non-code resources ¡ Notification Manager § Enables applications to display alerts, status messages, etc ¡ Activity Manager § Manages lifecycles of activities Page 4 Applications are written in Kotlin or Java. ¡ Bytecode compiled Ahead Of Time on device by Android Runtime VM (ART) to native machine code. ¡ § Traditional JVM too power hungry. § Now bundles pre-compiled binaries for common platforms ¡ Applications (VMs) run in their own dedicated Linux process. § Started and shutdown as needed ¡ Each application has a unique Linux user ID. § Processes run with low privileges. § Applications files are not visible to other applications. Page 5 ¡ An app is a collection of components. § Subclassed from frameworks. ¡ No single entry point – no main() ¡ May interact with other apps via their published interfaces. ¡ App components are started when needed. ¡ Applications inherit from classes to expose or access services. Page 6 ¡ Activity § User interface (composed of Views) for a single task § An application may use several Activities § May be used by several applications ¡ Service § Background process, no UI § May be used by several applications ¡ Broadcast Receiver § Receives/acts on notifications ¡ Intent § Used to activate Activities, Services and Broadcast Receivers ¡ Content Provider § Makes data available to applications. Page 7 ¡ All application packages (apk’s) include an AndroidManifest.xml file § Declares components § Names required libraries § Lists permissions required ▪ Content Providers (e.g. contacts) ▪ Hardware (e.g. camera) § Associates components with intents § Says how each intent should be invoked (e.g. by the Launcher) § Specifies icons and labels for display to the user Page 8 /** Copyright (C) 2007 The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); * … */ package com.example.android.helloactivity; import android.app.Activity; import android.os.Bundle; public class HelloActivity extends Activity { public HelloActivity() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View view = MakeView ( … ) // Build our view setContentView(view); // Paint the screen } } ¡ 3 states: § Active – in foreground, focus of user’s actions § Paused – (misnomer) still working, still (partially visible) but UI updates are not reflected on the screen. § Stopped – not visible, retains state When paused or stopped, system may remove it to reclaim memory ¡ Activity is notified of state changes by callbacks to your android.app.Activity sub-class: ¡ onCreate(), onStart(), onRestart(), onPause(), onResume(), onStop(), onDestroy() The Bundle savedInstanceState is a name/value structure to hold application data between invocations (think of it as like a session variable). Page 10 Page 11 • Just like a website, or any software, we need a design paradigm (or a design pattern). • There are many. • The flow of Android (event driven). • Model/Views/Controller (MVC) was an example. • MVC can be used for apps. • Isolate the business logic. Page 12 ¡ Continuously running background process § Provide shared service to one or more apps (activities) ▪ e.g. location tracking, music playing, … § Perform long-running tasks for a single app ▪ e.g. network file up/down-load, … ¡ Two priorities: § Foreground (high), background (low) ¡ Several alternative lifecycles: § Started and stopped by client app (or stopped by self) § Started by client, runs until task completed then stops § Once started, other clients may bind to the service § Service will not be stopped if running or has bound clients (except in extreme low-memory cases) Page 13 ¡ Content providers are custodians of data ¡ Built-in CPs for contacts list, audio, image and video store ¡ Two means of offering data: § Build a CP by subclassing ContentProvider § Publish to existing ContentProvider ¡ ContentResolver connects to a CP ¡ An object’s name is: § content://provider-name/object.../ Page 14 ¡ We've looked at: § The structure of the Android system and Android applications § How Android applications describe themselves § The lifecycle of an Android application § Non-user-facing components ¡ Next: the user-facing bits – GUIs Page 15 COMP5390 Web Development Daniel Soria An app called “Convert” which converts Celsius to Fahrenheit and vice versa ¡ Contents: ¡ § One input field with some “hint text” § A pair of labelled radio buttons § A button labelled “Calculate” which triggers the conversion ¡ Page 2 These things are all resources of the application ¡ Include strings and UI layouts (in XML) and images (png, jpg, gif) for use by your app res/ drawable/ icon.png layout/ main.xml info.xml values/ values-fr/ strings.xml strings.xml ¡ Alternative resources are indicated by adding qualifiers Page 3 to resource directory name (e.g. -fr for French, -port/-land for orientation, etc.) <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/myColor"> <RadioGroup android:id="@+id/radioGroup1" <RadioButton android:id="@+id/radio0" android:checked="true" android:text="@string/celsius"> </RadioButton> </RadioGroup <Button android:text="@string/calc" android:id="@+id/button1" android:onClick="myClickHandler"> </Button> </LinearLayout> Page 4 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/myColor"> <RadioGroup android:id="@+id/radioGroup1" <RadioButton android:id="@+id/radio0" android:checked="true" android:text="@string/celsius"> </RadioButton> </RadioGroup <Button android:text="@string/calc" android:id="@+id/button1" android:onClick="myClickHandler"> </Button> </LinearLayout> Page 5 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Convert</string> <string name="celsius">to Celsius</string> <string name="fahrenheit">to Fahrenheit</string> <string name="calc">Calculate</string> <color name="myColor">#3399cc</color> <string name="inputHint">Input temp</string> </resources> Page 6 ¡ The XML files are compiled into your application and appear as static attributes of (subclasses of) the class YourActivity’sPackage.R, named by: § their type, e.g.: string, drawable, color § the value of their XML android:name attribute (e.g. R.string.calc for a string attribute named calc in res/strings.xml), or their filename for non-XML resources (e.g. R.drawable.icon) Page 7 public class ConvertActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } // Called at button click because we assigned the name // to the "On Click property" of the button public void myClickHandler(View view) { switch (view.getId()) { case R.id.button1: // ... } } } Page 8 If an activity wants any of its state to survive shutdown/restart, it must save it when it becomes vulnerable ¡ As well as the other lifecycle callbacks, activities can override: void onSaveInstanceState(Bundle) void onRestoreInstanceState(Bundle) ¡ Bundle is also passed to onCreate() ¡ Activities can put key/value pairs (like a Map) into the Bundle and retrieve them when restarted ¡ GUI components implement this method pair to save their own graphical/selection state ¡ An easy way to save simple application state ¡ Page 9 ¡ An activity’s UI comprises a number of views (e.g. main and info, above), composed of subclasses of: § ViewGroup objects, containers or layouts for § View objects, the widgets in your UI VG ¡ Organised in a tree ¡ ViewGroup extends View VG ¡ Set the current view using: setContentView(View v) Page 10 View View View View ¡ LinearLayout – a vertical or horizontal stack of widgets: § Direction governed by the orientation attribute (“horizontal” or “vertical”) § Size of contents governed by their layout_width and _height attributes (typically “fill_parent”) § Stretchability of contents governed by their gravity and relative layout_weight attributes GridLayout – borderless, composed of columns, rows and cells (like an HTML table) ¡ RelativeLayout allows positioning of elements above/below/centered each other. ¡ ScrollView – wraps up a layout in a scrollable viewport ¡ Page 11 ¡ The usual set: Button, RadioButton (contained in a RadioGroup), ImageButton, CheckBox, TextView (single or multi-line) ¡ Default contents, fonts, shapes and names set via properties ¡ You can create your own widgets by aggregating existing Views, or creating entirely new View subclasses. Page 12 ¡ The Android documentation, including the Dev Guide, Reference Manual and installation instructions downloads with the Android SDK ¡ Lars Vogel’s Android Development Tutorial ¡ How far can you go? A 1-hour YouTube video presentation on Taming Android UIs with Eric Burke of Square ¡ Google uses a design metaphor and set of guidelines called Material Design to encourage consistency across UI developers Page 13