mysql_free_result result_id; A class- based int erface can carry encapsulat ion furt her and short en t he script even m ore by
elim inat ing t he need t o connect explicit ly, t o check for errors, or t o close t he result set . All of t hat can be handled aut om at ically:
include Cookbook_DB_Access.php; conn = new Cookbook_DB_Access;
query = UPDATE profile SET cats=cats+1 WHERE name = Fred; conn-issue_query query;
print conn-num_rows . rows were updated\n; query = SELECT id, name, cats FROM profile;
conn-issue_query query; while row = conn-fetch_row
print id: row[0], name: row[1], cats: row[2]\n;
A class int erface can m ake MySQL easier t o use by reducing t he am ount of code you need t o writ e when creat ing new script s, but it has ot her benefit s as well. For exam ple, it can also
serve as a recipe t ranslat ion aid. Suppose a program in a lat er chapt er is shown in Perl, but youd rat her use in it PHP and t here is no PHP version on t he Cookbook web sit e. Perl DBI is
obj ect orient ed, so youll likely find it easier t o t ranslat e a Perl script int o a PHP script t hat is obj ect orient ed, rat her t han int o one t hat is funct ion based.
2.10.4 Class Overview
The class int erface im plem ent at ion uses t he PHP recipes and t echniques developed earlier in t his chapt er, so you should fam iliarize yourself wit h t hose. For exam ple, t he class int erface
needs t o know how t o m ake connect ions t o t he server and process queries, and well use include library files t o encapsulat e t he int erface so t hat it can be used easily from m ult iple
PHP script s. The int erface shown here works only wit h PHP 4. This is som et hing t hat is not t rue of PHPs
nat ive MySQL rout ines, which work bot h wit h PHP 3 and PHP 4. The rest rict ion is necessit at ed by t he use of a few const ruct s t hat are not available or do not work properly in PHP 3.
Specifically, t he int erface assum es t he availabilit y of t he
include_once
st at em ent and t he PHP
NULL
value. I t also assum es t hat
count
correct ly count s unset values in arrays, which is t rue only for PHP 4.
The im plem ent at ion st rat egy involves t wo classes. The first is a generic base class
MySQL_Access
t hat provides t he variables and m et hods needed for using MySQL. The second is a derived class
Cookbook_DB_Access
t hat has access t o everyt hing in t he base class but aut om at ically set s up connect ion param et ers specifically for t he
cookbook
dat abase so we dont have t o do t hat ourselves. An alt ernat ive im plem ent at ion m ight use j ust a single class
and hardwire t he
cookbook
dat abase param et ers direct ly int o it . However, writ ing t he base class t o be generic allows it t o be used m ore easily for script s t hat access a dat abase ot her
t han
cookbook
. For such script s, youd j ust writ e anot her derived class t hat uses t he base class but provides a different set of connect ion param et ers.
A PHP class definit ion begins w it h a
class
line t hat specifies t he class nam e, t hen defines t he variables and m et hods associat ed wit h t he class. An out line of t he base class,
MySQL_Access
, looks like t his:
class MySQL_Access {
var host_name = ; var user_name = ;
var password = ; var db_name = ;
var conn_id = 0; var errno = 0;
var errstr = ; var halt_on_error = 1;
var query_pieces = array ; var result_id = 0;
var num_rows = 0; var row = array ;
... method definitions ... } end MySQL_Access
The class definit ion begins wit h several variables t hat are used as follows:
•
The first few variables hold t he param et ers for connect ing t o t he MySQL server
host_name
,
user_name
,
password
, and
db_name
. These are em pt y init ially and m ust be set before at t em pt ing a connect ion.
•
Once a connect ion is m ade, t he connect ion ident ifier is st ored in
conn_id
. I t s init ial value, 0, m eans no connect ion. This allows a class inst ance t o det erm ine whet her or
not it has connect ed t o t he dat abase server yet .
• errno
and
errstr
hold error inform at ion; t he class set s t hem aft er each MySQL operat ion t o indicat e t he success or failure of t he operat ion. The init ial values, and t he
em pt y st ring, m ean no error. For errors t hat occur but not as a result of int eract ing wit h t he server,
errno
is set t o - 1, which is a nonzero error value never used by MySQL. This can happen, for exam ple, if you use placeholder charact ers in a query
st ring but dont provide t he correct num ber of dat a values when you bind t hem t o t he placeholders. I n t hat case, t he class det ect s t he error wit hout sending anyt hing t o t he
server.
• halt_on_error
det erm ines whet her or not t o t erm inat e script execut ion when an error occurs. The default is t o do so. Script s t hat want t o perform t heir own error-
checking can set t his t o zero.
• query_pieces
is used t o hold a query st ring for prepared st at em ent s and param et er binding. I ll explain lat er why t his variable is an array.
• result_id
,
num_rows
, and
row
are used during result set processing t o hold t he result set ident ifier, t he num ber of rows changed by or ret urned by t he query, and t he
current row of t he result set .
PHP Class Constructor Functions
I n PHP, you can designat e a const ruct or funct ion in a class definit ion t o be called aut om at ically when new class inst ances are creat ed. This is done by giving t he
funct ion t he sam e nam e as t he class. You m ight do t his, for exam ple, if you need t o init ialize an obj ect s variables t o non-const ant values. I n PHP 4, obj ect variables can
only t ake const ant init ializers. The
MySQL_Access
class has no const ruct or because it s variables all have const ant init ial values.
The m et hod definit ions line near t he end of t he class out line is where well put t he funct ions t hat connect t o t he MySQL server, check for errors, issue queries, and so fort h. Well fill in t hat
part short ly, but before doing so, let s get a sense of how t he class can be used. We can put t he code for t he class in an include file, MySQL_Access.php, and inst all it in a direct ory t hat
PHP searches when looking for include files for exam ple, usr local apache lib php, as described in
Recipe 2.4 . Then we can use t he file by referencing it wit h an
include
st at em ent , creat ing an inst ance of t he class t o get a connect ion obj ect
conn
, and set t ing up t he connect ion param et ers for t hat obj ect :
include MySQL_Access.php; include the MySQL_Access class conn = new MySQL_Access; create new class object
conn-host_name = localhost; initialize connection parameters conn-db_name = cookbook;
conn-user_name = cbuser; conn-password = cbpass;
However, using t he class t his way wouldnt really m ake it very convenient t o connect t o t he server, due t o t he need t o writ e all t hose assignm ent st at em ent s t hat set t he connect ion
param et ers. Heres where a derived class t hat uses t he base class com es in handy, because t he derived class can be writ t en t o set t he param et ers aut om at ically. To t hat end, let s creat e
a class,
Cookbook_DB_Access
, t hat ext ends
MySQL_Access
by supplying param et ers for connect ing t o t he
cookbook
dat abase. Then you can writ e script s t hat prepare t o access t he
cookbook
dat abase wit h j ust t wo lines of code: include Cookbook_DB_Access.php;
conn = new Cookbook_DB_Access; The im plem ent at ion of
Cookbook_DB_Access
is quit e sim ple. Creat e a file, Cookbook_DB_Access.php, t hat looks like t his:
include_once MySQL_Access.php; class Cookbook_DB_Access extends MySQL_Access
{ override default class variable values
var host_name = localhost; var user_name = cbuser;
var password = cbpass; var db_name = cookbook;
}
The
class
line nam es t he class,
Cookbook_DB_Access
, and t he
extends
clause indicat es t hat it s based on t he
MySQL_Access
class. Ext ending a class t his way is called subclassing t he base class, or creat ing a derived class from t he base class. The new class definit ion is
alm ost t rivial, cont aining only variable assignm ent s for connect ion param et ers. These override t he em pt y values t hat are supplied by t he base class. The effect is t hat when you creat e an
inst ance of t he
Cookbook_DB_Access
class, you get an obj ect t hat s j ust like a
MySQL_Access
obj ect , except t hat t he connect ion param et ers are set aut om at ically for connect ing t o t he
cookbook
dat abase. Now you can see m ore clearly why we left t he connect ion param et ers in t he
MySQL_Access
class em pt y rat her t han set t ing t hem for accessing t he
cookbook
dat abase. By leaving t hem blank, we creat e a m ore generic class t hat can be ext ended for any num ber of dat abases by
creat ing different derived classes.
Cookbook_DB_Access
is one such class. I f youre w rit ing a set of script s t hat use a different dat abase, derive anot her ext ended class t hat supplies
appropriat e connect ion param et ers for t hat dat abase. Then have t he script s use t he second ext ended class rat her t han Cookbook_DB_Access.php.
I ncident ally, t he reason t hat Cookbook_DB_Access.php includes MySQL_Access.php is so t hat you dont need t o. When your script s include Cookbook_DB_Access.php, t hey get
MySQL_Access.php for free. The
include_once
st at em ent is used rat her t han
include
t o prevent duplicat e-definit ion problem s from occurring if your script s happen t o include
MySQL_Access.php anyway.
2.10.5 Connecting and Disconnecting