469,925 Members | 1,493 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,925 developers. It's quick & easy.

OOP database tables <-> php interface (semi LONG)

Hi,

I'm trying to grasp OOP to build an interface using class objects that lets
me access database tables easily. You have probably seen this before, or
maybe even built it yourself at some point in time. I have studied some
examples I found on the internet, and am now trying to build my own from
scratch.

I have made a default table class (DB_Table), a default validation class
(Validator) which is an object inside DB_Table and my final database tables
each get a class: e.g. User, UserProfile, Country, etc that extend the
DB_Table class.

Its something along the lines of (incomplete code, just for demonstration
purpose):

<?php

class DB_Table
{
public function __construct()
{
// intialize object
// initialize (common) validator
$this->validator = new Validator( $this );
}

public function loadData()
{
// get all data from record
}

public function saveData()
{
// save all data to record
}

public function __get( $field )
{
// get object property
}

public function __set( $field, $value )
{
// set object property
}
}

class User extends DB_Table
{
public $dbt = DB_TABLE_USER;

public $fields = array(
'id' =NULL,
'userType' =NULL,
'username' =NULL,
'password' =NULL,
'email' =NULL,
'active' =NULL,
'timeCreated' =NULL,
'timeActivated' =NULL,
'timeUpdated' =NULL
);

public $fieldSpecs = array(
'id' =array(
'screenname' ='user id',
'type' ='int',
'autoinsert' =true,
'autoincrement' =true,
'static' =true
),
'userType' =array(
'type' ='tyniint',
'nodisplay' =true
),
'username' =array(
'screenname' ='username',
'type' ='string',
'unique' =true,
'required' =true,
'static' =true,
),
// etc...
);
}

?>

It definately still needs a lot of tayloring for it to even work smoothly
for straightforward DB tables. But besides that, a few future issues are
bothering me already:

For instance, take the class User: let's say somebody registers at my site.
This person fills in the details. The Validator class checks each field
seperately. No problem. A new User record is inserted in the database.

But what now, if a user wants to login to the system after the user is
registrated?
I would create an instance of class User. Asign the credential values to the
object. And let the Validator class do its work again.
But, if a user logs in with incorrect credentials, I don't want to report
back to the user whether he/she filled in an incorrect username or an
incorrect password. No, I only want to report back that he/she has filled in
wrong credentials.

But the Validator class only checks each field seperately. In order to keep
the Validator class as common as possible would you build a seperate Login
class for instance? A class that has some custom validation methods? Or
perhaps just insert custom validation methods in the User class? I myself
just cannot seem to make up my mind in this case. Probably cause I'm still
too inexperienced when it comes to OOP programming.

A few other minor questions come to mind also:
- My gut feeling tells me it is wise to make a reference to the Validator
class inside DB_Table, e.g:
$this->validator =& new Validator( $this );
.... because it only creates a single instance of the object, right?

- And why can't I refer to a private variable in DB_Table from an extended
class (such as User)? I would asume, that this private variable, declared in
the parent object, is now a private variable in User also, no?

- And last but not least, is there a way for me to access let's say User
properties from the Validator class without having to pass $this as an
argument to:
$this->validator = new Validator( $this );
.... I know the following to be incorrect, but I was thinking of something
like the keyword parent.

I hope these questions and examples make sense to you and hopefully someone
can shed a light on these issues. Thank you in advance for your time.

Cheers
Apr 11 '07 #1
22 2849
amygdala wrote:
But the Validator class only checks each field seperately. In order to keep
the Validator class as common as possible would you build a seperate Login
class for instance? A class that has some custom validation methods? Or
perhaps just insert custom validation methods in the User class?
class User
{
public static logon ($username, $password)
{
// Example query. You will want to protect against SQL
// injection here.
$q = "SELECT blah
FROM blah
WHERE username=$username
AND password=$password";
$result = run_query($q);

if (!$result)
return NULL;

$user = new User;
$user->load_data(/* blah */);
return $user;
}
}

This is an example of a User "factory". See "factory design pattern" in the
PHP manual. To use it:

$logged_in_user = User::logon($_POST['un'], $_POST['pw']);
if (!$logged_in_user)
echo "Login failed.";

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

* = I'm getting there!
Apr 12 '07 #2

"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:jd************@ophelia.g5n.co.uk...
amygdala wrote:
>But the Validator class only checks each field seperately. In order to
keep
the Validator class as common as possible would you build a seperate
Login
class for instance? A class that has some custom validation methods? Or
perhaps just insert custom validation methods in the User class?

class User
{
public static logon ($username, $password)
{
// Example query. You will want to protect against SQL
// injection here.
$q = "SELECT blah
FROM blah
WHERE username=$username
AND password=$password";
$result = run_query($q);

if (!$result)
return NULL;

$user = new User;
$user->load_data(/* blah */);
return $user;
}
}

This is an example of a User "factory". See "factory design pattern" in
the
PHP manual. To use it:

$logged_in_user = User::logon($_POST['un'], $_POST['pw']);
if (!$logged_in_user)
echo "Login failed.";
Thanks for the response and the pointer.

I'm a little confused about the 'factory design pattern' though. Let me see
if I understand this correctly. Does the factory design pattern in this case
refer to the fact that you have different interfaces in one Class (in this
case class User) to create the object, depending on the purpose it serves.

So I could do a:

$blank_user = new User();

or I could do a

$logged_in_user = User::logon($_POST['un'], $_POST['pw']);

which both return a User object?
Apr 12 '07 #3
amygdala wrote:
I'm a little confused about the 'factory design pattern' though. Let me see
if I understand this correctly. Does the factory design pattern in this case
refer to the fact that you have different interfaces in one Class (in this
case class User) to create the object, depending on the purpose it serves.
Yep, precisely. You create a static method to produce an object which
would normally go further than the plain constructor function in terms of
setting object properties.

On some occasions you may even want to make the main constructor method
for the class private instead of public to force all objects to be created
via the factory.

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

* = I'm getting there!
Apr 13 '07 #4

"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:rr************@ophelia.g5n.co.uk...
amygdala wrote:
>I'm a little confused about the 'factory design pattern' though. Let me
see
if I understand this correctly. Does the factory design pattern in this
case
refer to the fact that you have different interfaces in one Class (in
this
case class User) to create the object, depending on the purpose it
serves.

Yep, precisely. You create a static method to produce an object which
would normally go further than the plain constructor function in terms of
setting object properties.

On some occasions you may even want to make the main constructor method
for the class private instead of public to force all objects to be created
via the factory.
Nice one! That's excellent stuff.
In the meantime I read a little further on the factory stuff, and indeed saw
that you could make the constructor method private. Could you by any chance
provide the simplest example of an occassion where making the constructor
private makes sense? Cause I can't think of a valuable situation right now.
But I'm interested in understanding where this would make sense. (That OOP
stuff is pretty hard to grasp for me)

Another thing I am trying to accomplish is the following: (still the same
'framework')

What would be ideal for me is if I had table classes derived from the
'template' DB_Table that would only describe table fields and their
properties. And for the most part let the parent DB_Table handle all the
generic methods for tweaking fields. Except of course a function such as
login, as discussed earlier.

What would seem important here also, is to have as little public methods and
properties as possible. So if you will, consider the following:

class DB_table
{
protected static fields;
protected static fieldSpecs;

// some __constructor etc...

public function getFieldSpecs( $f )
{
if( isset( self::fieldSpecs[ $f ] ) )
{
return self::fieldSpecs[ $f ];
}
else
{
return NULL;
}
}
}

class User extends DB_Table
{
protected static fieldSpecs = array(
'id' =array(
'article' ='a',
'screenname' ='user id',
'type' ='int',
'autoinsert' =true,
'autoincrement' =true,
'static' =true
),
etc...
);
}

What I would like to happen is that when I do a:

$u = new User();
var_dump( $u->getFieldSpecs( 'id' ) );

it would return the 'fieldSpecs' from the 'id' in User. But this doesn't
seem to work.

parent::$fieldSpecs = array( etc...

doesn't seem to work either.

Is there any way to get this working without having to declare fieldSpecs
public and/or having to overload (I think it is what it's called) the
'getFieldSpecs' function from within User?

In other words, how can I overwrite the 'protected static fieldSpecs' of
DB_Table from within User so that 'getFieldSpecs' in DB_Table returns its
values? Or is this against OOP principles?
Cheers.
Apr 13 '07 #5
>
class DB_table
{
protected static fields;
protected static fieldSpecs;

// some __constructor etc...

public function getFieldSpecs( $f )
{
if( isset( self::fieldSpecs[ $f ] ) )
{
return self::fieldSpecs[ $f ];
}
else
{
return NULL;
}
}
}

class User extends DB_Table
{
protected static fieldSpecs = array(
'id' =array(
'article' ='a',
'screenname' ='user id',
'type' ='int',
'autoinsert' =true,
'autoincrement' =true,
'static' =true
),
etc...
);
}
Oops; dollarsigns where needed of course. :-S
Apr 13 '07 #6
amygdala wrote:
"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:rr************@ophelia.g5n.co.uk...
>amygdala wrote:
>>I'm a little confused about the 'factory design pattern' though. Let me
see
if I understand this correctly. Does the factory design pattern in this
case
refer to the fact that you have different interfaces in one Class (in
this
case class User) to create the object, depending on the purpose it
serves.
Yep, precisely. You create a static method to produce an object which
would normally go further than the plain constructor function in terms of
setting object properties.

On some occasions you may even want to make the main constructor method
for the class private instead of public to force all objects to be created
via the factory.

Nice one! That's excellent stuff.
In the meantime I read a little further on the factory stuff, and indeed saw
that you could make the constructor method private. Could you by any chance
provide the simplest example of an occassion where making the constructor
private makes sense? Cause I can't think of a valuable situation right now.
But I'm interested in understanding where this would make sense. (That OOP
stuff is pretty hard to grasp for me)

Another thing I am trying to accomplish is the following: (still the same
'framework')

What would be ideal for me is if I had table classes derived from the
'template' DB_Table that would only describe table fields and their
properties. And for the most part let the parent DB_Table handle all the
generic methods for tweaking fields. Except of course a function such as
login, as discussed earlier.

What would seem important here also, is to have as little public methods and
properties as possible. So if you will, consider the following:

class DB_table
{
protected static fields;
protected static fieldSpecs;

// some __constructor etc...

public function getFieldSpecs( $f )
{
if( isset( self::fieldSpecs[ $f ] ) )
{
return self::fieldSpecs[ $f ];
}
else
{
return NULL;
}
}
}

class User extends DB_Table
{
protected static fieldSpecs = array(
'id' =array(
'article' ='a',
'screenname' ='user id',
'type' ='int',
'autoinsert' =true,
'autoincrement' =true,
'static' =true
),
etc...
);
}

What I would like to happen is that when I do a:

$u = new User();
var_dump( $u->getFieldSpecs( 'id' ) );

it would return the 'fieldSpecs' from the 'id' in User. But this doesn't
seem to work.

parent::$fieldSpecs = array( etc...

doesn't seem to work either.

Is there any way to get this working without having to declare fieldSpecs
public and/or having to overload (I think it is what it's called) the
'getFieldSpecs' function from within User?

In other words, how can I overwrite the 'protected static fieldSpecs' of
DB_Table from within User so that 'getFieldSpecs' in DB_Table returns its
values? Or is this against OOP principles?
Cheers.

Definitely properties should be private. They're part of the
implementation.

However, I often have lots of public methods. For instance, I'll have a
getXXX method to fetch 'xxx'. And I may have a setxxx method to set it,
if that makes sense - the latter doing validation on the parameter
passed, if necessary.

So potentially in a table with 25 columns I can have 25 getXXX and 25
setXXX methods (and 25 private variables, one for each column), database
related methods, etc. This can easily come out to 60-70 public methods
- and often I'll have some private ones, also.

But don't try to put all of your variables in one 'fieldspec' array.
While it will work, it will also be almost impossible to understand
later and even worse to maintain.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 13 '07 #7
amygdala wrote:
"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:rr************@ophelia.g5n.co.uk...
>amygdala wrote:
>>I'm a little confused about the 'factory design pattern' though. Let me
see
if I understand this correctly. Does the factory design pattern in this
case
refer to the fact that you have different interfaces in one Class (in
this
case class User) to create the object, depending on the purpose it
serves.
Yep, precisely. You create a static method to produce an object which
would normally go further than the plain constructor function in terms of
setting object properties.

On some occasions you may even want to make the main constructor method
for the class private instead of public to force all objects to be created
via the factory.

Nice one! That's excellent stuff.
In the meantime I read a little further on the factory stuff, and indeed saw
that you could make the constructor method private. Could you by any chance
provide the simplest example of an occassion where making the constructor
private makes sense? Cause I can't think of a valuable situation right now.
But I'm interested in understanding where this would make sense. (That OOP
stuff is pretty hard to grasp for me)

Another thing I am trying to accomplish is the following: (still the same
'framework')

What would be ideal for me is if I had table classes derived from the
'template' DB_Table that would only describe table fields and their
properties. And for the most part let the parent DB_Table handle all the
generic methods for tweaking fields. Except of course a function such as
login, as discussed earlier.

What would seem important here also, is to have as little public methods and
properties as possible. So if you will, consider the following:

class DB_table
{
protected static fields;
protected static fieldSpecs;

// some __constructor etc...

public function getFieldSpecs( $f )
{
if( isset( self::fieldSpecs[ $f ] ) )
{
return self::fieldSpecs[ $f ];
}
else
{
return NULL;
}
}
}

class User extends DB_Table
{
protected static fieldSpecs = array(
'id' =array(
'article' ='a',
'screenname' ='user id',
'type' ='int',
'autoinsert' =true,
'autoincrement' =true,
'static' =true
),
etc...
);
}

What I would like to happen is that when I do a:

$u = new User();
var_dump( $u->getFieldSpecs( 'id' ) );

it would return the 'fieldSpecs' from the 'id' in User. But this doesn't
seem to work.

parent::$fieldSpecs = array( etc...

doesn't seem to work either.

Is there any way to get this working without having to declare fieldSpecs
public and/or having to overload (I think it is what it's called) the
'getFieldSpecs' function from within User?

In other words, how can I overwrite the 'protected static fieldSpecs' of
DB_Table from within User so that 'getFieldSpecs' in DB_Table returns its
values? Or is this against OOP principles?
Cheers.

One other thing - the class members shouldn't be static. Static members
are shared by all objects of the class. So if you have two objects of
this class and change it in one, both will change.

Non-static data members are unique to each instantiation of the class.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 13 '07 #8

"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:_L******************************@comcast.com. ..
amygdala wrote:
<snip>

Definitely properties should be private. They're part of the
implementation.

However, I often have lots of public methods. For instance, I'll have a
getXXX method to fetch 'xxx'. And I may have a setxxx method to set it,
if that makes sense - the latter doing validation on the parameter passed,
if necessary.

So potentially in a table with 25 columns I can have 25 getXXX and 25
setXXX methods (and 25 private variables, one for each column), database
related methods, etc. This can easily come out to 60-70 public methods -
and often I'll have some private ones, also.
Well, this is just exactly what I am trying to avoid. I have (unfinished)
__get and __set methods in the base class DB_Table that should take care of
this in one go.
But don't try to put all of your variables in one 'fieldspec' array. While
it will work, it will also be almost impossible to understand later and
even worse to maintain.
Hmm, you are no doubt much more experienced in this field, but my gutfeeling
says I have to disagree on this one. The whole point of creating this
framework for me is to avoid the cumbersome task of creating getter and
setter functions for each and every table field. Thus I'm declaring one
generic fieldSpecs array that provides properties for the fields so that the
generic getters and setters as well as the generic Validator will take care
of the rest. I don't see the fieldSpecs array becoming to difficult to
understand quickly for me in the future.

Still, this leaves me wondering: why doesn't a child class just simply
inherite the 'getFieldSpecs' function and let self::$fieldSpecs refer to the
$fieldSpecs in the child class? Should this not be the basics of OOP? What
am I missing here? Or better yet: how can this be achieved?

Thanks for your time people. Much appreciated!
Apr 13 '07 #9

"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:_L******************************@comcast.com. ..
amygdala wrote:
<snip>
>
One other thing - the class members shouldn't be static. Static members
are shared by all objects of the class. So if you have two objects of
this class and change it in one, both will change.

Non-static data members are unique to each instantiation of the class.
Aaah yes of course. Silly me. Good point. I overlooked that one.

But would it be save to say that a derived class of DB_Table such as User
_could_ have a static $fields variable (for instance when I wont be
declaring it in the parent class first), since every User instance would
have the same table fields?

Thanks again Jerry et al.
Apr 13 '07 #10
amygdala wrote:
"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:_L******************************@comcast.com. ..
>amygdala wrote:

<snip>

>Definitely properties should be private. They're part of the
implementation.

However, I often have lots of public methods. For instance, I'll have a
getXXX method to fetch 'xxx'. And I may have a setxxx method to set it,
if that makes sense - the latter doing validation on the parameter passed,
if necessary.

So potentially in a table with 25 columns I can have 25 getXXX and 25
setXXX methods (and 25 private variables, one for each column), database
related methods, etc. This can easily come out to 60-70 public methods -
and often I'll have some private ones, also.

Well, this is just exactly what I am trying to avoid. I have (unfinished)
__get and __set methods in the base class DB_Table that should take care of
this in one go.
>But don't try to put all of your variables in one 'fieldspec' array. While
it will work, it will also be almost impossible to understand later and
even worse to maintain.

Hmm, you are no doubt much more experienced in this field, but my gutfeeling
says I have to disagree on this one. The whole point of creating this
framework for me is to avoid the cumbersome task of creating getter and
setter functions for each and every table field. Thus I'm declaring one
generic fieldSpecs array that provides properties for the fields so that the
generic getters and setters as well as the generic Validator will take care
of the rest. I don't see the fieldSpecs array becoming to difficult to
understand quickly for me in the future.

Still, this leaves me wondering: why doesn't a child class just simply
inherite the 'getFieldSpecs' function and let self::$fieldSpecs refer to the
$fieldSpecs in the child class? Should this not be the basics of OOP? What
am I missing here? Or better yet: how can this be achieved?

Thanks for your time people. Much appreciated!

OK, now how are you going to validate the entry? For instance - if you
have a date field, ensure they put a date in there? Or an integer?

Classes also need to be responsible for their own variables. There
should be no way you can ever set an invalid value in any member.

So you might as well get used to writing the set and get functions.
They go pretty quickly (unless you have some extensive validation), and
in the long run it's a much better way to go.

I've been doing OO programming for almost 20 years now, and yes, I've
seen your way before. It ends up being cumbersome and highly prone to
errors. It also creates a maintenance nightmare. You *really* don't
want to go that route.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 13 '07 #11
amygdala wrote:
"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:_L******************************@comcast.com. ..
>amygdala wrote:

<snip>
>One other thing - the class members shouldn't be static. Static members
are shared by all objects of the class. So if you have two objects of
this class and change it in one, both will change.

Non-static data members are unique to each instantiation of the class.

Aaah yes of course. Silly me. Good point. I overlooked that one.

But would it be save to say that a derived class of DB_Table such as User
_could_ have a static $fields variable (for instance when I wont be
declaring it in the parent class first), since every User instance would
have the same table fields?

Thanks again Jerry et al.

No, because I would never do it that way per my previous response.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 13 '07 #12

"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:Ub******************************@comcast.com. ..
amygdala wrote:
>"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:_L******************************@comcast.com ...
>>amygdala wrote:

<snip>

>>Definitely properties should be private. They're part of the
implementation.

However, I often have lots of public methods. For instance, I'll have a
getXXX method to fetch 'xxx'. And I may have a setxxx method to set it,
if that makes sense - the latter doing validation on the parameter
passed, if necessary.

So potentially in a table with 25 columns I can have 25 getXXX and 25
setXXX methods (and 25 private variables, one for each column), database
related methods, etc. This can easily come out to 60-70 public
methods - and often I'll have some private ones, also.

Well, this is just exactly what I am trying to avoid. I have (unfinished)
__get and __set methods in the base class DB_Table that should take care
of this in one go.
>>But don't try to put all of your variables in one 'fieldspec' array.
While it will work, it will also be almost impossible to understand
later and even worse to maintain.

Hmm, you are no doubt much more experienced in this field, but my
gutfeeling says I have to disagree on this one. The whole point of
creating this framework for me is to avoid the cumbersome task of
creating getter and setter functions for each and every table field. Thus
I'm declaring one generic fieldSpecs array that provides properties for
the fields so that the generic getters and setters as well as the generic
Validator will take care of the rest. I don't see the fieldSpecs array
becoming to difficult to understand quickly for me in the future.

Still, this leaves me wondering: why doesn't a child class just simply
inherite the 'getFieldSpecs' function and let self::$fieldSpecs refer to
the $fieldSpecs in the child class? Should this not be the basics of OOP?
What am I missing here? Or better yet: how can this be achieved?

Thanks for your time people. Much appreciated!

OK, now how are you going to validate the entry? For instance - if you
have a date field, ensure they put a date in there? Or an integer?
Well, I would use a generic Validator class for that. Something along the
lines of:

class Validator
{
public function validateField( $fieldName, $fieldValue, $fieldSpecs )
{
switch( $fieldSpec [ 'type' ] )
{
case 'boolean':
// validate boolean
break;
case 'string':
if( isset( $fieldSpec[ 'subtype' ] ) )
{
switch( $fieldSpec[ 'subtype' ] )
{
case 'email':
// validate email
break;
case 'url':
// validate url
break
etc.. etc...
}
}
case 'int':
etc.. etc...
For dates I _would_ probably use a custom setter which would convert three
form elements (dd, mm, yyyy) to a unix timestamp (I like those better then
SQL dates) first, but then I would validate its outcome with the generic
Validator also. I could even have some minimal and maximal date values in
$fieldSpecs to check that the date doesn't exceed a certain time span.

For integers I would define some minimal and maximal values in the
$fieldSpecs, and check it directly in the generic Validator. Use is_numeric
and the likes.
Classes also need to be responsible for their own variables. There should
be no way you can ever set an invalid value in any member.
Of course, I agree with you totally. But I don't see how my approach would
lead to this happening. I would validate each entry just like you do. But
with a generic __set instead of custom setters.
So you might as well get used to writing the set and get functions. They
go pretty quickly (unless you have some extensive validation), and in the
long run it's a much better way to go.
Maybe you're right. I might be stubborn here. ;-) And off course, I have
thought of the fact that exceptional situations _will_ occur. Probably more
often then I'm thinking off right now. But then that leads me to the
somewhat black and white conclusion stated under your following opinions:
I've been doing OO programming for almost 20 years now, and yes, I've seen
your way before. It ends up being cumbersome and highly prone to errors.
It also creates a maintenance nightmare. You *really* don't want to go
that route.
I see where you are coming from Jerry, but this point of view then almost
leads me to believe that there is no point in creating DB table objects
whatsoever. Cause then it pretty much comes down to the same old 'linear'
routines again. What then, in your opinion, is the surplus value of creating
DB table classes?
Apr 13 '07 #13
amygdala wrote:
Could you by any chance provide the simplest example of an occassion
where making the constructor private makes sense? Cause I can't think of
a valuable situation right now.
OK -- how about this -- you have a Database class, but you want to make
sure that your scripts only ever open a single connection to the database.
You don't want both, say, a User object and an Article object to open
their own individual connections like this:

<?php
class User
{
private $db;
public function __construct ()
{
$this->db = new Database(/*...*/);
}
}
class Article
{
private $db;
public function __construct ()
{
$this->db = new Database(/*...*/);
}
}
?>

And so to prevent this, you make the Database's constructor function
private. This is known as the "singleton" design pattern in the PHP
manual. (It's on the same page as the factory design pattern!)

<?php
class Database
{
public function query ($q) { /*...*/ }
public function type () { /*...*/ }
public function escape_string ($s) { /*...*/ }
private function __construct ($dsn, $username, $password) { /*...*/ }

private static $instance;
public static singleton ($dsn, $username, $password)
{
if (!isset(self::$instance))
self::$instance = new Database ($dsn, $username, $password);

return self::$instance;
}
}
?>

So now you must use "Database::singleton()" instead of "new Database" to
get a database object, but the singleton class method will always return a
pointer to the same Database object -- it won't create a brand new one!

And your code becomes:

<?php
class User
{
private $db;
public function __construct ()
{
$this->db = Database::singleton(/*...*/);
}
}
class Article
{
private $db;
public function __construct ()
{
$this->db = Database::singleton(/*...*/);
}
}
?>

I bet if you think about it there are plenty of occasions when the
singleton design pattern would have come in handy if you'd known about it!
That OOP stuff is pretty hard to grasp for me
Don't worry about it. I think a lot of PHPers are at that stage now. PHP
4's object oriented capabilities were fairly limited, so apart from the
benefit of namespacing (i.e. being able to wrap up a bunch of functions and
variables into something with just one name) objects didn't offer an awful
lot of benefit over, say, arrays. A couple of years after its release, PHP
5 is only really beginning to get decent penetration onto commercial web
servers.

I'm quite lucky in that I have direct physical access to most of the PHP
servers I use, and quite a lot of say over the ones I don't have physical
access to. So I upgraded most of them to PHP 5 when it was still fairly
new (I waited until 5.0.4 I think. Most are now on 5.1.x and I'm looking
to switch to 5.2.x after another release or two), so I've been able to play
with the improved OO facilities for quite a while. But I'm still learning
things too!

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

* = I'm getting there!
Apr 13 '07 #14
amygdala wrote:
"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:Ub******************************@comcast.com. ..
>amygdala wrote:
>>"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:_L******************************@comcast.co m...
amygdala wrote:
<snip>
Definitely properties should be private. They're part of the
implementation.

However, I often have lots of public methods. For instance, I'll have a
getXXX method to fetch 'xxx'. And I may have a setxxx method to set it,
if that makes sense - the latter doing validation on the parameter
passed, if necessary.

So potentially in a table with 25 columns I can have 25 getXXX and 25
setXXX methods (and 25 private variables, one for each column), database
related methods, etc. This can easily come out to 60-70 public
methods - and often I'll have some private ones, also.
Well, this is just exactly what I am trying to avoid. I have (unfinished)
__get and __set methods in the base class DB_Table that should take care
of this in one go.

But don't try to put all of your variables in one 'fieldspec' array.
While it will work, it will also be almost impossible to understand
later and even worse to maintain.
Hmm, you are no doubt much more experienced in this field, but my
gutfeeling says I have to disagree on this one. The whole point of
creating this framework for me is to avoid the cumbersome task of
creating getter and setter functions for each and every table field. Thus
I'm declaring one generic fieldSpecs array that provides properties for
the fields so that the generic getters and setters as well as the generic
Validator will take care of the rest. I don't see the fieldSpecs array
becoming to difficult to understand quickly for me in the future.

Still, this leaves me wondering: why doesn't a child class just simply
inherite the 'getFieldSpecs' function and let self::$fieldSpecs refer to
the $fieldSpecs in the child class? Should this not be the basics of OOP?
What am I missing here? Or better yet: how can this be achieved?

Thanks for your time people. Much appreciated!
OK, now how are you going to validate the entry? For instance - if you
have a date field, ensure they put a date in there? Or an integer?

Well, I would use a generic Validator class for that. Something along the
lines of:

class Validator
{
public function validateField( $fieldName, $fieldValue, $fieldSpecs )
{
switch( $fieldSpec [ 'type' ] )
{
case 'boolean':
// validate boolean
break;
case 'string':
if( isset( $fieldSpec[ 'subtype' ] ) )
{
switch( $fieldSpec[ 'subtype' ] )
{
case 'email':
// validate email
break;
case 'url':
// validate url
break
etc.. etc...
}
}
case 'int':
etc.. etc...
And as you add more types and subtypes, this gets longer and longer.
And slower and slower. And harder to maintain and more subject to errors.
>
For dates I _would_ probably use a custom setter which would convert three
form elements (dd, mm, yyyy) to a unix timestamp (I like those better then
SQL dates) first, but then I would validate its outcome with the generic
Validator also. I could even have some minimal and maximal date values in
$fieldSpecs to check that the date doesn't exceed a certain time span.
And you'll have to add more custom validators plus hooks for them.
For integers I would define some minimal and maximal values in the
$fieldSpecs, and check it directly in the generic Validator. Use is_numeric
and the likes.
And what about cases where you need non-consecutive numbers? Such as
those from the set (1, 2, 3, 5, 8, 13, 21...)? Another custom validator...
>Classes also need to be responsible for their own variables. There should
be no way you can ever set an invalid value in any member.

Of course, I agree with you totally. But I don't see how my approach would
lead to this happening. I would validate each entry just like you do. But
with a generic __set instead of custom setters.
The generic will be much larger, much slower and much harder to maintain.
>So you might as well get used to writing the set and get functions. They
go pretty quickly (unless you have some extensive validation), and in the
long run it's a much better way to go.

Maybe you're right. I might be stubborn here. ;-) And off course, I have
thought of the fact that exceptional situations _will_ occur. Probably more
often then I'm thinking off right now. But then that leads me to the
somewhat black and white conclusion stated under your following opinions:
Yes, it's easy to get one idea in your mind as the best way and stick to
it too long. You need to be flexible. Even after 40 years of
programming I sometimes have to change my approach because someone shows
me a better way.
>I've been doing OO programming for almost 20 years now, and yes, I've seen
your way before. It ends up being cumbersome and highly prone to errors.
It also creates a maintenance nightmare. You *really* don't want to go
that route.

I see where you are coming from Jerry, but this point of view then almost
leads me to believe that there is no point in creating DB table objects
whatsoever. Cause then it pretty much comes down to the same old 'linear'
routines again. What then, in your opinion, is the surplus value of creating
DB table classes?

I create db objects all the time. But they have get and set functions
for each field (at least the appropriate ones). They are quite handy
for a number of purposes - the biggest one being abstracting the
database access. But then that's their major purpose.

For instance - one I'm on right now. I have a site coded in VBScript
using Access. I want to change it to PHP and MySQL. However, for
various reasons this needs to be done in stages. The Access database
has over 30 tables, ranging from 2 columns to over 40 columns per table.

We're (others are involved - it's a big site) creating DB objects to
interface the Access tables. These will handle the actual SQL calls and
isolates the program from the database being used (or even flat files,
if necessary).

Next we'll creating business objects - these objects translate between
the program and the database objects, and convert what's in the tables
to a format the rest of the program needs. This isolates the rest of
the code from the database table design (i.e. if we need to change one
or more tables, this and the db objects are all that will need changing).

We'll then convert sections of the site at a time. Once we get a
section converted, we'll bring it online.

When we're done and can change from the Access database to MySQL, we'll
change the Database layer and move the data. If at the same time we
need to change some of the table design, this will be handled between
the database and business object layers. But any changes will be
isolated to those layers.

Note the business object layer isn't always needed. But due to the
complexity of the site and how many tables are interrelated, we decided
it would be better to use them here.

These are the benefits of database objects (and OO in general).
But I would hate to use your fieldspec idea in this case. It would
make things much harder to troubleshoot, and we'd end up with a lot of
specialized validators. The result would rapidly become unmanageable.

So we're putting in the set and get functions for several hundred table
columns. Additionally, we're doing a similar number on the business
object end. And depending on the data, it may be validated in either level.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 13 '07 #15

"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:r1************@ophelia.g5n.co.uk...
amygdala wrote:
>Could you by any chance provide the simplest example of an occassion
where making the constructor private makes sense? Cause I can't think of
a valuable situation right now.

OK -- how about this -- you have a Database class, but you want to make
sure that your scripts only ever open a single connection to the database.
You don't want both, say, a User object and an Article object to open
their own individual connections like this:

<?php
class User
{
private $db;
public function __construct ()
{
$this->db = new Database(/*...*/);
}
}
class Article
{
private $db;
public function __construct ()
{
$this->db = new Database(/*...*/);
}
}
?>

And so to prevent this, you make the Database's constructor function
private. This is known as the "singleton" design pattern in the PHP
manual. (It's on the same page as the factory design pattern!)

<?php
class Database
{
public function query ($q) { /*...*/ }
public function type () { /*...*/ }
public function escape_string ($s) { /*...*/ }
private function __construct ($dsn, $username, $password) { /*...*/ }

private static $instance;
public static singleton ($dsn, $username, $password)
{
if (!isset(self::$instance))
self::$instance = new Database ($dsn, $username, $password);

return self::$instance;
}
}
?>

So now you must use "Database::singleton()" instead of "new Database" to
get a database object, but the singleton class method will always return a
pointer to the same Database object -- it won't create a brand new one!

And your code becomes:

<?php
class User
{
private $db;
public function __construct ()
{
$this->db = Database::singleton(/*...*/);
}
}
class Article
{
private $db;
public function __construct ()
{
$this->db = Database::singleton(/*...*/);
}
}
?>
Aaah yes of course, I read about such an example at one point in time. And
at first I didn't understand how such an object could ever be made since the
constructor is private. So I left it for what it was. But the object is of
course constructed from within the object itself with its singleton method.
Doh! ;-)
It all makes sense now. Thanks Toby.

Apr 13 '07 #16

"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:mp******************************@comcast.com. ..
amygdala wrote:
<snip>
And as you add more types and subtypes, this gets longer and longer. And
slower and slower. And harder to maintain and more subject to errors.
<snip>
And you'll have to add more custom validators plus hooks for them.
<snip>
And what about cases where you need non-consecutive numbers? Such as
those from the set (1, 2, 3, 5, 8, 13, 21...)? Another custom
validator...
<snip>
The generic will be much larger, much slower and much harder to maintain.
<snip>
Yes, it's easy to get one idea in your mind as the best way and stick to
it too long. You need to be flexible. Even after 40 years of programming
I sometimes have to change my approach because someone shows me a better
way.
<snip>
I create db objects all the time. But they have get and set functions for
each field (at least the appropriate ones). They are quite handy for a
number of purposes - the biggest one being abstracting the database
access. But then that's their major purpose.

For instance - one I'm on right now. I have a site coded in VBScript
using Access. I want to change it to PHP and MySQL. However, for various
reasons this needs to be done in stages. The Access database has over 30
tables, ranging from 2 columns to over 40 columns per table.

We're (others are involved - it's a big site) creating DB objects to
interface the Access tables. These will handle the actual SQL calls and
isolates the program from the database being used (or even flat files, if
necessary).

Next we'll creating business objects - these objects translate between the
program and the database objects, and convert what's in the tables to a
format the rest of the program needs. This isolates the rest of the code
from the database table design (i.e. if we need to change one or more
tables, this and the db objects are all that will need changing).

We'll then convert sections of the site at a time. Once we get a section
converted, we'll bring it online.

When we're done and can change from the Access database to MySQL, we'll
change the Database layer and move the data. If at the same time we need
to change some of the table design, this will be handled between the
database and business object layers. But any changes will be isolated to
those layers.

Note the business object layer isn't always needed. But due to the
complexity of the site and how many tables are interrelated, we decided it
would be better to use them here.

These are the benefits of database objects (and OO in general).
But I would hate to use your fieldspec idea in this case. It would make
things much harder to troubleshoot, and we'd end up with a lot of
specialized validators. The result would rapidly become unmanageable.

So we're putting in the set and get functions for several hundred table
columns. Additionally, we're doing a similar number on the business
object end. And depending on the data, it may be validated in either
level.
Some darned good points Jerry. Especially the getting too large and slow
parts are starting to convince me

Good point about the flexibility too! I try my best to keep up a flexible
attitude. The thing is though that I often get caught up in trying to
generalize things too much and/or mixing up in what 'layer' certain routines
should take place.

For instance, as you put in your example: Where would validating in the
bussiness objects stop and validating in DB objects start, or vice versa.
Are there some ground rules or methodologies for determining this in early
stages of coding a project? Do you know of some pointers; some good clear
articles perhaps?

Just out of curiousity though. I assume that you _do_ have some sort of
generic validator routines for repeating column / field validation right?
For instance a generic validateEmail() function which you call for the
specific task when doing a setEmail. You're not reinventing the wheel in
each and every getter methods right?

Thanks again!
Apr 13 '07 #17
amygdala wrote:
"Jerry Stuckle" <js*******@attglobal.netschreef in bericht
news:mp******************************@comcast.com. ..
>amygdala wrote:

<snip>
>And as you add more types and subtypes, this gets longer and longer. And
slower and slower. And harder to maintain and more subject to errors.

<snip>
>And you'll have to add more custom validators plus hooks for them.

<snip>
>And what about cases where you need non-consecutive numbers? Such as
those from the set (1, 2, 3, 5, 8, 13, 21...)? Another custom
validator...

<snip>
>The generic will be much larger, much slower and much harder to maintain.

<snip>
>Yes, it's easy to get one idea in your mind as the best way and stick to
it too long. You need to be flexible. Even after 40 years of programming
I sometimes have to change my approach because someone shows me a better
way.

<snip>
>I create db objects all the time. But they have get and set functions for
each field (at least the appropriate ones). They are quite handy for a
number of purposes - the biggest one being abstracting the database
access. But then that's their major purpose.

For instance - one I'm on right now. I have a site coded in VBScript
using Access. I want to change it to PHP and MySQL. However, for various
reasons this needs to be done in stages. The Access database has over 30
tables, ranging from 2 columns to over 40 columns per table.

We're (others are involved - it's a big site) creating DB objects to
interface the Access tables. These will handle the actual SQL calls and
isolates the program from the database being used (or even flat files, if
necessary).

Next we'll creating business objects - these objects translate between the
program and the database objects, and convert what's in the tables to a
format the rest of the program needs. This isolates the rest of the code
from the database table design (i.e. if we need to change one or more
tables, this and the db objects are all that will need changing).

We'll then convert sections of the site at a time. Once we get a section
converted, we'll bring it online.

When we're done and can change from the Access database to MySQL, we'll
change the Database layer and move the data. If at the same time we need
to change some of the table design, this will be handled between the
database and business object layers. But any changes will be isolated to
those layers.

Note the business object layer isn't always needed. But due to the
complexity of the site and how many tables are interrelated, we decided it
would be better to use them here.

These are the benefits of database objects (and OO in general).
But I would hate to use your fieldspec idea in this case. It would make
things much harder to troubleshoot, and we'd end up with a lot of
specialized validators. The result would rapidly become unmanageable.

So we're putting in the set and get functions for several hundred table
columns. Additionally, we're doing a similar number on the business
object end. And depending on the data, it may be validated in either
level.

Some darned good points Jerry. Especially the getting too large and slow
parts are starting to convince me

Good point about the flexibility too! I try my best to keep up a flexible
attitude. The thing is though that I often get caught up in trying to
generalize things too much and/or mixing up in what 'layer' certain routines
should take place.

For instance, as you put in your example: Where would validating in the
bussiness objects stop and validating in DB objects start, or vice versa.
Are there some ground rules or methodologies for determining this in early
stages of coding a project? Do you know of some pointers; some good clear
articles perhaps?
Generally the business object is at least (if not more) restrictive than
the database object, so the validation would be done in the business
object. I don't normally validate in the database object if it's not
being accessed by the program itself.
Just out of curiousity though. I assume that you _do_ have some sort of
generic validator routines for repeating column / field validation right?
For instance a generic validateEmail() function which you call for the
specific task when doing a setEmail. You're not reinventing the wheel in
each and every getter methods right?

Thanks again!

Not necessarily functions - just some spare code running around. I
either copy and paste into a function or create a validator function
with it, depending on my needs.

I generally don't create a separate function just to validate one
attribute. I just put the code directly in the setxxx function.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Apr 14 '07 #18

"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:rr************@ophelia.g5n.co.uk...
amygdala wrote:
>I'm a little confused about the 'factory design pattern' though. Let me
see
if I understand this correctly. Does the factory design pattern in this
case
refer to the fact that you have different interfaces in one Class (in
this
case class User) to create the object, depending on the purpose it
serves.

Yep, precisely. You create a static method to produce an object which
would normally go further than the plain constructor function in terms of
setting object properties.

On some occasions you may even want to make the main constructor method
for the class private instead of public to force all objects to be created
via the factory.
I think I am starting to get the hang of this factory design pattern. My
class User up until now looks something like (stripped version, and needs
custom error handling, etc.):

<?php

require_once( 'Database.class.php' );

class User
{
// database handler values
private static $dbh;
private static $dbt = DB_TABLE_USER;

// table columns
private $id;
private $userType;
private $username;
private $password;
private $email;
private $active;
private $timeCreated;
private $timeActivated;
private $timeUpdated;

public function __construct()
{
self::$dbh = Database::getInstance( DB_INTERFACE, DB_HOST, DB_SCHEMA,
DB_USERNAME, DB_PASSWORD );
}

public function getUsername()
{
return $this->username;
}

// and a bunch of other getter and setter methods

public static function getUserById( $id )
{
if( is_mysql_int( $id, true ) )
{
self::$dbh = Database::getInstance( DB_INTERFACE, DB_HOST, DB_SCHEMA,
DB_USERNAME, DB_PASSWORD );
$sql = 'SELECT * FROM ' . self::$dbt . ' WHERE id = :id LIMIT 1';
$sth = self::$dbh->prepare( $sql );
try
{
$sth->execute( array(
':id' =$id
)
);
}
catch( PDOException $e )
{
die( $e->getMessage() . ' on line: ' . __LINE__ );
}
$row = $sth->fetch( PDO::FETCH_ASSOC );
if( $row )
{
$user = new User();
foreach( $row as $column =$value )
{
$user->{ $column } = $value;
}
return $user;
}
echo 'no user found!';
return NULL;
}
echo 'invalid id!';
return NULL;
}
}
?>

A few questions though:

Since I would like to have only one database handler that can be accessed by
both the constructor and the factory method (?) getUserById() I decided to
declare $dbh static. Does this make sense? If so, it seems I'm not allowed
to declare it all in one go at the start of the class like so:

private static $dbh = Database::getInstance( DB_INTERFACE, DB_HOST,
DB_SCHEMA, DB_USERNAME, DB_PASSWORD );

Any ideas why not?

But what is of more concern for me right now is the following:

A user should be able to register and later on login to the website I'm
building. Logging in, seems pretty obvious, should be a method of the User
class, which returns a User object just like getUserById(). But would a
register method be a logical thing to put in the User class? Or would you
put that somewhere else?

Thank you once more for any insight.
Apr 15 '07 #19
amygdala wrote:
Since I would like to have only one database handler that can be accessed by
both the constructor and the factory method (?) getUserById() I decided to
declare $dbh static. Does this make sense?
It makes sense, but a better solution would be to make your database
object into a singleton class. That is, similar to the Database object
here:

http://message-id.net/<r1************@ophelia.g5n.co.uk>

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

* = I'm getting there!
Apr 16 '07 #20

"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:dc************@ophelia.g5n.co.uk...
amygdala wrote:
>Since I would like to have only one database handler that can be accessed
by
both the constructor and the factory method (?) getUserById() I decided
to
declare $dbh static. Does this make sense?

It makes sense, but a better solution would be to make your database
object into a singleton class. That is, similar to the Database object
here:

http://message-id.net/<r1************@ophelia.g5n.co.uk>
Well, that is the case already. Perhaps it was a bit confusion because I
named the method in the Database object getInstance. I've changed it to
getSingleton now. (See below).

But that still doesn't allow me to create the $dbh only once at the
beginning of the User class like so:

class User
{
private $dbh = Database::getSingleton( /* */ );

private function __construct() {}

public static function getUserById()
{
// use self::$dbh here
}

public function saveUser()
{
// use self::$dbh here
}
}

Mind you, it's not a big issue, merely a cosmetic one. What I am still
struggeling more with is the registrate function. Would you consider that a
User class method. Or should it be in some other object. Or perhaps just be
a regular function in the global script?
// class Database code:

class Database
{
protected static $dbh;

private function __construct() {}

public static function getSingleton( $interface, $host, $schema, $username,
$password )
{
if ( !isset( self::$dbh ) )
{
self::$dbh = new PDO( ( $interface . ':host=' . $host . ';dbname=' .
$schema ), $username, $password );
self::$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
//self::$dbh->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, TRUE );
}
return self::$dbh;
}

public function __destruct()
{
if ( isset( self::$dbh ) )
{
self::$dbh = NULL;
}
}
}
Apr 16 '07 #21
amygdala wrote:
Mind you, it's not a big issue, merely a cosmetic one. What I am still
struggeling more with is the registrate function. Would you consider that a
User class method. Or should it be in some other object. Or perhaps just be
a regular function in the global script?
It could be implemented as a regular function, but I'd tend to put it as a
static factory function in the User class. (i.e. it returns the newly
registered User as an object -- much like the static login function
would.) This has the benefit of having internal consistency with the login
function. (A developer familiar with the login function would have little
trouble picking up the registration function.) Also, it keeps the function
"wrapped up" in the User class, so that everything is kept in one place.

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

* = I'm getting there!
Apr 16 '07 #22

"Toby A Inkster" <us**********@tobyinkster.co.ukschreef in bericht
news:go************@ophelia.g5n.co.uk...
amygdala wrote:
>Mind you, it's not a big issue, merely a cosmetic one. What I am still
struggeling more with is the registrate function. Would you consider that
a
User class method. Or should it be in some other object. Or perhaps just
be
a regular function in the global script?

It could be implemented as a regular function, but I'd tend to put it as a
static factory function in the User class. (i.e. it returns the newly
registered User as an object -- much like the static login function
would.) This has the benefit of having internal consistency with the login
function. (A developer familiar with the login function would have little
trouble picking up the registration function.) Also, it keeps the function
"wrapped up" in the User class, so that everything is kept in one place.
Alright Toby, that is reassuring. Thanks for the input.
Apr 16 '07 #23

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Don Vaillancourt | last post: by
35 posts views Thread by Terry Jolly | last post: by
bartonc
reply views Thread by bartonc | last post: by
8 posts views Thread by situ | last post: by
12 posts views Thread by grace | last post: by
9 posts views Thread by Peter Duniho | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.