25/02/2015
1
CSCI110 brought you
PHP
and
More PHP
1
Now it’s time for
Still More PHP
2
What more could there be?
• Some cleanups
• Worthwhile additions
– ADOdb
• Automation of data persistence
– Smarty
• Separate display generation (view) from logic code and data
• A whole new “ball game”
– Zend framework
• A new model
• Automation of development
3
Some cleanups …
• (I’m not yet in the habit of using these – so don’t expect to
see them in my examples!)
• “Never use $_GET again!”
–Instead, use PHP’s filter functions
– Why?
• You are less likely to miss out on sanitising your data
4
Filter functions
• You should use them (even if I don’t)
• Example “filter_input”
– Use to access $_GET, or $_POST (or $_COOKIE or
$_SERVER)
– Request named data item
– Provide a filter function (from standard set)
• E.g FILTER_SANITIZE_EMAIL,
FILTER_SANITIZE_NUMBER_INT, …
5
Filtering input
• Lerdorf’s name and age again …
$yourname = filter_input(INPUT_GET, ‘name’,
FILTER_SANITIZE_SPECIAL_CHARS);
$yourage = filter_input(INPUT_GET, ‘age’,
FILTER_SANITIZE_NUMBER_INT);
// Get NULL if variable (‘age’, ‘name’) not set
// Get FALSE if data failed by filter
6
25/02/2015
2
Other tidying up
• Namespaces – yes supported now
• “traits”
– As in Java, you can inherit from one class but you
can “implement many interfaces” (or in PHP “use
many traits”)
• …
7
Xdebug & Netbeans
• I think that I’ve correctly configured the lab so that
you can use xdebug (from within Netbeans)
– Open PHP file that needs debugging (don’t they all?)
– Set some breakpoints
– Select project, right click and pick debug
8
Caveat
• Remember Drupal from CSCI110?
• Most of the examples that will be used in this
“Still More PHP” section are relatively simple and
could be implemented using the Drupal content
management system and its various extension
modules.
– Examples are kept simple so that you can learn about
Smarty or Zend rather than some complex application
domain.
9
Use Drupal when you can
• In practice, you should always consider Drupal
before you commit yourself to developing new
code for an application
– Your development time will be shorter
– Your maintenance burden will be smaller
– OK, run‐time performance might be poorer with a Drupal‐based solution;
you do have to consider that too.
• In some cases, Drupal project performance is pretty woeful!
• Not everything can be done with Drupal or
similar content management systems, but if they
will suffice – use them!
10
A good programmer …
• Remember Larry Wall’s dictum
– Characteristics of a programmer
• Impatience
• Laziness
• Hubris
• You goal should be to work less while
achieving more in less time
– Achieved in part through use of automation tools
11
What do all web apps do?
• All (well, almost all) web apps use a relational
database.
• What does that mean for you?
– Lots of messy SQL code
– Lots of code for copying data between your
program’s structs/objects and SQL‐related
structures like “prepared statements” and “result
set rows”
– And, in conventional PHP, re‐doing it all if you
need to work with a different database.
12
25/02/2015
3
Can we fix it?
• Database independent code
– Well that shouldn’t be too hard to fix
• Think of Java’s JDBC – same code, just different drivers
loaded
– Try fixing this first
• Messy repetitive boring code
– Sounds like work for an automatic code generator.
• Don’t want to have database specific code generators,
so deal with this second
13
Can we fix it?
Yes we can
• ADOdb
– ADOdb started as a database‐neutral, procedural
interface – something like ODBC, JDBC, or Perl’s
DBI – which then grew into an automated “Object
Relational Mapping” (ORM) system
There are several alternative PHP libraries that provide for database neutrality, and
lots of other PHP‐based ORM systems (we will be working mostly with the ORM created
for the Zend framework). ADOdb is just an example. If there is another one that you like,
or one that you learnt because your boss liked it, then use it.
http://adodb.sourceforge.net/
14
Database specific interfaces
• Database systems such as Oracle, DB2, SQLServer
etc were initially used from (C) programs through
special libraries – e.g. the Oracle Call level
Interface.
– These libraries defined a set of C functions and structs
(along with COBOL equivalents etc) that could be
added to a program so that it could work with a
database.
• Of course, each database system had a different
library with different function names and
different types of struct
– Your code was very much database specific
15
Database specific interfaces
• The libraries differed, but they all provided much
the same functionality
– Connect to database
– Supply user credentials and specify schema required
– Submit SQL queries to be run by database
– Retrieve result sets, process row by row extracting
data.
• Couldn’t a higher level abstraction capture all
this?
16
Database neutral interfaces
Embedded SQL
• First attempt at a higher level abstraction (late
1980s) was “Embedded SQL”
– Define a standard set of macros for those standard
database operations
– Each database vendor provides a set of macro expansion
templates that map onto their call level interface
• Works, but really messy and ugly
17
EXEC SQL BEGIN DECLARE SECTION;
varchar dbuser[10];
varchar dbpassword[15];
EXEC SQL END DECLARE SECTION;
strlcpy((char*)dbuser.arr, name, 9);
dbuser.len = strlen((char*)dbuser.arr);
strlcpy((char*)dbpassword.arr, password, 16);
dbpassword.len = strlen((char*)dbpassword.arr);
EXEC SQL CONNECT :dbuser IDENTIFIED BY :dbpassword;
18
25/02/2015
4
Database neutral interfaces
ODBC
• Second attempt – Open Database Connectivity
– “Open Group” (an industrial collaborative) defined a
database‐neutral, procedural interface;
DB vendors were to provide function libraries that
would have functions having the neutral interface that
invoked work via the database specific call level
interface
• Disadvantage – each database vendor very proud of the
proprietary features and optimizations present in their own
call level interface; these features lost when using ODBC
– Initially, only Microsoft bothered with ODBC
• Provided an implementation shortly after standard
published in ~1992
19
ODBC copies
• ODBC model copied in other implementations
in the 1990s
– DBI/DBD – Perl
– JDBC ‐ Java
• (The ODBC variants are very similar, differing primarily in the
names that they give to various parts of the system – e.g.
“database handle” or “connection”)
20
But PHP
• Traditionally, PHP programs used the database
call level interfaces
– Remember, the PHP interpreter is in C,
– It’s relatively easy to define a “PHP function” which is
simply a direct call to a C function in a linked library.
• Why make the code database specific?
– Because
• It allows an application to exploit those special features and
optimizations that the database vendors extol
• And, anyway, how often do you change your database? !
– In house developments will always use same database.
21
PHP extensions
Database neutral interfaces
• Some PHP developers did want database
neutral interfaces
– Developing an application, e.g. a bulletin board
system, that was intended to be configurable so
that it would work with whatever database was
available at site where installed
– Contract workers who develop many small
applications and didn’t want to have to remember
the many different call level interfaces
22
PHP variants on ODBC theme
• Several such libraries created
– ADOdb is just one
• Illustrate here with a simple web‐application
– Web application – select a toy for boy/girl in particular
age group
– Databases (Oracle and MySQL versions) have a table
with details of toys
• Illustrate first the database neutral bit – then move
on to automation through Object Relational Mapping
23
ADOdb
• A generic database interface (equivalent to JDBC,
ODBC, Perl’s DBI, …)
• Example
Static HTML form Script generated response
24
25/02/2015
5
Data table
• Same table defined in MySQL and Oracle
– MySQL version of definition:
CREATE TABLE `mark`.`XmasStockingItems` (
`itemid` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NOT NULL ,
`price` DECIMAL(8,2) NOT NULL ,
`agegroup` ENUM('Infant', 'Toddler', 'PreSchool',
'Primary', 'Secondary') NOT NULL ,
`gender` ENUM('Boy', 'Girl', 'Either') NOT NULL ,
PRIMARY KEY (`itemid`) )
ENGINE = MyISAM
DEFAULT CHARACTER SET = latin1;
25
Oracle table
CREATE TABLE XmasStockingItems (
itemid INT PRIMARY KEY ,
name VARCHAR(90) NOT NULL ,
price DECIMAL(8,2) NOT NULL ,
agegroup varchar(12) constraint ageconstrain
check (agegroup in ('Infant', 'Toddler', 'PreSchool', 'Primary', 'Secondary')),
gender varchar(8) constraint genderconstrain
check (gender in('Boy', 'Girl', 'Either'))
);
create sequence XmasSeq increment by 1 start with 1;
insert into XmasStockingItems values ( XmasSeq.NEXTVAL,
'Baby Einstein Take Along Tunes', 9.51, 'Infant', 'Either‘ );
insert into XmasStockingItems values ( XmasSeq.NEXTVAL,
'Yookidoo Flow N Fill Spout', 14.51, 'Infant', 'Either');
I made the prices in the two tables slightly different so that I could see from glance at results which table was being used
26
27
Database specific code: MySQL
Gift selection
A selection of suitable gifts
Gift | Price |
HEAD;
if ($gender == "Either") {
$stmt = $mysqli->prepare(
"select name,price from XmasStockingItems where agegroup=?");
$stmt->bind_param("s", $agegroup);
} else {
$stmt = $mysqli->prepare(
"select name,price from XmasStockingItems where agegroup=? and gender=?");
$stmt->bind_param("ss", $agegroup, $gender);
}
The usual – a mingling of
presentation and code;
will be resolved later
via Smarty
30
25/02/2015
6
Database specific code: MySQL
$stmt->execute();
$stmt->bind_result($name, $price);
while ($stmt->fetch()) {
echo "$name | \$$price |
";
}
$mysqli->close();
echo <<