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

Post on 23-Jan-2016

222 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

CO3041

Databasesand the Web

Week 8Dr 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

In-class test 1

Good results

Tough questions

3CO3041 Databases and the Web lecture 8

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

CO3041 Databases and the Web lecture 8

4

4

2

0

5

From last time

Date query efficiency

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…

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)";

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!)

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}

10

Regular Expressions

Perl-compatiblesyntax

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.

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?

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”

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.

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.

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’.”

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"

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)

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 ...

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_]

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)

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)/

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 “.”

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

27

Complex validation

PHP andRegular Expressions

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()

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.

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.

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…

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

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;?>

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>';?>

top related