Class Overview Writing an Object-Oriented MySQL Interface for PHP

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