1 co3041 databases and the web week 8 dr james denholm-price

32
1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

Post on 23-Jan-2016

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

1

CO3041

Databasesand the Web

Week 8Dr James Denholm-Price

Page 2: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

2

Outline/Schedule

• Today (lecture 8/week 9)– In-class test 1: tough questions– Dates (from last time)– Perl-compatible regular expressions

• Next week (lecture 9/week 10)– Discussing a set of “requirements” for the Group

Project that will form the marking scheme• c.f. last year’s.

– Edit/Delete

Page 3: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

In-class test 1

Good results

Tough questions

3CO3041 Databases and the Web lecture 8

Page 4: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

In-class test 1 – Good results: m=54%

CO3041 Databases and the Web lecture 8

4

4

2

0

Page 5: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

5

From last time

Date query efficiency

Page 6: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

6

Dates• MySQL default date format is ‘YYYY-MM-DD HH:MM:SS’

– Other formats are accepted…• SQL queries can be formed comparing date/times, e.g.

– SELECT * FROM tableName WHERE dateField > '2004-03-11 14:30:00'

• Output from MySQL queries can be manipulated with PHP’s date functions but PHP is best suited to comparing numbers using “>”, “<” and “==”– The most common number format for dates is a Unix timestamp which is a

32bit (signed) integer holding the number of seconds since 1st January 1970.

– Right about .. Now!• MySQL: NOW() in string format, UNIX_TIMESTAMP() as a number• PHP: time() in Unix timestamp format, date() in string format

– In PHP strtotime($row['dateField']); converts a MySQL DATETIME string to a Unix epoch number

• Also good for doing things like strtotime('+7 days', time() ) to calculate the date & time 7 days hence…

Page 7: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

7

Working in MySQL with PHP

• MySQL functions– UNIX_TIMESTAMP converts DATETIME into these numbers– FROM_UNIXTIME converts the number back to a DATETIME string

format

Q Easy to convert to/from date strings and timestamps…These two queries are equivalent, but which is the most efficient?1.$sql = "SELECT dateField FROM tableName WHERE UNIX_TIMESTAMP(dateField) > $PHPdateTime";or

2.$sql = "SELECT dateField FROM tableName WHERE dateField > FROM_UNIXTIME($PHPdateTime)";

Page 8: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

8

Working in MySQL• MySQL functions

– UNIX_TIMESTAMP converts DATETIME into these numbers– FROM_UNIXTIME converts the number back to a DATETIME string

formatQ: Easy to convert to/from date strings and timestamps…

These two queries are equivalent, but which is the more efficient?1. $sql = "SELECT dateField FROM tableName WHERE

UNIX_TIMESTAMP(dateField) > $PHPdateTime";or

2. sql = "SELECT dateField FROM tableName WHERE dateField > FROM_UNIXTIME($PHPdateTime)";

A: One applies a function to your database (e.g. 500000 rows!) the other applies a function to the comparison element … which is one function call irrespective of the number of rows! (demo – please don’t try this too often!)

Page 9: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

9

Manipulating dates in PHP• date(string format, [integer timestamp])

– optional timestamp defaults to ‘now’– format uses letters to represent a lot of date/time elements– E.g. to get back to MySQL’s “YYYY-MM-DD HH:MM:SS” use date('Y-m-d

H:i:s')

– To put keyword characters into the date string they must be escaped.– E.g. date('D\&\n\b\s\p;d-M-y\&\n\b\s\p;\a\t\&\n\b\s\

p;g.ia',$row->startTime)• D = Mon, Tue, Wed, …• d = 01, …, {28,29,30,31}• M = Jan, Feb, Mar, …• y = 04 for 2004• g = 1…12 hours, i = 01 … 60 minutes, a = {am,pm}

Page 10: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

10

Regular Expressions

Perl-compatiblesyntax

Page 11: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

11

Regular Expressions• Rules for matching string patterns.• PHP’s REs (regexps) are strings like '/hello/'

– This is a ‘literal character’ RE that matches the word “hello” at any point in a string.

– E.g. In 'Fred said “hello”!' (url)– There are a number of special characters that mean something in a

regexp and otherwise must be escaped with a backslash “\”. These are:

^ $ . * + ? = ! : | \ / ( ) [ ] { }– These form the basis of complex regexps that match flexible patterns

rather than fixed strings.• If all you want is to match a fixed string the manual recommends using strpos() or strstr()

– In PHP you’ll have to escape quotes too.

Page 12: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

12

Regular Expressions: Test

$string="Hello World";– preg_match('/world/', $string);

• TRUE/FALSE? – preg_match('/o W/', $string);

• TRUE/FALSE?– preg_match('/oW/', $string);

• TRUE/FALSE? – preg_match('/o/', $string);

• TRUE/FALSE?

Page 13: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

13

Regular Expressions: Test

$string="Hello World.";– preg_match('/world/', $string);

• Doesn’t match case (“W” not “w”)– preg_match('/o W/', $string);

• Matches the $matches array is ['o W']– preg_match('/oW/', $string);

• Doesn’t match (no space)– preg_match('/o/', $string);

• Matches just the “o” in “Hello”

Page 14: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

14

RE: Escaped special characters

$string="Hello+world.";– preg_match('/o+w/', $string);

• Doesn’t match case as “+” is a special character(meta-character.)

– preg_match('/o\+w/', $string);• Matches as “\+” is escaped.

Page 15: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

15

RE: Anchors ‘^’ and ‘$’

$string="Hello World";– preg_match('/^Hello/', $string);

• Matches “^” means beginning of string.– preg_match('/^World/', $string);

• No match.– preg_match('/World$/', $string);

• Matches “$” means end of string.– preg_match('/^World$/', $string);

• No match – “^” anchors to the start of the string and “$” to the end.

Page 16: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

16

RE: Character classes ‘[]’

$string="bat cat rat";– preg_match('/cat/', $string);

• Matches “cat”.– preg_match('/[bcr]at/', $string);

• Matches “bat” first but would also match “bat”, “cat” and “rat”. preg_match_all() would match them all.

– preg_match('/[cat]/', $string);• Stops at the first match it finds which is the “a” in “bat”

– The square brackets mean “any character in the class” i.e. in this case “any one of ‘c’, ‘a’ or ‘t’ not ‘c’, ‘a’ and ‘t’.”

Page 17: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

17

RE: Negating classes ‘[^…]’

$string="bat cat rat";– Starting a character class with a caret “^” negates the

class, i.e. it (the class) matches anything but its contents.– preg_match('/[^br]at/', $string);

• Matches just “cat” because the class means “anything but ‘b’ or ‘r’.” (url)

– However a caret inside a class becomes a member of that class so:

– preg_match('/[b^r]at/', $string);• Matches “bat” first (“rat” second) and would also match "^at"

Page 18: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

18

RE: Matching case

$string="yes Yes yEs yeS YEs YeS";– preg_match('/[Yy][Ee][Ss]/', $string);• Matches any combination of upper/lower “yes”

– Much easier to choose a case-insensitive match with a modifier at the end of the RE:

– preg_match('/yes/i', $string);

Q: Does this match?– preg_match('/YES/i', $string);

A: Yes! It’s a case-insensitive match so even though “YES” isn’t in $string it still matches the first “yes” (url)

Page 19: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

19

RE: Character ranges

$string="yes1 Yes2 yEs3 yeS4 YEs5 YeS6";– preg_match('/yes[1-6]/i',$string);

• Matches “yes1” at first (url).• “[1-6]” does not match “1”, “-”, “6” individually, it matches

the range of ASCII characters from “1” to “6”– preg_match_all('/yes[1-6]/i',

$string);• Matches all of the combinations (url).

Q: Does preg_match('/[0-7]/i','007'); return TRUE or FALSE?

A: TRUE. The character range [0-7] matches any 1 character ...

Page 20: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

20

RE: Shorthand classes

• Perl REs define shorthand classes:– \d digits, the same as [0-9]– \s spaces, including spaces, tabs…– \w ‘word’ (alphanumeric) [a-zA-Z0-9_]– . matches anything except “\n”

• Capital letters negate the class– \D [^0-9]– \S [^\s]– \W [^a-zA-Z0-9_]

Page 21: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

21

RE: Alternatives “|”

$string="yes1 Yes2 yEs3 yeS4 YEs5 YeS6";– preg_match('/yes4|yes3/i',$string);

• It’s case-insensitive and the “|” means ‘or’• preg_match matches & returns the first match in the

string, which is “yEs3”.• preg_match_all matches & returns all the matches

which are “yEs3” and “yeS4”.

Q: So what regexp would match either ‘Brosnan’ or ‘Connery’?

A: /Brosnan|Connery/ (url)

Page 22: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

22

RE: Grouping “(…)”

$string="KT1 2EE";– preg_match('/(...)\s(...)/',$string);

• Remember “.” matches any character (including a space)• The brackets group the character matches into

subexpressions• preg_match returns these in the $matches array as

elements [1] and [2] (url)

$string="02085478870";Q: how can I extract the codes from the number

‘xxxyyyyzzzz’ with a regexp?A: /(\d\d\d)(\d\d\d\d)(\d\d\d\d)/

Page 23: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

23

RE: Repeating “?” “*” “+” “{m,n}”

? “0 or 1” * “any number from 0 up” + “at least 1” {n} “exactly n” {m,n} “between m and n”$string="KT1 2EE";

– preg_match('/.{3}\s.{3}/',$string);• Matches postcode but also rubbish like “!!! !!!”

Q: How do we restrict “.” to alphanumeric?A: Use “\w” instead of “.”

Page 24: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

26

Quick exercise: RE for last namesform.html<form method="post" action="process.php">

<label for="fn"> First name> <input type="text" name="firstname" id="fn" /></label>

<label for="fn"> Last name <input type="text" name="lastname" id="ln" /></label>

</form>

process.php<?php$fn_OK = preg_match( '/^[A-Za-z]+$/', $_POST['firstname']);$ln_OK = preg_match( '/ /', $_POST['lastname']);if($fn_OK && $ln_OK) { $sql = "INSERT INTO name VALUES('{$_POST['firstname']}', '{$_POST['lastname']}'"; if(!mysql_query($sql)) die('<h1>Error:</h1>' . mysql_error()); else echo '<h1>OK!</h1>;?>

url url src

Page 25: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

27

Complex validation

PHP andRegular Expressions

Page 26: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

28

Quick intro to PHP RE functions• PHP includes a “PCRE” library

– Perl-Compatible Regular Expressions … next slide … + supports Unix standard “Posix” RE’s• PCRE is a superset of Posix

– the manual says they’re faster so use them for preference!– PCRE are very similar to Perl (& JavaScript) REs– Posix RE functions (briefly) [look them up online]– bool ereg ( string pattern, string string [, array regs])

• eregi () case-insensitive version– string ereg_replace ( string pattern, string replacement,

string string)• eregi_replace() case-insensitive version

– array split ( string pattern, string string [, int limit])• spliti()

Page 27: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

29

Main PHP PCRE functions

–int preg_match (string pattern, string subject[, array matches [, int flags

[, int offset]]])

• The basic pattern-matching function. Returns:– ‘0’ for no match (0==FALSE)– ‘1’ for a match (stops at the first match) (1==TRUE)– ‘FALSE’ for an error. (0!==FALSE)

• Returns the matching strings in the array matches:– matches[0] == full pattern match; matches[1] sub-pattern 1 etc.

Page 28: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

30

Main PHP PCRE functions

–int preg_match_all (string pattern, string subject,array matches[, int flags [, int offset]]

)• Unlike preg_match() this doesn’t stop at the first match.• Returns a count of all matches. (and ‘FALSE’ for error.)• Returns the matching strings in the array matches:

– matches[0] is an array of the full pattern matches– matches[1] an array of sub-pattern 1 matches … etc.

Page 29: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

31

Main PHP PCRE functions– mixed preg_replace ( mixed pattern,

mixed replacement, mixed subject

[, int limit] )• Search and replace by RE.• pattern is the RE.• replacement may reference the RE sub-patterns as $n or \\n• limit limits :-) the number of replacements.• Very useful for removing invalid characters.

– array preg_split ( string pattern, string subject [, int limit [, int flags]]

)• String splitting by RE.• Returns an array of string fragments

– optionally up to limit…

Page 30: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

32

PHP RE’s

• PHP patterns are strings, usually delimited by pairs of forward slashes– E.g. $pattern = "/world/";– May be delimited by other pairs of characters.– No case-insensitive PCRE functions -- just add an “i” after the end

pattern delimiter. $pattern="/world/i";• Complex RE’s may be copied from regexlib.com

– E.g. one of the simpler email address matching RE’s is ^\w+[\w-\.]*\@\w+((-\w+)|(\w*))\.[a-z]{2,3}$

• You can test RE’s here in JavaScript:– staffnet/~ku13043/WebDB/ex/week05/regexp_test.html

• Or here in PHP:– staffnet/~ku13043/WebDB/ex/week05/RE_test_post.php

Page 31: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

33

Form entry demo with REs<?php //Submitted the form? if (isset($_POST['Submit']) && $_POST['Submit']=='Submit…') {

$formSubmitted=1;//Valid? Both fields are required!//And should be text only

//Valid? Both fields are required!if ( preg_match('/^\w+\-?\w+$/',

$_POST['firstname']) && preg_match('/^\w+\-?\w+$/',

$_POST['lastname']) ) $formValid=1;else $formValid=0;

else $formValid=0; } else $formSubmitted=0;?>

Page 32: 1 CO3041 Databases and the Web Week 8 Dr James Denholm-Price

CO3041 Databases and the Web lecture 8

34

Form entry demo with REs<label for="firstname">First name:</label><input type="text" maxlength="30" name="firstname" <?php if ($formSubmitted && !$formValid) echo 'value="' . $_POST['firstname'] . '"'; ?>/><?php if ($formSubmitted && !$formValid && !preg_match('/^\w+\-?\w+$/', $_POST['firstname']) )

echo '<span class="error">Please enter your ' . 'first name using only letters!</span>';?>