473,573 Members | 2,905 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 3472
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=$usern ame
AND password=$passw ord";
$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($_P OST['un'], $_POST['pw']);
if (!$logged_in_us er)
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**********@t obyinkster.co.u kschreef in bericht
news:jd******** ****@ophelia.g5 n.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=$usern ame
AND password=$passw ord";
$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($_P OST['un'], $_POST['pw']);
if (!$logged_in_us er)
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($_P OST['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**********@t obyinkster.co.u kschreef in bericht
news:rr******** ****@ophelia.g5 n.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::fieldSpec s[ $f ] ) )
{
return self::fieldSpec s[ $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->getFieldSpec s( 'id' ) );

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

parent::$fieldS pecs = 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::fieldSpec s[ $f ] ) )
{
return self::fieldSpec s[ $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**********@t obyinkster.co.u kschreef in bericht
news:rr******** ****@ophelia.g5 n.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::fieldSpec s[ $f ] ) )
{
return self::fieldSpec s[ $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->getFieldSpec s( 'id' ) );

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

parent::$fieldS pecs = 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*******@attgl obal.net
=============== ===
Apr 13 '07 #7
amygdala wrote:
"Toby A Inkster" <us**********@t obyinkster.co.u kschreef in bericht
news:rr******** ****@ophelia.g5 n.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::fieldSpec s[ $f ] ) )
{
return self::fieldSpec s[ $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->getFieldSpec s( 'id' ) );

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

parent::$fieldS pecs = 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*******@attgl obal.net
=============== ===
Apr 13 '07 #8

"Jerry Stuckle" <js*******@attg lobal.netschree f 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::$fieldSpe cs 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*******@attg lobal.netschree f 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

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
3031
by: lkrubner | last post by:
I have a webserver through Rackspace. I create a domain. I create an FTP user. I upload some files. I create a database called testOfSetupScript and then I create a database user named setup. I write some PHP code which should, I think, be able to to auto create the tables. The SQL looks like this:
5
674
by: Don Vaillancourt | last post by:
Hello all, Over the years as I design more database schemas the more I come up with patterns in database design. The more patterns I recognize the more I want to try to design some kind of generic design patterns that can be used and shared amongst many sub-schemas. For example, the grouping of entities. I may have the following tables:...
0
2233
by: gasturbtec | last post by:
please help im new at access programming and i just got this project dropped in my lap because the old programmer quit. i've been doing ok so far but now i need to add code to an existing database that is used to connect to other databases and generate reports. below is sample code of how the database does the linking i hope i give you enough...
7
2412
by: PC Datasheet | last post by:
Looking for suggestions ---- A database was designed for a national automobile inspection program. In it's simplest form, the database has two tables: TblOwner OwnerID <Year/Make/Model owned by owner, Owner name/address, etc) TblInspection InspectionID
35
4822
by: Terry Jolly | last post by:
Web Solution Goal: Have a global database connection Why: (There will be 30+ tables, represented by 30+ classes) I only want to reference the database connection once. I put the connection string in the web.config. I created a class with a static database connection and the class opens and closes the database.
76
271540
MMcCarthy
by: MMcCarthy | last post by:
Normalisation is the term used to describe how you break a file down into tables to create a database. There are 3 or 4 major steps involved known as 1NF (First Normal Form), 2NF (Second Normal Form), 3NF (Third Normal Form) and BCNF (Boyce-Codd Normal Form). There are others but they are rarely if ever used. A database is said to be Normalised if...
0
4986
bartonc
by: bartonc | last post by:
With one small change to the view/control: self.staticText3 = wx.StaticText(id=wxID_DBCONNECTDIALOGSTATICTEXT3, label='ODBC Data Source Name', name='staticText3', parent=self, pos=wx.Point(240, 40), size=wx.Size(143, 16), style=0) and some rework of the model:##from MySQLdb import * from mx.ODBC.Windows...
8
2742
by: situ | last post by:
Hello all, i have Database1 and database2, is it possible to make database connection to database2 by running stored procedure on database1. Thanks and Regards Situ
12
3922
by: grace | last post by:
i am wondering why my database retrieval becomes too slow...we set up a new server (ubuntu, breezy badger) machine where we transferred all our files from the old server.. Our new server uses Asus p5pe-vm motherboard and an Intel Pentium D 3.0Ghz processor, compared to the old one where we uses asrock motherboard and AMD Duron. Both has the...
9
2330
by: Peter Duniho | last post by:
Is there a straightfoward API in .NET that allows for inspection of a database? That is, to look at the structure of the database, without knowing anything in advance about it? For example, retrieving a list of tables in the database. Doing a little browsing in MSDN, I see that the abstract representation of a database appears to be the...
0
7784
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7705
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8032
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8205
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
8074
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5601
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5294
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3734
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
1044
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.