Skip to content
UoL CS Notes

COMP284 (Scripting Languages)

Event-Driven Programs

COMP284 Lectures

Our programs can react to events on the client side by writing event handlers.

There is an example of creating noughts and crosses starting from slide 13 of the lecture. This is hosted live at: https://cgi.csc.liv.ac.uk/~ullrich/COMP284/examples/jsBoard.html.

Events

Event handlers are associated with HTML elements for a specific event. We can do this with attributes:

<input type="button" value="Help" onclick="Help()">

or by using a JavaScript function:

// For Browsers
window.addEventListener("load", Hello)
// Internet Explorer
window.attachEvent("onload", Hello)

Attaching Event Handlers

We can use JavaScript to add a handler to a HTML element. The following conditional statement also supports IE:

// adding
if (window.addEventListener) {
	window.addEventListener("load", Hello)
} else {
	window.attachEvent("onload", Hello)
}

// removing
if (window.removeEventListener) {
	window.removeEventListener("load", Hello)
} else {
	window.dettachEvent("onload", Hello)
}

This is required as IE has different function names for adding events.

We can also place an event attribute on the element like so:

<html>
	<head>
	</head>
	<body onload="Hello()">
	</body>
</html>

We typically use onload with the body element or window object.

Other Events

Event Description Attribute
focus Occurs when a form field receives input. onFocus
change Occurs when an input is modified. onChange
blur Occurs when an HTML element loses focus. onBlur
click Occurs when an object is clicked. onClick
keydown Occurs when a users presses a key. onkeydown
mouseOver Occurs once each time the mouse pointer moves over an HTML element. onMouseOver
select Occurs when a users selects some of the text within an object. onSelect
submit Occurs when a user submits a form. onSubmit

Creating Custom Events

When an event occurs, an event object, with methods and attributes, is created. We can make our own event objects which will be passed to event handler functions (not in IE).

In Internet Explorer we can access only the most recent event with window.event.

<html>
	<body onKeyDown="processKey(event)">
		<script>
		function processKey(e) {
		e = e || window.event	// this accommodates for IE
		document.getElementById("key").innerHTML = String.fromCharCode(e.keyCode) + 'has been pressed '
		}
		</script>
		<!-- key code will appear in the paragraph below -->
		<p id="key"></p>
	</body>
</html>

Dynamic Web Pages Using JavaScript

COMP284 Lectures

Window Object

A window object represents an open window in a browser. If a document contains frames, there there is:

  • One window object, for the HTML document.
  • One additional window object for each frame accessible via a window.frames array.

Whenever an object or property is referenced in a script without an object name and dot prefix it is assumed to be a member of the window object.

window has the following properties:

Property Description
document The document object for the window.
history The history object for the window.
location The current URL of the window.
navigator The web browser object for the window.
opener Reference to the window that created the window.
innerHeight Inner height of a window’s content area.
innerWidth Inner width of a window’s content area.
closed A boolean value indicating whether the window is still open.

The properties of the navigator object include:

Property Description
navigator.appName The web browser’s name.
navigator.appVersion The web browser’s version.

This can be used to load different style sheets depending on browser version.

Window Object Methods

Methods provided by the window object include:

open(url, name[, features])

Opens a new browser window/tab:

  • Returns a reference to a window object.
  • url is the URL to access in the new window.

    This can be an empty string.

  • name is a name given to the window for later reference.
  • features is a string that determines various window features.

We can use this like so:

var newWin = window.open(...)
newWin.document.write('<html>...</html>')

There are also the following methods:

Method Description
close() Closes a browser window or tab.
focus() Give focus to a window.
blur() Removes focus from a window.
print() Sends the contents of the current window to the printer.

Dialog Boxes

The window object provides predefined methods for the handling of dialog boxes.

alert()

alert(message_string)
  • The box contains an OK button that the user will have to click for execution to resume.


confirm()

bool confirm(message_string)
  • The box contains two buttons: Cancel and OK.
  • The function returns true if the user selects OK and false otherwise.


prompt()

Creates a dialog box displaying message_string and an input field:

string prompt(message_string[, default])
  • default will be shown in the input field, if given.
  • The box contains two buttons: OK and Cancel.
  • If the users selects OK then the current value entered in the input field is returned as a string, otherwise null is returned.


To convert from a string to other datatypes we can use the following functions:

  • parseInt(string[, base])
  • parseFloat(string)
  • Number(string)

Input Validation

There is an example of user input validation at:

The code is also available staring at slide 15.

Document Object Model (DOM)

We can use the document object to interact with the DOM.

The following HTML:

<table>
	<tbody>
		<tr>
			<td>Shady Grove</td>
			<td>Aeolian</td>
		</tr>
		<tr>
			<td>Over the River, Charlie</td>
			<td>Dorian</td>
		</tr>
	</tbody>
</table>

is converted into the following DOM:

graph TD
table["table"] --> body[tbody] --> tr1[tr] & tr2[tr]
tr1 --> td1[td] & td2[td]
td1 --> sg[Shady Grove]
td2 --> a[Aeolian]
tr2 --> td3[td] & td4[td]
td3 --> otrc[Over the River, Charlie]
td4 --> d[Dorian]

Accessing via Object Methods

We can access objects in the DOM by using the tree:

var first = document.firstChild;
var firstChild = first.childNodes[1];
first.removeChild(firstChild);
first.data = "Hello";

Accessing via Names

So that we don’t have to use child and parent selectors, we can give objects names:

<div>
	<form name="form1" action"">
		...
	</form>
</div>

We can then access them like so:

document.div.form1

The path of an object could change when editing the DOM so this method isn’t always too useful.

Accessing via IDs

IDs are a more reliable way to access objects. We can assign them like so:

<div>
	<form id="form1" action"">
		...
	</form>
</div>

and find that object that they are referring to like so:

document.getElementById("form1")

we can then get the value of this object like so:

document.getElementById("form1").value

Manipulating HTML elements

There is an example of manipulating HTML elements using JavaScript here:

The code is also available staring at slide 23.

JavaScript - Functions, Libraries & Objects

COMP284 Lectures

Functions

A basic JavaScript function takes the following form:

function identifier(param1, param2,...) {
	statements
}

We can also assign a function to a variable like so:

var identifier = function(param1, param2, ...){
	statements 
}

identifier.length can be used inside the body of the function to determine the number of parameters.

Default Values for Parameters

For every browser apart from internet explorer we can use the following syntax:

function sum(num1 = 0, num2 = 0) {
	...
}

but for internet explorer we can do the following:

function sum(num1, num2) {
	if (num1 == undefined) num1 = 0
	if (num2 == undefined) num2 = 0
	...
}

Functions as Arguments

Functions are objects in JavaScript and can be passed to other functions:

function apply(f, x, y) {
	return f(x, y)
}
function mult(x, y) {
	return x * y
}
console.log('2 * 3 =', apply(mult, 2, 3))

Variable-Length Argument Lists

Every JavaScript function has an array called arguments which consists of all the arguments passed to a function:

function sumAll() {
	var sum = 0
	for (var i = 0; i < arguments.length; i++) {
		sum += arguments[i]
	return sum
}

Global Static Variables

We can make global static variables to preserve the value of a variable between function calls:

function counter() {
	counter.count = counter.count || 0
	counter.count++
	return counter.count
}
document.writeln("1: static count = " + counter())
document.writeln("2: static count = " + counter())
document.writeln("3: global counter.count = " + counter.count)
1. static count = 1
2. static count = 2
3. global counter.count = 2

Nested Functions

Function definitions can be nested in JavaScript:

  • Inner function have access to the variables of outer functions.
  • By default, inner function can not be invoked from outside the function they are defined in.
function bubble_sort(array) {
	function swap(i, j) {
		var tmp = array[i]; array[i] = array[j]; array[j] = tmp;
	}
	if (!(array && array.constructor == Array))
		throw("Argument not an array")
	for (var i = 0; i < array.length; i++) {
		for (var j = 0; j < array.length - i; j++) {
			if (array[j + 1] < array[j]) swap(j, j + 1)
		}
	}
	return array
}

JavaScript Libraries

JavaScript libraries can be imported to HTML using the following syntax:

<script src="url"></script>

Objects

Object Literals

Instead of having classes, JavaScript has object literals. They have the following syntax:

{memberName1: value1, memberName2: value2, ...}

and can look like the following:

var person1 = {
	age:	(30 + 2),
	gender: 	'male',
	name:	{first:	'Ben', last:	'Weston'},
	interests:	['music', 'skiing'],
	hello:	function() {return 'Hi! I\'m ' + this.name.first + '.'}
}

Member values can be accessed using dot notation or bracket notation:

person1.age
person1['gender']

Object Constructors

We can use functions to act as object constructors like so:

function SomeObj() {
	this.prop1 = 'A'	// public property
	var  prop2 = 'B'	// private property
	this.method1 = function() {	// public method
		return 'm1[prop1 = ' + this.prop1 + ' prop2 2 = ' + prop2 + ']'
	}
	var method 2 = function() {...}	// private method
}
obj1 = new SomeObj()
obj2 = new SomeObj()

Prototype Property

All functions have a prototype property that can hold shared object properties and methods:

  • Objects do not store their own copes of these properties and methods, but only store references to a single copy.
function SomeObj() {
	this.prop1 = 'A' 	// public property
	var prop2 = 'B' // private property
	
	SomeObj.prototype.method1 = function() {...} // public prototype
	
	var method2 = function() {...} // private method

These can be edited during runtime to change the behaviour of a set of objects.

Class Variables & Methods

Function properties can be used to emulate Java’s class variables & methods (static variables shared among instances).

function Circle(radius { this.r = radius }

// class variable - property of the Circle constructor function

Circle.PI = 3.14159

// instance method
Circle.prototype.area = function() {
	return Circle.PI * this.r * this.r;
}

// class method - property of the Circle constructor function
Circle.max = function (cx, cy) {
	if (cx.r > cy.r) {return cx } else { return cy }
}

c1 = new Circle(1.0) // create an instance of the Circle class
c1.r = 2.2 // set the r instance variable
c1_area = c1.area() // invoke the area() instance method
x = Math.exp(Circle.pi) // use the PI class variable in a computation
c2 = new Circle(1.2) // create another Circle instance
bigger = Circle.max(c1, c2) // the the max class method

Private Static Variables

In order to create private static variables shared between objects we can us a self-executing anonymous function:

var Person = (function () {
	var population = 0 // private static class variable
	return function (value) { // constructor
		population++
		var name = value // private property
		this.setName = function(value) {return name}
		this.getName = function() {return name}
		this.getPop = function() {return population}
	}
}())
person1 = new Person('Peter')
person2 = new Person('James')

Pre-Defined Objects

String

A String object encapsulates the values of the primitive datatype string.

Properties of String include:

  • length - The number of characters in the string.

Methods of String include:

Method Description
charAt(index) Returns the character at position index, starting at 0.
substring(start, end) Returns the part of a string between positions start and end inclusive.
toUpperCase() Returns a copy of a string with all the letters in uppercase.
toLowerCase() Returns a copy of a string with all letters in lowercase.

RegExp

JavaScript supports perl-like regular expressions. String object have methods that use regular expressions:

Method Description
search(regexp) Matches regexp witha string and retursn the start position of the first match, or -1 if there is no match.
match(regexp) Without g, returns the matching groups for the first match. With g, returns an array containing all the matches for the whole expression. Returns null if no match is found.
replace(regexp, replacement) Replaces matches for regexp with replacement and returns the resulting string.

Date

The Date object can be used to access the local date and time.

It supports the following constructors:

new Date() // current date and time
new Date(milliseconds) // set date to unix millis
new Date(dateString) // set date according to dateString
new Date(year, month, day, hours, min, sec, msec)

Date also provides the following methods:

Method Description
toString() Returns a string representation of the Date object.
getFullYear() Returns a four digit string representation of the current year.
parse() Parses a date string and returns it in unix millis.

JavaScript Control Structures & Arrays

COMP284 Lectures

Control Structures

Conditional Statements

Conditional statements can take the following forms:

if (condition)
	statement
else if (condition)
	statement
else
	statement
condition ? if_true_expr : if_false_expr

Switch Statements

We can use switch statements like so:

switch (expr) {
	case expr1:
		statements
		break;
	case expr2:
		statements
		break;
	default:
		statements
		break;
}

while & do while Loops

We can use these two different types of while loop like so:

while (condition)
	statement
do
	statement
while (condition)

For Loops

We can write for loops with the following syntax:

for (i = 1, j = 1; j >= 0; i++, j--)
	document.writeln(i = " * " + j + " = " + i*j)

Variables declared in the for loop are still visible outside the loop. We can use let, instead of var, to declare a variable that is local to a block.

break & continue

We can use these statements in a loop to modify the program flow:

  • break - Stops execution of the loop and continues with the rest of the program.
  • continue - Stops execution of the current iteration of the loop and skips to the next iteration.

Error Handling

When a JavaScript statement generates an error, an exception is thrown. We can use the following structure to handle this behaviour:

x = "A"
try {
	if (isNaN(x)) throw "x is NaN"
	y = x.toFixed(2)
} catch (e) {
	document.writeln("Caught: " + e)
	y = 0
} finally {
	document.writeln("y = ", y)
}

You can also see that we can use throw to generate exceptions.

Arrays

An array is created by assigning an array value to a variable:

var arrayVar = [elem0, elem1, ...]

We can find the length of an array like so:

var length = arrayVar.length

Assigning a value to arrayVar.length will extend, or shrink, the array to this new length.

We can return a copy of any array by using the slice function:

var newArray = arrayVar.slice(start, end)

This can be useful as, by default, arrays are passed by reference.

Other Array Operators

JavaScript has no stack or queue data structures. We do have the following functions though:

Function Description
array.push(value1, value2, ...) Appends one or more elements to the end of an array. Returns the number of elements in the resulting array.
array.pop() Extracts the last element from an array and returns it.
array.shift() Extracts the first element of an array and returns it.
array.unshift(value1, value2, ...) Inserts one or more elements at the start of an array variable. Returns the number of elements in the resulting array.

Iterating on Arrays

The recommended way to iterate over all elements of an array is a for loop:

for (i = 0; i < arrayVar.length; i++) {
	... arrayVar[i] ...
}

We can also use the forEach method like so:

var callback = function (elem, index, arrayArg) {
	statements
}
arrayVer.forEach(callback);
  • The forEach method takes a function as an argument.
  • It iterates over all elements of the array.
  • It passes the current array element elem, to the current index index and a pointer to the array arrayArg to the function.
  • Return value of that function is ignored.

JavaScript Introduction

COMP284 Lectures

JavaScript is a language for client-side programming.

Hello, world!

<!DOCTYPE html>
<html lang="en-GB">
<head>
	<title>Hello, world!</title>
</head>
<body>
	<script>
		document.writeln("<p><b>Hello, world!</b></p>");
	</script>
	<noscript>
		<p><b>Please enable JavaScript to see the super secret message!</b></p>
	</noscript>
</body>
</html>
  • Script is enclosed in script tags.
  • Alternative HTML is enclosed in noscript tags.

Types

JavaScript is a dynamically and loosely typed language. It has five different types:

  • boolean
  • number
    • This is both integers and floating point numbers are treated the same.
    • We can use the Math object (Math.log()) to do mathematical functions.
  • string
  • function
  • object

We can find the type of an object like so:

document.writeln("Type of 23.0: " + typeof(23.0));

Typecasting

We can cast types by wrapping them in an appropriate object from:

  • Number()
  • String()
  • Boolean()

We can also process specifically as an int or float:

  • parseInt()
  • parseFloat()

Strings

We can write strings like so:

document.writeln("Your name is " + name + "and\
	you are studying " + degree + "\
	at " + university);

Variables

Variables can be declared like so:

var variable1 = value, variable2 = value2, ...

If you don’t initialise a variable before using it you will get a reference error.

The PDO Class (Databases in PHP)

COMP284 Lectures

The PHP Data Objects (PDO) extension defines an interface for accessing databases in PHP.

Connections

We create a connection to the database server by creating an instance of the PDO class. We can use the following constructor to this:

$pdo = new PDO(dsn, username, password, options);

The connection remains open for the lifetime of the object. Therefore, we can close the connection by running the following:

$pdo = NULL

A full example would look like so:

# Connection information for the Departmental MySQL Server
$host = "studdb.csc.liv.ac.uk";
$user = "sgfsurn"; # your University username
$passwd = "-------" ; # your MySQL server account password
$db = "sgfsurn"; # your University username
$charset = "utf8mb4";
$dsn = "mysql:host = $host; dbname = $db; charset = $charset " ;

# Useful options
$opt = array (
	PDO::ATTR_ERRMODE	=> PDO::ERRMODE_EXCEPTION,
	PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
	PDO::ATTR_EMULATE_PREPARES => false
);

try {
	$pdo = new PDO($dsn, $user, $passwd, $opt);
} catch(PDOException $e) {
	echo 'Connection failed: ', $e->getMessage();
}

Queries

The query() method of PDO object can be used to execute an SQL query:

$result = $pdo->query("SELECT * FROM meetings");

The exec() method of PDO objects executes an SQL statement, returning the number of roes affected by the statement:

$rowNum = $pdo->exec("DELETE * FROM meetings");

Processing Result Sets

Getting results in this way can leave the server open to SQL injection attacks. You should use prepared statements instead.

fetch()

To get a single row as an array from a result set stored in a PDOStatement object, we can use the fetch() method.

By default, PDO returns each row as an array indexed by the column name and a 0-indexed column position in the row:

$row = $result - > fetch ()
array(
	'slot' => 1,
	'name' => 'Michael North',
	'email' => 'M.North@student.liverpool.ac.uk',
	0 => 1,
	1 => 'Michael North',
	2 => 'M.North@student.liverpool.ac.uk'
)

After the last call of fetch() the result set should be released using:

$rows = $result->closeCursor();

fetchAll()

To get all rows as an array of arrays from a resut set stored in a PDOStatement object, we can use the fetchAll() method:

$rows = $result->fetchAll();

We can use a while-loop together with the fetch() method to iterate over all rows in a result set:

while ($row = $result->fetch()) {
	echo "Slot: ", $row["slot"], "<br>\n";
	echo "Name: ", $row["name"], "<br>\n";
	echo "Email: ", $row["email"], "<br>\n";
}

alternatively we can use a foreach loop:

foreach ($result as $row) {
	echo "Slot: ", $row["slot"], "<br>\n";
	echo "Name: ", $row["name"], "<br>\n";
	echo "Email: ", $row["email"], "<br>\n";
}

fetch() uses a cursor that moves through the rows in a result set and does not reset at the end. You should store the result set in an array first, then iterate over the array as often as you like.

bindColumn()

We can bind a variable to a particular column in the result set of a query:

  • Columns can be specified with a number (indexed at 1).
  • Columns can be specified by name.

We can use it like so:

$result->bindColumn(1, $slot);
$result->bindColumn(2, $name);
$result->bindColumn("email", $email);
while($row = $result->fetch (PDO::FETCH_BOUND)) {
	echo "Slot: ", $slot, "<br>\n" ;
	echo "Name: ", $name, "<br>\n" ;
	echo "Email: ", $email, "<br>\n" ;
}
  • Each call to fetch() and fetchAll() will then update all the variables that are bound to columns.
  • The binding needs to be renewed after each query call.

Prepared Statements

The use of parameterised prepared statements is preferable over queries.

  • Prepared statements are pared, analysed, compiled and optimised only once.
  • Prepared statements can be executed repeatedly with different arguments.
  • Arguments to prepared statements do not need to be quoted and biding of parameters to arguments will automatically prevent SQL injection.
  • PDO can emulate prepared statements for a DBMS state does not support them.
    • MySQL supports prepared statements, so PDO emulation should be turned off:

        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
      

Use of prepared statements requires the following three steps:

SQL Templates

An SQL template is an SQL query possibly containing either:

  • Named parameters of the form :name, where name is a PHP identifier.
  • Question marks ?, where the values will be substituted when the query is executed:

The PDO method prepare() turns an SQL template into a prepared statement:

  • On Success - A PDOSatement object is returned.
  • Of Failure - FALSE or an error will be returned.

Binding

bindValue()

We can bind the parameters of a PDOStatement object to a value using the bindValue() method:

  • Named parameters are bound by name.
  • Question mark parameters are bound by position (starting from 1).
  • The value is bound to the parameter at the time bindValue() is executed.

The datatype of the value can optionally be declared.

$stmt1->bindValue(':name', 'Ben', PDO::PARAM_STR);
$email = 'abc:example.com';
$stmt1->bindValue(':email', $email);
$stmt2->bindValue(1, 20, PDO::PARAM_INT);

bindParam()

We can bind the parameters of a PDOStatement object to a variable using the bindParam() method:

These are bound in a similar way to bindValue() except:

  • The variable is bound to the parameter as a reference.
$name = 'Ben';
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':email', $email);

Execution

Prepared statements are executed using the execute() method. Parameters must:

  • Previously have been bound using bindValue() or bindParam().
  • Be given as an array of values to execute()

    These values take precedence over previous values and are bound using bindValue().

When running execute():

  • On Success - The PDOStatement object stores a result set which can be processed in the same way as the result set returned by query().
$stmt1->execute();
$stmt1->execute(array(':name' => 'Eve', ':email' => $email));

Transactions

By default PDO runs in auto-commit mode. To execute a sequenc of SQL statements atomically then you must use the following commands to construct a transaction:

beginTransaction()
  • Turns off auto-commit mode. Changes to the database are not commited until commit() is called.
  • Returns TRUE on success or FALSE on failure.
  • Throws an exception if another transaction is already active.
commit()
  • Changes to the database are made permanent and auto-commit mode it turned back on.
  • Returns TRUE on success or FALSE on failure.
  • Throws an exception if no transaction is active.
rollBack()
  • Discards the changes to the database and re-enables auto-commit mode.
  • Returns TRUE on success or FALSE on failure.
  • Throws an exception if no transaction is active.

Here is an example for transferring money from one account to another:

$balance = array();

// this function stores a key-value pair to a global array called balance

function storeBalance($id, $b) {
	global $balance;
	$balance[$id] = $b;
}

$pdo = new PDO('mysql:host=...; dbname=...' , '...' , '...',
	array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
	PDO::ATTR_EMULATE_PREPARES => false));
try {
	// Details of the transaction: payer, payee, amount
	$payerId = 1; $payeeId = 2; $paymentAmount = 10.50;
	$pdo->beginTransaction();
	
	// Obtain payee's and payer's account balances and lock access to both records
	$sql1 = "select id, balace from accounts where id=? or id=? for update";
	$stmt = $pdo->prepare($spq1);
	$stmt->execute(array($payerId, $payeeId));
	
	// store the data retrieved from the database in the $balance array
	$smt->fetchAll(PDO::FETCH_FUNC, 'storeBalance');
	
	// Check whether there is enough money in the payer's account
	if ($balance[$payerId] < $paymentAmount) {
		echo "Insufficient funds in payer's account";
	} else {
		$sql = "UPDATE account SET balance = balance + ? WHERE id = ?";
		$stmt = $pdo->prepare($sql);
		
		// Increase balance of payee's account by payment ammount
		$stmt->execute(array($paymentAmmount, $payeeId));
		
		// Decrease balance of payer's account by payment ammount
		$stmt->execute(array(-$paymentAmount, $payerId));
	}
	
	// Commit the transaction (whether money was transferred or not)
	$pdo->commit();
} catch (PDOException $e) {
	echo "Error: ", $e->getMessage(), "<br>\n";
	
	// roll back the transaction
	$pdo->rollBack();
}

PHP Classes & Objects

COMP284 Lectures

Defining Classes

Classes are defined like so:

class identifier {
	property_definitions
	function_definitions
}

Function definition may include the definition of a constructor.

An object of a class is created using:

new identifier(arg1, arg2, ...)

The definition of a class typically looks like so:

class identifier {
	# Properties
	vis $attrib1
	...
	vis $attribN = value
	
	# Constructor
	function __construct(p1, ...) i{
		statements
	}
	# Methods
	vis function method1(p1, ...) {
		statements
	}
	vis function methodN(p1, ...) {
		statements
	}
}

vis is a declaration of visbility.

We can access the methods and objects of a class like so:

obj->attrib1 ...
obj->method1(a1) ...

$this

We can use the pseudo-variable $this as a reference to the current object like so:

class Rectangle {
	protected $height;
	protected $width;
	
	function __construct($height, $width) {
		$this->width = $width;
		$this->height = $height;
	}
}

Visibility

Properties and methods can have the following visibilities:

  • public - Accessible everywhere.
  • private - Accessible only within the same class.
  • protected - Accessible only within the class itself, by inheriting and parent classes.

Properties require a visibility declaration whereas, by default, methods are public.

Constants

Classes can have their own constants. By default they are declared public:

  • Class constants are allocated once per class and not for each class instance.
  • Class constants are accessed using the scope resolution operator :::
class MyClass {
	const SIZE = 10;
}
echo MyClass::SIZE;	# prints 10
$o = new MyClass();
echo $o::SIZE;	# prints 10

Destructors

A class can have a destructor method that is called as soon as there are no references to a particular object:

class Employee {
	static $totalNumber = 0;
	public $name;
	
	function __construct($name) {
		$this->name = $name;
		Employee::$totalNumber++
	}
	function __destruct() {
		Employee::$totalNumber--;
	}
}

$e1 = new Employee("Ada");
$e2 = new Employee("Ben");
echo Employee:$totalNumber	# prints 2
$e1 = null;
echo Employee::$totalNumber	# prints 1

Inheritance

Inheritance can be implemented like so:

class Rectangle {
	protected $height;
	protected $width;
	
	function __construct($height, $width) {
		$this->height = $height;
		$this->width = $width;
	}
	function area() {
		return $this->width * $this->height;
	}
}

class Square extends Rectangle {
	function __construct($size) {
		parent::__construct($size, $size);
	}
}

$rt = new Rectangle(3, 4);
echo "\$rt1 area = ", $rt1->area(), "\n";
$sq1 = new Square(5);
echo "\$sq1 area = ", $sq1->area(), "\n";
$rt1 area = 12
$sq1 area = 25
  • The constructor of the parent class is not automatically called. It must be called explicitly from the child class.
  • Inherited constants, properties and methods can be overridden by re-declaring them with the same name defined in the parent class.
  • The declaration final can be used to prevent a method from being overridden.
  • Using parent:: it is possible to access overridden methods or static properties of the parent class.
  • Using self:: it is possible to access static properties and methods of the current class.

Interfaces

Interfaces specify which methods a class must implement, without providing an implementation:

interface Shape {
	public function area();
}

class Rectangle implements Shape {
	...
}
  • All methods in an interface must be declared public.

Introspection Functions

Function Description
class_exists(class) Returns TRUE if a class class exists.
get_class(obj) Returns the name of the class to which an object belongs.
is_a(obj, class) Returns TRUE if obj is an instance of the class named class.
method_exists(obj, method) Returns TRUE if obj has a method named method.
property_exists(obj, property) Returns TRUE if obj has an property named property.
get_object_vars(object) Returns an array with the accessible non-static properties of object mapped to their values.
get_class_methods(class) Returns an array of method names for class.

property and class are read in as strings.

PHP Sessions

COMP284 Lectures

As no data about a client is remembered by default we can’t track a series of requests from coming from the same user. This can be problematic if we want to send several forms, such as on a shopping site.

Hidden Inputs

One way of solving this is by sending the data from the last form along with the next using a hidden input:

form1.php:

<form action="form2.php" method="post">
	<label>
		Item:
		<input type="text" name="item">
	</label>
</form>

form2.php:

<form action="process.php" method="post">
	<label>
		Adress
		<input type="text" name="address">
	</label>
	<input
		type="hidden"
		name="item"
		value="</php echo $_REQUEST['item'] ?>"
	/>
</form>

As we use $_REQUEST['item'] we can manipulate this value using process.php.

The user is able to modify these hidden fields if they want to act maliciously.

Sessions

This is a way of keeping track of a user’s session by using a session identifier which is:

  • Generated by the server, when the session starts.
  • Remembered by the browser.
  • Sent by the browser with every further HTTP request to that server.
  • Forgotten by the browser when the session ends, or the browser is closed.

In addition, the server can use session variables for storing information that relate to a session.

Session variables only store data temporarily. to preserve data between visits then you need to use a persistent cookie or a database.

Sessions vs. Cookies

Sessions:

  • ID and session data are stored on the web server.
  • Access and changes to session data are done in PHP via the $_SESSION array.
  • Expiration cannot be set; it always expires when the user’s close the browser or the session is ended by a script.
  • The client can’t manipulate the data.

Cookies:

  • ID and cookies data are stored by the web client on the user’s device.
  • Acess to cookie data is done in PHP via the $_COOKIE array.
  • Changes to cookie data are done in PHP via setcookie.
    • Expiration can be set via setcookie too.
  • Web client can be manipulated.

    This can be used as an attack vector.

Session Method

Creating and using sessions uses the following method:

  1. Start the session:
    • session_start()
    • session_id([id])
    • session_regenerate_id([delete_old])
  2. Maintain session data:
    • session_start()
    • The $_SESSION array.
    • isset($_SESSION[key])
  3. End a PHP session:
    • session_destroy()
    • $_SESSION = array();
    • session_unset()
    • setcookie(name, value, expires, path)

Starting a Session

session_start()

session_start()

Creates a session identifier when a session is created:

  • Sets up the $_SESSION array that stores session variables and session data.

The function must be executed before any other header calls or output is procured.

session_id()

session_id([id])

Get or set the session id for the current session:

  • The constant SID can also be used to retrieve the current name and session id as a string suitable for adding to URLs.

session_name()

session_name([name])

Returns the name of the current session:

  • If a name is given, the current session name will be replaces with the given one and the old name returned.

session_regenerate_id()

session_regenerate_id([delete_old])

Replaces the current session id with a new one:

  • By default keeps the current session information stored in $_SESSION.
  • If the optional boolean argument is true, then the current session information is deleted.

Regular use of this function alleviates the risk of a session being hijacked.

Maintaining Session Data

We can use the following methods:

  • session_start()
  • The $_SESSION array.
  • isset($_SESSION[key])

like so:

<?php
// counting the number of page requests in a session
// each web page contains the following PHP code
session_start();
if (!isset($_SESSION['requests']))
	$_SESSION['requests'] = 1;
else
	$_SESSION['requests']++;
echo "#Requests in this session so far: ", 
	$_SESSION['requests'], "<br>\n";
?>

Ending a Session

We can end a session like so:

<?
session_start();
session_unset();
if (session_id() != "" || isset($_COOKIE[session_name()]))
	// force the cookie to expire
	setcookie(session_name(), session_id(), time()-2592000, '/');
session_destroy();
?>

You should only end the session if the operation is successful. This saves losing all existing.

Close on Inactivity

The following code tracks whether a session is active and end the session if there has been no activity for more than 30 mins:

if (
	isset($_SESSION['LAST_ACTIVITY']) &&
	(time() - $_SESSION['LAST_ACTIVITY'] > 1800)
) {
	session_destroy();
	$_SESSION = array();
	if (session_id() != "" ||isset($_COOKIE[session_name()]))
		setcookie(session_name(), session_id(), time()-2592000, '/');
} else {
	$_SESSION['LAST_ACTIVITY'] = time();
}	

We can also use this same construct to make the session identifier change every 30 mins1:

if (!isset($_SESSION['CREATED'])) {
	$_SESSION['CREATED'] = time ();
} else if (time() - $_SESSION['CREATED'] > 1800) {
	// session started more than 30 minutes ago
	session_regenerate_id();
	$_SESSION['CREATED'] = time();
}

Session Examples

  • There is an improved example of the “hidden inputs” example from above using session variables [starting at slide 16]https://liverpool.instructure.com/courses/46944/files/6811254?module_item_id=1325181).

  • There is also a PRG (POST, redirect; GET) example with sessions starting at slide 19.

HTML Forms & PHP

COMP284 Lectures

Web Applications using PHP

flowchart LR
Browser -->|1. Post Action| ws[Web Server]
ws -->|2. Process| pp[PHP Processor]
pp <-->|3. Store/Retrieve| ds[Database Server]
pp -->|4. Merge with HTML| ws
ws -->|5. Return HTML| Browser

PHP & Forms

We can use something like the following to call a php script with the restult of a form:

<form action='process.php' method='post'>
	...
</form>

The following information is available to PHP scripts:

  • Information about the PHP environment.
  • Information about the web-server and client request.
  • Information store in files and databases.
  • Form Data
  • Cookie / Session Data
  • Date & Time (date formatting):

      date('H:i l, j F Y')	// 12:20 Thursday, 8 March 2022
      time() // Unix time in seconds
    

PHP Environment

phpinfo([part])

Displays information abou the PHP installation and EGPCS data (environment, GET, POST, cookie and server data).

  • The optional part argument can take the following options to only display certain information:
    • INFO_GENERAL - The configuration, php.ini location, build date and web-server.
    • INFO_CONFIGURATION - Local and master vales for PHP directives.
    • INFO_MODULES - Loaded modules.
    • INFO_VARIABLES - All EGPCS data.

Manipulating the PHP Configuration

The following function can be used to access and change the configuration of PHP from within the PHP script:

Function Description
ini_get_all() Returns all the registerd configuration options.
ini_get(option) Returns the value of the configuration option option.
ini_set(option, value) Sets the value of the given configuration value. The configuration option will keep this new value during the script’s execution and will be restored after.
ini_restore(option) Restores a given configuration option to its original value.

We can use this to show errors in the HTML output:

<html lang='en-GB'>
<head></head>
<body>
<? php
	ini_set('display_errors', 1);
	error_reporting(E_ALL | E_STRICT); // choose one
	echo '<p>The value of 1 divided by 0 is ' , 1/0 , '</p >';
?>
</body>
</html>

Server Variables

The superglobal $_SERVER array stores information about the web-server and the client request.

A full list of keys are available here: http://php.net/manual/en/reserved.variables.server.php.

Form Data

The form data is passes to a PHP script via three superglobal arrays:

Variable Description
$_POST Data from the POST client requests.
$_GET Data from the GET client requests.
$_REQUEST Combined data from POST and GAT client requests. Equivalent to cgi.FieldStorage() in Python CGI.

We can access data by the name:

$_REQUEST['username']

String Functions

The following functions could be useful when processing form data:

Function Description
strtolower(str) Returns a string will all alphabetic characters in str converted to lower-case.
substr(str, start [,length]) Returns the portion of the string str starting at position start and consisting of at most length characters. If start is negitive, the returned string will start at the start‘th character from the end of the string.
date(format, [,timestamp) Returns a string formatted according to the given format string format using the given timestamp or the current time if no timestamp is given.

HTML Form Example

There is a full example for generating and processing a HTML form using PHP starting at slide 14

The following form is used:



POST, Redirect, GET (PRG)

As we used a POST request, if a person refreshes the page, this can resend the request giving unwanted side effects.

This design pattern requires that we:

  • Redirect to a results page after a POST request.

There is an example of extending the original form with this functionality starting at slide 21

PHP Regular Expressions

COMP284 Lectures

PHP uses PCRE (Perl-compatible regular expressions). You can try out your expressions in a live environment at regex101 (ensure that PCRE2 is checked).

PHP RE Syntax

We can use the following syntax to define regular expressions in PHP:

'/a*bc/'

The expression is enclosed in two /.

Quantifiers

We can request a certain number of characters:

Quantifier Description
* Match 0 or more times.
+ Match 1 or more times.
? Match 1 or 0 times.
{n} Match exactly $n$ times.
{n,} Match at least $n$ times.
{n,m} Match between $n$ and $m$ times.

These quantifiers are greedy:

  • Match the longest leftmost sequence of characters possible.

We can match lazily by following a quantifier with a ? character:

'=/\*.*?\*/='

Any non-whitespace, non-backslash character can be a regex delimiter. = is used here for convenience.

this would match:

x = /* one */ y*z; /* three */

as opposed to the following using a greedy expression:

x = /* one */ y*z; /* three */

Capture Groups & Back-references

We can capture groups and use them with backreferences like so:

"=<(?<c1>\w+)>/*?</\g{c1}>="

This captures a group of w+ called c1 and uses it later using \g{c1}.

This would match the whole string:

"<li><b>item</b></li>"

Available syntax includes:

Expression Description
(regex) Creates a capturing sub-pattern and automatically names starting from 1.
(?<name>regex) Creates a named capturing sub-pattern.
(?:regex) Creates a non-capturing sub-pattern.
\N, \gN, \g{N} Back-reference to a capturing pattern called $N$, where $N$ is a natural number.
\g{name} Back-reference to a named capture group.

(?:regex) is used to enclose alternations without making another capture group:

"/(?:regex1|regex2)/"

Modifiers

Usually we might enclose our regular expression in / /. We can use the following modifiers to match in different ways like so:

"/hello/i"

This performs a case-insensitive match.

Modifier Description
i Perform case-insensitive match.
s Treat multiline string as a single line.
m Treat string as a set of multiple lines (multi-line mode).

You can combine these modifiers one after the other.

PHP Regex Functions

preg_match()

preg_match(rx, str [,&$matches [,flags [,offset]]])

Attempts to match a regular expression rx against the string str starting at offset:

  • Returns 1 is there is a match, 0 if not and False if there is an error.
  • $matches is an array containing all the matching groups where group/key 0 is the full matching string.
  • flags modify the behaviour of the function.

It can be useful to run this in the expression of an if statement so that your output will only run if the pattern matches.

preg_match_all()

preg_match_all(rx, str, [,&$matches [,flags [,offs]]])

Retrieves all matches of the regular expression rx against teh string str starting at offs:

  • Returns the number of matches and False in the case of an error.
  • $matches is a multi-dimensional array containing all matches indexed from 0; with each match in the same format at preg_match().
  • flags modify the behaviour of the function.

preg_replace()

preg_replace(rx, rpl, str [,lmt [, &$num]])

Returns the result of replacing matches of rx in str by rpl:

  • lmt specifies the maximum number of replacements.
  • On completion, $num contains the number of replacements performed.
  • You can use groups captured from str in rpl.

preg_replace_callback()

You can also use preg_replace_callback() with the result of a function:

$old = "105 degrees Fahrenheit is quite warm";

$new = preg_replace_callback(
	'/(\d+) degrees Fahrenheit/',
	function ($match) {
		return round(($match[1] - 32) * 5 / 9) . " degrees Celsius";
	},
	$old
);

echo $new;
41 degrees Celsius is quite warm

preg_split()

preg_split(rx, str [,lmt [,flags]])

Splits str by the regular expression rx and returns the result as an array:

  • lmt specifies the maximum number of split components.
  • flagsmodify the behaviour of the function.

Control Structures, Functions & Libraries

COMP284 Lectures

Conditional Statements

In addition to the standard curly brace notation we can also use the following notation:

if (condition):
	statement
endif

This must be ended with the statement endif.

It also supports conditional expressions:

condition ? if_true_expr : if_false_expr

Other conditional statements such as:

  • Switch-Case
  • If
  • While & Do-While
  • Break & Continue

are very similar to other languages.

Exceptions & Error Handling

PHP has several classes of error:

  • Exception
  • Error
  • Notice
  • Warning

We can throw exceptions with a throw statement:

throw new Exception(message)
  • message is a string.

Other user-level errors are generated like so:

trigger_error(message [, type])
  • message is a string.
  • type is an integer representing the error level.

We can use the same structures from Java to handle errors:

try { statements }
catch { Exception $e } { statements }
finally { statements }

We can create a useful error handler like so:

$x = 0;
try {
	$y = 1 % $x ;
} catch ( Throwable $e ) {
	echo " Caught : $e \ n " ;
	$y = 0;
} finally {
	echo " y = $y \ n " ;
}
Caught : DivisionByZeroError: Modulo by zero in try.php:3
Stack trace:
#0 {main}
y = 0

Functions

Functions are defined with the following syntax:

function identifier($param1, &$param2, ...) {
	statements
}

To change a variable outside the function then it must be preceded with an ampersand &.

In addition, parameters can have default values:

$param = const_expr

The return value stops execution of the function and returns the associated value:

  • Functions can have more than one return value.
  • The return values don’t have to have the same type.

Calling Functions

We can call functions in the normal way:

identifier(arg1, arg2, ...)
  • We can use a default value by leaving a black space between commas.
  • We can call a function before it is defined.

Type Checking in Functions

As there is no type checking, if we want an input variable to be a particular type, we need to check the type ourselves:

function bubble_sort($array) {
	if (!is_array($array))
		throw new Exception("Argument is not an array.");
	...
}

Functions & HTML

It is possible to include HTML markup in the body of a function:

<?php
	function print_form($fn) {
?>
<form>
	<?php echo $fn?>...
</form>
<?php
}
print_form("test");
?>

A call of the function will execute the PHP, insert the output into the HTML markup and print the markup.

Functions with a Variable Number of Aguments

We can write functions that can take an arbitrary number of arguments:

function sum() {
	if (func_num_args() < 1)
		return 0;
	$sum = 0;
	foreach (func_get_args() as $value)
		$sum += $value;
	return $sum;
}

We can use the following functions:

Function Description
func_num_args() Returns the number of arguments passed to a function.
func_get_arg(arg_num) Returns the specified argument or False on error.
func_get_args() Returns an array with copies of the arguments passed to a function.

Scope

PHP distinguishes the following categories of variables with respect to scope:

  • Local Variables - Only valid in the part of the code in which they are introduces.
  • Global Variables - Are valid outside of functions.
  • Superglobal Variables - Are built-in variables that are always available in all scopes.
  • Static Variables - Local variables within a function that retain their value between separate calls of the function

By default:

  • Variables in a function are local but not static.
  • Variables outside any function are global.

We can access and modify global variables like so:

$x = "Hello";
function fn() {
	global $x;
	echo "$x\n";
}

An unset operation removes a specific variable, but leaves other global variables with the same name unchanged.

We can declare a static variable like so:

static $count = 0;

Including & Requiring Files

  • include - This includes a file in the script but generates a warning if it doesn’t exist.
  • require - This includes a file in the script but generates an error if it doesn’t exist and execution stops.
include 'test.php';

The file we are including must be enclosed in <? php and ?>.

If we want to ensure a file is only included once (to avoid errors) we can use:

  • include_once
  • require_once

If no absolute path is specified PHP will search in the following order:

  1. Directories in the include_path.
  2. The scripts directory.
  3. The current working directory.

PHP - Arrays, Comparisons, Printing & NULL

COMP284 Lectures

Comparison Operators

Type juggling affects the way that comparisons work in PHP, consequently there are some additional competitors:

Expression Name Description
expr1 == expr2 Equal TRUE if expr1 is equal to expr2 after type juggling.
expr1 != expr2 Not Equal TRUE if expr1 is not equal to expr2 after type juggling.
expr1 <> expr2 Not Equal TRUE if expr1 is not equal to expr2 after type juggling.
expr1 === expr2 Identical TRUE if expr1 is equal to expr2 and they are the same type.
expr1 !== expr2 Identical TRUE if expr1 is not equal to expr2 or they are not the same type.

Comparing NAN and INF are also possible but may not behave as expected in PHP versions earlier than 5.3.

You can compare strings as strings using the following function:

Expression Name Description
strcmp(expr1, expr2) String Comparison Returns < 0 if expr1 is less than expr2,
> 0 if expr1 is greater than expr2,
0 of expr1 is equal to expr2.

You can convert strings to numbers and compare using the spaceship operator:

Expression Name Description
expr1 <=> expr2 Three-way Comparison Returns -1 if expr1 is less than expr2,
+1 if expr1 is greater than expr2,
0 of expr1 is equal to expr2.

NAN & INF Comparisons

PHP provides three functions to test whether a value is one of these values:

Expression Description
bool is_nan(<value>) Returns TRUE if the value is NAN.
bool is_infinite(<value>) Returns TRUE if the value is INF or -INF.
bool is_finite(<value>) Returns TRUE if the value is neither NAN nor INF or -INF.

Arrays

Creating Arrays

PHP only supports hash tables, hence they are just referred to as arrays. They are created like so:

array(key1 => value1, key2 => value2)
[key1 => value1, key2 => value2]
  • key - Is an integer or string.
  • value - Can be of any type, including arrays:

      $arr2 = array (200846369 = > array (
          "name" = > "Jan Olsen",
          "COMP201" = > 69,
          "COMP207" = > 52
          )
      );
    

The size of an array can be determined using the count function:

count(array[, mode])

using them on the above array would yield the following results:

print count($arr2);	// prints 1
print count($arr2, 1)	// prints 4

You can omit the keys when creating an array:

$arr3 = array("Peter", "Paul", "Mary");

This will automatically generate the keys as natural numbers (0, 1, …).

You can add a value to the end of an array using the following assingment:

$arr4[] = 51;	// 0 => 51
$arr4[] = 42;	// 1=> 42

Reading Arrays

All of the keys of an array can be fetched with the following function:

array_keys($array1)

this will return a natural number indexed array containing the keys of array1.

All of the values of an array can be fetched with the following function:

array_values($array1)

this will return a natural number indexed array containing the values stored in array1.

You can access an element of an array via its key:

$arr1 = array (1 => "Peter", 3 = > 2009, "a" => 101);
print "'a' = > " . $arr1 ["a"] . "\ n" ;
'a' => 101

Accessing an undefined key returns NULL.

You can use the following function to check if a key exists in an array:

array_key_exists("a", $arr1) // returns TRUE

foreach-loop

You can loop through all the mappings of an array using the following structure:

foreach (<array> as $value) {
	<statement>;
}

foreach (<array> as $key => $value) {
	<statement>;
}

Arrays are not sorted so the values are returned in insertion order.

In order to change the values of an array using a for each loop you need to use a reference (&):

foreach ($arr6 as $key => &$value) { // note the &
	$value .= " - modified";
}
  • This is required, otherwise a copy will be modified.
  • Unsetting the pointier is required to remove the structure from memory.
  • You can’t change the key, only the value.

Array Assignments

PHP uses copy-on-write for array assignments. This means that if you create a copy of an array:

$arr2 = $arr1;

they are treated as a reference to eachother (this saves the memory of writing it twice).

When one is changed:

$arr2[1] += 1000;

then the other copy is written to memory.

This means that $arr2 is no longer a pointer to $arr1 and is now its own array.

If you explicitly want a reference then you can do the following:

$arr2 = &$arr1;

This will create an alias for the same array.

Array Operators

PHP has no stack or queue datastructures. We can use the following functions with arrays to emulate these features:

Function Description
array_push(&$array, value1, value2, ...) Appends one, or more, elements at the end of an array. Returns the number of elements in the resulting array.
array_pop(&$array) Extracts the last element from an array and returns it.
array_shift(&$array) Extract the first element of an array and returns it.
array_unshift(&$array, value1, value2, ...) Inserts one or more elements at the start of an array variable. Returns the number of elements in the resulting array.

Printing

In PHP the default command for generating output is echo:

echo(arg1);
echo arg1, arg2, ...

No brackets are allowed if there is more than one argument.

This method is more efficient that printf so should be used when possible.

Additionally there are also the functions print and printf:

Function Description
print(arg) Takes one argument only and returns value 1. Brackets can be omitted.
printf(format, arg1, arg2, ...) Produces output according to format. Returns the length of the output string.
sprintf(format, arg1, arg2, ...) Returns a string produced according to the format.
vprintf(format array) Same as printf by accepts an array instead of comma separated values.
vsprintf(format, array) Same as sprintf and vprintf.

NULL

A variable can have the value and type of NULL in the following situations:

  • The variable has not yet been assigned a value.
  • The variable has been assigned the value NULL.
  • The variable has been unset.

You can use the following function to sets whether a variable is NULL:

Function Description
isset($variable) True if $variable exists and does not have value NULL.
is_null(expr) True if expr is identical to NULL.

Empty arrays are only loosely (==) equal to NULL but not identical (===).

Resources

A resource is a reference to an external file. We can use the following functions:

Function Description
fopen(filename, mode) Returns a file pointer for filename on success, false on error.
fclose(resource) Closes the resource. Returns true on success.
fgets(resource [, length]) Returns a line read from resource and returns false if there is no more data to read. length can be used to read the first $n$ characters, or until the end of the line.
fread(resource, length) Returns length charactesr read from resource.
fwrite(resource, string [, length]) Writes a string to a resource. If length is given, writing stops after length bytes, or the end of the string.
fprintf(resource, format, arg1, arg2, ...) Same as printf with output to resource.
vfprintf(resource, format, array) Same as vprintf with output to resource.

We can use the following modes:

Mode Operation Create Truncate
r Read File    
r+ Read/Write File    
w Write File Y Y
w+ Read/Write File Y Y
a Append File Y  
a+ Read/Append File Y  
x Write File Y  
x+ Read/Write File Y  

Here are some common file operations:

$handle = fopen('somefile.txt', 'r');
while ($line = fgets($handle)) {
	// processing each line
}
fclose($handle);
$handle = fopen('somefile.txt', 'w');
fwrite($handle, "Hello, World!".PHP_EOL);	// platform dependant newline
fclose($handle);

PHP Introduction

COMP284 Lectures

Using CGI is disadvantageous as it is difficult to add a small amount of dynamic content to a web page.

PHP is a scripting language that aims to make it easy to write server-side code.

PHP Processing

You install PHP as a web server plugin:

This avoids the need to execute an external program.

PHP code is embedded into HTML pages using tags. This makes it easy to turn static pages into dynamic ones.

The processing follows the following method:

  1. The web server receives a client request.
  2. The web server recognises that the client request is for an HTML document containing PHP code.
  3. The server executes the PHP, substitutes output into the HTML document; the resulting page is then sent to the client.

The client never sees the PHP code, only the HTML document that is produced.

PHP “Hello, world!”

You can write this like so:

<!DOCTYPE html>
<html lang="en-GB">
<head>
	<title>Hello, world!</title>
</head>
<body>
	<h1>Our First PHP Script</h1>
	<?php
		print("<p><b>Hello, world!</b></p>\n");
	?>
</body>
</html>
  • PHP code is enclosed between <?php and ?>.
  • The file name must have the extension .php.

There is also a command line program included in php.

This means that it can be used as a scripting language outside of a website.

You can run a php script using a she-bang #! at the start of the script, or by passing the php file as an argument.

PHP Scripts

  • They contain only statements and comments
    • No main or classes.
  • Statements end in a semi-colon ;.
  • One line comments start with // or #.
  • Multiline comments are enclosed in /* and */.

PHP Types

PHP has eight datatypes including:

Four primitive types:

  • bool
  • int
  • float
  • string

Two compound types:

  • array
  • object

Two special types:

  • resource
  • NULL

Integers and Floats

PHP has several pre-defined mathematical functions that you can look up.

PHP also provides pre-defined number constants:

  • M_PI - Pi
  • NAN - Not a number.
  • INF - Infinity

The last two can be returned from mathematical functions where appropriate.

Booleans

When converting to boolean, the following values are “falsy”:

Value Type
FALSE Boolean
0 Integer
0.0 Float
‘0’ String
’’ Empty String
{} An array with zero elements
NULL Null and other unset variables.
  SimpleXML objects created from empty tags.

All other values are considered “truthy”.

When converting boolean to string:

  • TRUE becomes “1”.
  • FALSE becomes “”.

Strings

  • Strings can be single or double quoted.
  • Strings can span several lines.
  • Concatenation is denoted with ..

    This is opposed to + like other languages.

You can use substitution in double quoted strings:

$title = "String Operators";
print "<title>$title</title >";

Which produces the following HTML:

<title>String Operators</title>
  • In single quoted strings only \ and ' are escaped.
  • In double quoted strings all common escape codes are accepted.

Variables

All PHP variables start with $, they can’t start with a number and are case sensitive:

  • Variables don’t have to be declared before they are used.

    You can use a variable with the default value before is it assigned.

  • Variables don’t have to be initialised before they are used.

    • Default - generally FALSE, empty, or NULL - values are chosen.

They can be assigned like so:

$student_id = 123457890;
$b = ($a = 0) + 1;

Constants

You can define global constants with the following function:

define(<name>, <expression>)

This can be used like so:

define("PI", 3.14159);

and you can access them like so:

print "Value if PI:" . PI . "\n";

You can’t use variable substitution with constants.

Values, Variables & Types

PHP provides several functions to find the type of an expression:

Function Description
string gettype(<expr>) Returns the type of expr as a string.
bool is_<type>(<expr>) Checks whether <expr> is of type <type>.
void var_dump(<expr>) Displays structured information about <expr> that include its type and value.

Type Juggling & Casting

PHP will automatically convert a value to the appropriate type as required by the operation applied to the value (type juggling).

We can also apply an identity function of the target type to force a type conversion:

\[\text{`12'} * 1.0 \rightarrow 12.0\]

PHP also support explicit type casting via (<type>):

$a = (bool) "foo"
print $a

would return:

TRUE

CGI Programming and HTML Forms

COMP284 Lectures

Web-Based Application Interfaces

Web-based applications are client-server applications where:

  1. The client software, consisting of a user interface and client-side logic of the application, run in a web browser.
  2. Static aspects of a user interface are realised using HTML.
  3. The client software incorporates user inputs into a HTTP request that it sends to a web server to retrieve information or to update parts of itself.
  4. The web server uses a program, the server software, to compute an HTTP response that it sends back the web browser.
flowchart LR
subgraph wb[Web Browser]
cs[Client Software]
end
wb -->|HTTP Request| ws[Web Server]
ws -->|HTTP Response| wb
ws <--> ss[Sever Software]

HTML

Elements

  • A HTML element is an individual component of a HTML document.
  • Most element consist of a start tag and a matching end tag with some content in-between.

The general form of a start tag is like so:

<tagName attrib1="value" attribN="valueN">

and an end tag looks like the following:

</tagName>

Void Elements

These are HTML elements that only have a starting tag such as:

  • area
  • base
  • br

Since they have no content, they cannot be nested.

The start tag of void elements can be made self-closing by ending the tag with /> instead of > like so:

<br/>

Documents

An HTML5 document begins with a DOCTYPE declaration and an html element like so:

<!DOCTYPE html>
<html>
</html>

It is recommended that the start tag specifies the language used in the document:

<html lang="en-GB">

Forms

Forms allow users to enter data which can be sent to a web server. It has several optional attributes, including:

Attribute Description
action URL to use for form submission.
method HTTP method to use for form submission (get or post).
enctype The encoding type to use for form submission.
novalidate Form is not validated during submission.

You would use these attributes like so:

<form action="https://sam.csc.liv.ac.uk/COMP/Calendar.pl" method="post" enctype="text/plain">
</form>

Input

The input element represents a field that allows the user to enter data of a certain type.

The input element is a void element.

The type attribute of an input element determines what type of data can be entered and in what form.

Value of Type Data Type Form Control
text Text with no line breaks Text field.
number Floating-point number. Text field or spinner.
password Password Text field with obscured input.
button   Button
submit Initiates form submission. Button
reset Resets the form. Button

You can use them like so:

<input type="text">
<input type="reset">

Common attributes of input elements include the following:

Attribute Description
id A unique id used to identify the element within the document.
name A unique name used by the form processor to access input.
autofocus Automatically focus on this form control when the page is loaded.
disabled Whether the form control is disabled.
required Whether the form control is required to have a non-empty value for form submission.

Labels

In order for a form to be readable, each form control should be accompanied by an indication of what it is. A label element is a caption the can be associated with a specific form control.

It can be used in the following ways:

<label for="s1">Surname:</label>
<input type="text" name="surname" id="s1">
<label>
	First names(s):
	<input type="text" name="first" id="f1">
</label>

Form Example

You can put this all together using the following HTML which would render like so:

<form action="process.py">
	<label for="s1">Surname:</label>
	<input type="text" name="surname" id="s1">
	<label>
		First Name:
		<input type="text" name="first" id="f1">
	</label>
	<label>
		Student ID:
		<input type="number name="studentid" id="sid" min="190000000" max="999999999">
	</label>
	<input type="submit">
</form> 


A string composed of name=value pairs will be sent to the action program.

HTML encoding is used on strings.

Select

A select element represents a drop-down menu with pre-defined options. They can be made with the following HTML and render like so:

<label for="m1">Select a module:</label>
<select name="module" id="m1">
	<option value="COMP201">COMP201: Software Engineering I</option>
	<option value="COMP207">COMP207: Database Development</option>
	<option value="COMP211">COMP211: Computer Networks</option>
</select>


  • By default, the first option is selected.
  • If the selection is not changed and the user activates the submit button then module=COMP201 is sent to the server.
  • If the default element has an empty value then the user is forced to make a choice.

Common Gateway Interface (CGI)

This is a standard method for web server to use an external application, a CGI program, to dynamically generate web pages.

  1. A web client generates an HTTP request and sends it to a web server.
  2. The web server selects a CGI program to handle the request, converts the HTTP request to a CGI request and executes the program.
    • The CGI program then processes the CGI request and the server passes the program’s response back to the client.

Common gateway interface illustration.1

GET vs POST

There are two main request methods used by HTML forms:

  • GET:
    • The browser appends the form data to the URI in the request:
      <scheme> "://" <server-name> ":" <server-port> <script-path> <extra-path> "?" <query-string>
    
    • They are limited to between 1KB and 8KB depending on the browser and server.
    • Requests remain in the browser history and can be bookmarked.
    • They should not be used for sensitive data such as passwords.
  • POST:
    • The browser appeds the form datat to the body of the request.
    • No limit on the length of the request.
    • They don’t remain in the browser history.
    • They are suitable for transfer of sensitive information.

Sever Interaction

The server can access this information in the following ways:

  • GET:
    • Form data is provided tot he CGI program via the QUERY_STRING environment variable.
  • POST:
    • Form data is provided to CGI programs via the standard input.

The following environment variables are also available to the CGI:

Variable Meaning
REQUEST_METHOD The request method that was used.
HTTP_USER_AGENT The browser issuing the request.
HTTP_REFERER The URL of the document that the browser points to before accessing the CGI program.
HTTP_ACCEPT A list of the MIME types that the browser can accept.
REMOTE_ADDR The remote IP address of the device from which the request came.

CGI Program in Python

We can use python to make a CGI program by using the following features:

  • environ dictionary of the os module to access the environment variables.
  • cgi module to process and decode form data.
  • print statements to produce HTML markup.

Accessing Environment Variables

We can access environment variables like so:

os.environ['REQUEST_METHOD']

This might return the string such as GET.

Accessing Form Data

To access form data we can use the cgi module like so:

  1. Create an instance of the FieldStorage class and assign it to a variable:

     variable = cgi.FieldStorage()
    

    This reads the form data from the standard input, or the environment variable QUERY_STRING.

  2. We can then use the following functions to get the data:

     variable['name'].value
     varaible.getvalue('name')
     variable.getfirst('name', default=None)
     variable.getlist('name')
    

CGI Wrapper Example

Consider that we want to develop a CGI program for a username generator with the following functionality:

  • Access is restricted to IP addresses starting with 128.253 (for the University of Liverpool).
  • The program point out a HTML document with an HTML form that allows a user to enter the data required fro our program.
    • The drop-down menu should cover the previous nine years plus the current year.
  • On submission of the completed form, the program:
    • Generates a user name based on the data that was entered into the form.
    • Prints out an HTML document with that username.

HTML Wrapper

This code define functions that can print outh the initial and final part for some HTML markup:

# htmlUH.py

def startHTML(title):
	print('''\
Content-type: text/html

<!DOCTYPE html>
<html lang='en-GB'>
	<head>
		<meta charset='utf-8'>
		<link rel='stylesheet' type='text/css' href='form.css'>
		<title>''' + title + '''</title>
	</head>
	<body>''')
	
def endHTML():
	print('''
	</body>
</html>''')

HTML Form

We can then use the following python to make the form:

def printForm():
	print('''\
<form action='generate.py' method='post'>
	<label>
		Enter your full name:
		<input type='text' name='fullname'>
	</label>
	<label>
		Select your year of registration:
		<select name='year' required>
			<option value=''>
				----
			</option>''')
	now = datetime.datetime.now()
	for year in range(now.year - 9, now.year + 1):
		print('<option>',year, '</option>')
	print('''\
		</select>
	</label>
	<input type='submit' name='submit' value='Generate'>
</form>''')

Generating Username

We can use the following function to generate a username:

def genUsername(name, year):
	# first letter of given name/names
	return ("sg" + name.split()[0][0].lower()
	# first three letter of surname
	+ name.split()[-1][:3].lower()
	# last two digits of year
	+ str(year)[2:4])

Wrapper Script

#!/usr/bin/python3
# generate.py

import os, sys, codecs, datetime, locale
from htmlUH import start_html, end_html

start_html("Generate Username")
if (os.environ["REMOTE_ADDR"][0:7] != "138.253"):
	print('<div><b>Sorry, please come back when you are on a uni computer</b></div>')
else:
	inputs = cgi.FeildStorage()
	if inputs.getvalue('submit'j):
		# form has been completed and submitted
		name = inputs['fullname'].value
		year = inputs['year'].value
		username = genUsername(name, year)
		print('<div>The username for ' + name + ' registerd in ' + year + ' is ' + username + '</div>')
	else:
		# show user the form
		printForm()
end_html()
  1. Common gateway interface illustration - https://www.oreilly.com/library/view/cgi-programming-on/9781565921689/04_chapter-01.html 

Introduction to Scripting Languages

COMP284 Lectures

Scripting Languages

Scripts are user-readable and user-modifiable programs that perform simpler operations and control the operation of other programs.

They have the following properties:

  • Program code is present at run time and the starting point of execution:
    • Compilation is not needed.
    • Compilation to intermediary languages may be performed behind the scenes as an optimisation.
  • Presences of a suitable runtime environment is required for thee execution so scripts:
    • Includes one of:
      • Interpreter
      • Just-In-Time Compiler
      • Byte-code Compiler

    and a virtual machine.

  • Execution of scripts is typically slower than the execution of code that has been fully pre-compiled.
  • Rich and easy to use interface to the underlying operating system in order to run other programs and communicate with them.
    • Rich I/O including:
      • Pipes
      • Network Sockets
      • File I/O
  • Easy integration with larger systems:
    • Often used to glue other systems together.
    • Can be embedded into other applications.

Language Constructs

  • Variables, functions, and methods typically do not require type declarations. Automatic conversion between types:
    • Strings and numbers.
  • Lots of pre-defined functions and libraries.
    • Lots of pre-defined functions for the specific purpose the language was designed for.
  • Ability to generate, load, and interpret source code at run time through an eval function.
    • This can lead to self modifying and running code like the following:

        var x = 2;
        var y = 6;
        var str = " if ( x > 0) { z = y / x } else { z = -1 }";
        console . log ( ' z is ', eval ( str )); // Output : z is 3
        x = 0;
        console . log ( ' z is ', eval ( str )); // Output : z is -1
      

Language Evolution

The evolution of a scripting language typically starts with a limited set of languages constructs for a specific purpose:

  • PHP started as a set of functions for tracking web visits.

The language then accumulates more and more language constructs as it is used for a wider range of purposes:

  • These additional language constructs may or may not fit well together with the original core and may duplicate existing language constructs.
  • During this evolution of the language, backward compatibility may or may not be preserved.

Language design of scripting languages is often sub-optimal.