Is this a good way to structure an object oriented php site (with mysql, users, forum etc)

I am creating a new version of our website which is almost entirely object-orinted. I have a static html file acting as the template, but all content is drawn from an object. I have an object directory, where each file contains a class with the same name.

The class that is called from the static html file is called "start", and extends the class "mysql". The start constructor includes other class files, calls the mysql constuctor (parent::mysql()) so as to connect to the db, initiates a user object based on a session, calls a "post"-script if the method is POST, and finally contains some methods that return parts of what will be the content of the page (logo, link bar, "you are here", main content). The methods that use user variables (from the user object) are given the whole user object by reference as an argument. For example:

      function bar() {
      
            $b = new bar(&$this->user);
            return $b->show();
      
      }

All other classes that access mysql inherit the mysql class, but since the constructor is not called automatically, it only connects once.

Basically, what I want with all this, is some feedback from people experienced with structuring object-oriented php sites. So far, the only thing that appears somewhat ineffective to me is that I have to add the user object every time a sub-class is initiated which uses user variables. Could I make this more effective somehow?

And, generally speaking, does this seem like a good way of structuring a site?
olbionAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

snoyes_jwCommented:
When a class extends another class, it should be because it is a more specific object of the same type.  A web page is not a more specific version of a mysql connection, so I would contend that this approach is not good OOD.

Instead, you might be happier writing your database connection class with a singleton pattern, which means that the constructor returns a pointer to a single instance of the class.
http://www.php.net/manual/en/language.oop5.patterns.php

If every subclass requires a user object, then the user object should go in the parent class.  The subclasses will inherit it, provided they call the parent constructor.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
joshlrogersCommented:
snoyes_jw is right on the ball on this one.  

I can tell you from a project that I am working on now.  I am developing an intranet for our company and automating a lot of the spreadsheets and access databases we have been working off of for years into one tool.  I have a filesystem such as you, all of my classes have their own filename, they are

db.class: This is a class that automates all MySQL database queries/functions.  I.E. a select method

            public function select($qsrch, $qtable, $qrule = 1) {
                  $this->qresult = mysql_query("SELECT {$qsrch} FROM `{$qtable}` WHERE {$qrule};", $this->dblink)
                        or die("Could not issue MySQL command SELECT: " . mysql_error());
                        
                  return("SELECT {$qsrch} FROM {$qtable} WHERE {$qrule};");
            }

masdb.class: This is a class to connect to an ODBC database that our accounting package runs off of
processblocks.class:  This is the ad hoc templating system that I have developed
request.class:  This is the class I use for "transportation" purposes, it gets a person from a click on a button to the page they intended

All of these classes are independent, if I have something for a MySQL query, but I won't use it enough to warrant a method, I'll include that db.class file and extend the class within the script that I am working on.  Anyways, to sum it up Snoyes is right on.

Good Luck,

Josh Rogers
zariokCommented:
Utilize the singleton pattern for the database connections.

Build the user object ONCE and slap that into $_SESSION[] where you will possibly be also adding something to check for a "valid user" anyway for each page hit.  

This will keep you from consistantly hitting the database for each page hit for user information/authentication.  From within your other 'classes' you use the super-global $_SESSION (Exampe: $_SESSION['user']->fname ) to locate information.

For further, please comment with questions.
Expert Spotlight: Joe Anderson (DatabaseMX)

We’ve posted a new Expert Spotlight!  Joe Anderson (DatabaseMX) has been on Experts Exchange since 2006. Learn more about this database architect, guitar aficionado, and Microsoft MVP.

olbionAuthor Commented:
Thank you all for your comments. I saw later that I may not have provided enough information in my question, but I got very good response anyhow. It seems to me though that I've been suggested two different methods for accessing user information.

1. Instantiate the user class in a parent class, and let all other classes that make use of user variables inherit this class.

2. Instantiate the user class only when the user logs in and save the entire object in a session, which I can then access from any class since sessions are global.

Which of these methods would you recommend? It seems to me that the second one would be better since it requires less communication with the database (actually, this way, most pages would load without any database communication).

--------------

Another question. I read about the singleton pattern, and it seems fine by me. I suppose that using that way, I would in all sub-classes that use db queries, call something like this in the constructor:

$this->db = db::singleton();

So that I then could call $this->db->query() from any method in the class.

However, an alternative to this would be to instantiate a mysql class in every class that makes use of mysql. Like this in the constructor:

$this->db = new mysql;

The constructor would be called every time, and this calls the mysql_pconnect function, but (because the way mysql_pconnect works) if there already is a connection, it will only return the id of the current connection. So the constructor would not make a new connection every time.

Here is my question: Is the suggested method (singleton) better in any way than creating a new db object every time?
snoyes_jwCommented:
The singleton method will require less overhead, because everything points to a single instance of the class, rather than having many instances of the class that point to a single connection.  Also, if the requirements change and you can't use pconnect anymore, it's no big deal if you're using the singleton.  It might require some rework if you aren't.
snoyes_jwCommented:
Normally I don't bother, but it seems to me that with 3 different experts providing equally valuable but different information, a points split would have been in order.  It also also usual in EE culture to accept an answer with an A, unless you have a good reason for doing otherwise.

You can post a free question in Community Support if you wish to reopen this question for re-grading.
snoyes_jwCommented:
Thanks, olbion and Lunchy.  I appreciate the extra effort on both your parts.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.