Re: Merging PHPLIB into PEAR
| From: | Kristian Koehntopp | Date: | Fri, 19 Jan 2001 21:31:53 +0000 |
| Subject: | Re: Merging PHPLIB into PEAR | ||
| References: | 1 | Groups: | php.pear |
| Request: | Send a blank email to php-pear+get-1095@lists.php.net to get a copy of this message | ||
On Fri, Jan 19, 2001 at 11:53:53AM -0500, Chuck Hagenbuch wrote:
> > Yes, if you mean that methods of PHPLib classes are
> > underscore with _ as delimiters in names, not java-style
> > PEAR class methods names.
> No, I mean that instead of having a Session:: class with a
> factory method (Session::factory()) that creates objects of
> any session type, saving you from hardcoding class names,
> there is CT_sql, CT_foo, CT_bar, and you need to subclass one
> of them and specify that name somewhere in your app to use it
> - and none of them are related to the Session class, which
> they could inherit from.
This is what I called impedance mismatch between PEAR and PHPLIB
in a previous mail. PEAR parametrizes, for example by
specifiying database connect parameters as parameters to the
constructor (if I am not mistaken).
PHPLIB subclasses instead.
Why does it do that? What is the reasoning behind that?
PHPLIB is build around the idea of an application, which is
basically a set of files/webpages using the same classes. As
these classes are working together, they should be using a set
of specialized classes, which magically know what to do, and how
to connect, and what subclasses to use.
So you have three levels of logic in PHPLIB:
- You have generic code, which is useful in any application.
Such code is in PHPLIB itself, it is abstract and in some
cases (Auth for example) it does not do anything useful
by itself without prior specialization.
DB_Sql (from db_mysql.inc) is such code, it is a complete
class to talk to a MySQL database, but it contains no useful
connect parameters at all, nor a way to specifiy them when
instantiating the class.
- You have application specific code, which is useful in
any page of your specific application and which is shared
among all your pages belonging to a single application. Such
code is either contained in local.inc or included from
local.inc.
Your DB_Sql subclass, for example Example_Sql, is such code.
It is a subclass from a generic PHPLIB class, overwriting
instance variables with sensible defaults for your current
application.
By instantiating Example_Sql, you get a database connection
suited for your application, ready to use, no parameters
needed. Same goes for Example_Session, which does know which
CT_* to use, and for Example_CT_Sql, which does know which
Example_Sql to use.
PHPLIB does this, because it is harmful to specify classnames
or connect parameters on each page. Instead, these values are
kept in a single central location, your subclass definition.
By changing local.inc you control the behaviour of your
application from a single file.
- You have page specific code, which is useful only on
this particular page of an application and which is not shared
at all.
A particular query using Example_Sql is an example for such
code. Such code can be passed as a parameter to a DB_Sql
constructor (or the constructor of any DB_Sql subclass) and
it will not only initialize the class, but also send the
query. This makes your code extremely short using PHPLIBs
DB_Sql:
$db = new Example_Sql("select ...");
while($db->next_record()) {
printf("%s %s %s",
$db->f("field1"),
$db->f("field2"),
$db->f("field3")
);
}
Note how DB_Sql does all the work for you:
It just knows where to connect and how, because that is built
into your subclass as birth knowledge.
Also, it keeps track whether a connection already has been
established, and creates a connection if necessary. There is
no need to call a connect method manually.
Finally, it performs error checking internally, and has an
internal error messaging function which can be overridden by a
subclass to provide customized error handling and error
messages. There is no need to manually check errors.
So all you need to do is to create an object, provide it with
a query (can be all in one as show above) and get your result.
Should your data source change, change your subclass
definition. Should your error handling need changes, change
the subclass definition. The change will be uniform, and
application wide. No need to touch any source file, as the
change is managed centrally from your subclass definition.
The behaviour of CT_*, Session and other PHPLIB classes is
similar - all application wide defaults are inherited and
overridden, not parametrized on each page, as this makes verbose
code and is difficult to change.
Kristian