I create one class per table which represents a record in the table i.e. for the person table I have a CPerson class.
I create a 2nd class per table which represents the table itself and holds 0 or more record classes i.e. CPersons contains a list of CPerson objects.
A 3rd class represents the databse and is just an easy way to hold the various table classes.
Unlike matto, I find that the 1 class per table approach makes it easier to implement complex queries. In fact, it's why I went this route in the first place.
Consider a soccer game schedule showing what teams are playing and who the officials are.
/* Start with a comma delmited distinct list of the games to be shown. */
$gamesID = "1,5,8,10';
/* Load the games */
$games->addItemsForIDs($gameIDs);
/* Get the teams */
$teamIDs = $games->getTeamIDs();
$teams->addItemsForIDs($teamIDs);
/* Get the coaches */
$coachIDs = $teams->getPersonIDs(array(HEAD_COACH,ASST_COACH));
$persons->addItemsForIDs($coachIDs);
/* Get the officials */
$refereeIDs = $games->getRefereeIDs();
$persons->addItemsForIDs($refereeIDs);
Now I have one copy of every object and I can generate the report.