Page 1 of 1

Object Scope Question

Posted: Sun Mar 30, 2008 12:38 am
by flying_circus
Guys, I am still a bit new to PHP objects and feel like I am tripping over myself.

I think this should be simple enough.

I want to make a database class to handle all DB activity.

I want to make a user session class to handle all session activity (mysql based).
I want to make a products class to handle all product functions.

I only want to open 1 database connection at the top of the page and close 1 database connection at the bottom of the page.

Both the user session and products class need to access db functionality in the db class. Am I correct in my thinking that if the session class and products class both extend the db class, that there will be 2 seperate db connections?

I would like to reference the db class from other classes without setting my connection resource to public. Can I do this?

Here is what I have and it works only with my db connection resource set to public.

Code: Select all

<?php
  # Create a database object
    $dbServer = new Database;
 
  # Begin the User Session
    $user = new User(&$dbServer);
?>
Also, if someone could please confirm: The Ampersand before an object means to reference that object and not create a 2nd instance, is this correct?

Re: Object Scope Question

Posted: Sun Mar 30, 2008 1:44 am
by Chris Corbyn
flying_circus wrote:Guys, I am still a bit new to PHP objects and feel like I am tripping over myself.

I think this should be simple enough.

I want to make a database class to handle all DB activity.

I want to make a user session class to handle all session activity (mysql based).
I want to make a products class to handle all product functions.

I only want to open 1 database connection at the top of the page and close 1 database connection at the bottom of the page.

Both the user session and products class need to access db functionality in the db class. Am I correct in my thinking that if the session class and products class both extend the db class, that there will be 2 seperate db connections?
You've asked a bit of a tricky question in this exact scenario. In general my answer would be yes since they are two separate objects with their properties completely encapsulated. However, I may be wrong, but I think MySQL connection resources are a bit clever and calling mysql_connect() twice doesn't really open two connections. I seem to recall stumbling upon a problem with this at some point whilst writing some experimental multi DB connection classes.

You should just treat the general answer as "yes" they will be separate from each other though because that's how objects work.
I would like to reference the db class from other classes without setting my connection resource to public. Can I do this?
Sure :) Just make sure you provide public access to anything which operates on the resource (e.g. provide begin(), query(), commit() methods which are public).

Code: Select all

<?php
  # Create a database object
    $dbServer = new Database;
 
  # Begin the User Session
    $user = new User(&$dbServer);
?>
Also, if someone could please confirm: The Ampersand before an object means to reference that object and not create a 2nd instance, is this correct?
The ampersand does prevent a copy from being created yes. More specifically it returns a reference instead of a value. If you're using PHP5 you shouldn't be doing this however. The only reason it's done in PHP4 is because it provides a workaround to a fundamental OO problem in PHP4. Objects should always be passed like resources (i.e. the reference to the object gets passed by value). PHP5 does this implicitly which is the correct thing to do. There are complications with explicitly using references instead of PHP5 default object referencing.

Take this example:

Code: Select all

$a = 42;
$b =& $a; //references $a = 42
 
$b = 57;
 
echo $a; //57
Now take that scenario with an object being passed as a parameter:

Code: Select all

function foo(&$obj) {
  if (!$obj->isSuitableForWhatever()) {
    $obj =& new SomethingElse();
  }
  //rest of function
}
 
$obj =& new WantedClass();
foo($obj);
 
//Breakage... $obj is no longer WantedClass()
In PHP5 you can assing to objects happily because what happens is that you replace the value of the reference with a new value, but you don't replace the thing it references. It's hard to explain, but basically if you're using PHP5 don't pass objects by reference.

Also, just to re-jig your code a bit in the scenario that you are using PHP4:

Code: Select all

<?php
  # Create a database object
    $dbServer =& new Database;
 
  # Begin the User Session
    $user =& new User($dbServer);
 
// .. with User looking like this:
 
class User {
  function User(&$db) {
    // ...
  }
}
Placing the references at the places you make assignments is needed, but also it's better to declare a method as receiving a parameter by reference rather than passing a reference at call time. allow_call_time_pass_reference is another badly thought out PHP "feature" which can be disabled or enabled making it very difficult to support scripts which depend on it being turned on (which your code does).

Re: Object Scope Question

Posted: Tue Apr 01, 2008 4:22 pm
by flying_circus
Chris,

Thank you for taking the time to reply to me. What you said helps to clear up alot. I hade made a reference in another post about reading "Professional PHP5" by wrox (dont bother, it really is a terrible book) they use the & and failed to explain it. So, thank you, I will omit the ampersands from my code, since I am on PHP5 :D

And Doh! Yes, of course I am access my db connection through the object, using public functions.


I can't quite make our your picture avatar. Is that a computer head set or are you flying in that picture? We're building a kit plane, though I never seem to run into other pilots outside of "pilot" message forums.